(Pygame) What is wrong with this function?

Viewed 48

So, i have been working on a snake game made in Pygame. So far, everything is fine, except for one problem: When the snake eats the fruit, the fruit (that randomly spawns) sometimes appears inside the snake's body. So, to avoid this, i made this function:

def random_fruit(body_pos):
    global general_fruit_x, general_fruit_y  # Fruit rectangle coordinates
    while True:
        general_fruit_x = randrange(window[0] // snake.w) * snake.w  # (Snake is a pygame.Rect)
        general_fruit_y = randrange(window[1] // snake.h) * snake.h
        if len(list(filter(lambda z: body_pos == (general_fruit_x, general_fruit_y), body_pos))) > 0:
            continue  # If the spawning position of the fruit is the same as the snake's body, we continue the loop
        else:
            break  # If not, we are done
    set_obj_coordinates(general_fruit, general_fruit_x, general_fruit_y)  # set fruit random position

And implemented it in the main game loop:

if fruit_eated:
    random_ind1 = random_ind2
    snake_len += 1
    apple_sound.play()
    random_fruit(snake_pos)  # snake_pos is a list of tuples with all snake's body coordinates
    for m in range(3):
        snake_imgs[random_ind1][m] = img("snake_" + snake_colors[random_ind1] + str(m + 1))  # Reset snake image
    random_ind2 = randint(0, 3)
    if x_move < 0:
        rotate_imgs(90, random_ind1)
    if x_move > 0:
        rotate_imgs(-90, random_ind1)
    if y_move > 0:
        rotate_imgs(180, random_ind1)
    if y_move < 0:
        pass

But it seems that the random_fruit function ignores the condition of the snake's body.

Here is the complete code: https://github.com/n4tm/PySnake/tree/main/snake

1 Answers

You have to check if any position of the body is equal to the new random position of the fruit:

if len(list(filter(lambda z: body_pos == (general_fruit_x, general_fruit_y), body_pos))) > 0:`

if any(pos == (general_fruit_x, general_fruit_y) for pos in body_pos):

random_fruit function:

def random_fruit(body_pos):
    global general_fruit_x, general_fruit_y
    while True:
        general_fruit_x = randrange(window[0] // snake.w) * snake.w 
        general_fruit_y = randrange(window[1] // snake.h) * snake.h
        if not any(pos == (general_fruit_x, general_fruit_y) for pos in body_pos):
            break
    set_obj_coordinates(general_fruit, general_fruit_x, general_fruit_y)
Related