ghidhfh 2023-08-17 16:10 采纳率: 0%
浏览 11

Python自动贪吃蛇遇到自我锁死的算法问题

我在制作一个Python自动的贪吃蛇程序,由于我不会BFS或者DFS,所以就基于曼哈顿距离制作了一个,但是我发现我的蛇有时候会绕成一个圈把自己锁在里面,请问有什么思路可以解决这个问题的

from random import randrange
from turtle import *

from freegames import square, vector

food = vector(0, 0)
snake = [vector(10, 0)]
aim = vector(0, -10)
aim_list = []


def change():
    global aim
    global head
    head = snake[-1].copy()
    food_x = food.x
    food_y = food.y
    head_x = head.x
    head_y = head.y

    directions = [vector(0, 10), vector(0, -10), vector(10, 0), vector(-10, 0)]  # 上,下,右,左
    valid_directions = []

    for bodys in snake:
        if bodys == head:
            if len(snake) > 4 and head in snake[:-1]:
                # 蛇围成一个圈
                # 让蛇沿着自身的身体移动一段距离
                for i in range(1, 5):
                    next_head = head.copy()
                    next_head.move(aim)
                    if next_head not in snake:
                        head = next_head
                        break
                    aim.rotate(90)
        else:
            pass

    for direction in directions:
        next_head = head.copy()
        next_head.move(direction)
        if inside(next_head) and next_head not in snake:
            valid_directions.append(direction)
    if valid_directions:
        aim = min(valid_directions, key=lambda direction: abs(food_x - (head_x + direction.x)) + abs(food_y - (head_y + direction.y)))
   
        
def inside(head):
    return -200 < head.x < 190 and -200 < head.y < 190


def move():
    global head
    global aim
    change()
    head = snake[-1].copy()
    head.move(aim)
    food_x = food.x
    food_y = food.y
    head_x = head.x
    head_y = head.y


    if not inside(head) or head in snake:
        square(head.x, head.y, 9, 'red')
        update()
        return

    
    snake.append(head)

    if head == food:
        print('Snake:', len(snake))
        food.x = randrange(-15, 15) * 10
        food.y = randrange(-15, 15) * 10
    else:
        snake.pop(0)

    clear()

    for body in snake:
        square(body.x, body.y, 9, 'black')

    square(food.x, food.y, 9, 'green')
    update()
    ontimer(move, 5)

setup(420, 420, 370, 0)
hideturtle()
tracer(False)
move()

done()

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-08-17 19:08
    关注

    【以下回答由 GPT 生成】

    问题标题: Python自动贪吃蛇遇到自我锁死的算法问题

    问题内容: 我正在用Python制作一个自动贪吃蛇程序。由于我不了解BFS或DFS算法,所以采用了基于曼哈顿距离的方法。但是我发现我的蛇有时候会绕成一个圈把自己锁在里面。请问有什么方法可以解决这个问题吗?

    from random import randrange
    from turtle import *
    from freegames import square, vector
    
    food = vector(0, 0)
    snake = [vector(10, 0)]
    aim = vector(0, -10)
    aim_list = []
    
    def change():
        """
        在每次移动之前检查蛇头和食物的位置,然后更新移动方向。
        """
        global aim
        global head
        head = snake[-1].copy()
        food_x = food.x
        food_y = food.y
        head_x = head.x
        head_y = head.y
    
        directions = [vector(0, 10), vector(0, -10), vector(10, 0), vector(-10, 0)]  # 上、下、右、左
        valid_directions = []
    
        for bodys in snake:
            if bodys == head:
                if len(snake) > 4 and head in snake[:-1]:
                    # 蛇围成一个圈
                    # 让蛇沿着自身的身体移动一段距离
                    for i in range(1, 5):
                        next_head = head.copy()
                        next_head.move(aim)
                        if next_head not in snake:
                            head = next_head
                            break
                        aim.rotate(90)
            else:
                pass
    
        for direction in directions:
            next_head = head.copy()
            next_head.move(direction)
            if inside(next_head) and next_head not in snake:
                valid_directions.append(direction)
    
        if valid_directions:
            aim = min(valid_directions, key=lambda direction: abs(food_x - (head_x + direction.x)) + abs(food_y - (head_y + direction.y)))
    
    def inside(head):
        """
        判断蛇头是否在游戏边界内。
        """
        return -200 < head.x < 190 and -200 < head.y < 190
    
    def move():
        """
        移动蛇的位置并更新蛇的身体。
        """
        global head
        # 实现移动的过程
    

    请问有什么方法可以解决这个问题吗?

    回答: 目前的实现方式中没有对蛇头和蛇身体接触时的等待时间进行限制,因此导致蛇会在蛇身体内部转圈子。为了解决这个问题,可以在蛇头碰到蛇身体时,增加一个等待时间,让蛇能继续朝其他方向前进。

    以下是解决方案的修改部分代码:

    from random import randrange
    from turtle import *
    from freegames import square, vector
    import time
    
    ...
    
    def change():
        """
        在每次移动之前检查蛇头和食物的位置,然后更新移动方向。
        """
        global aim
        global head
        head = snake[-1].copy()
        food_x = food.x
        food_y = food.y
        head_x = head.x
        head_y = head.y
    
        directions = [vector(0, 10), vector(0, -10), vector(10, 0), vector(-10, 0)]  # 上、下、右、左
        valid_directions = []
    
        for bodys in snake:
            if bodys == head:
                if len(snake) > 4 and head in snake[:-1]:
                    # 蛇围成一个圈
                    # 让蛇沿着自身的身体移动一段距离
                    for i in range(1, 5):
                        next_head = head.copy()
                        next_head.move(aim)
                        if next_head not in snake:
                            head = next_head
                            break
                        aim.rotate(90)
                        time.sleep(0.2)  # 增加等待时间
            else:
                pass
    
        ...
    
    def move():
        """
        移动蛇的位置并更新蛇的身体。
        """
        global head
        # 实现移动的过程
    
        time.sleep(0.1)  # 增加等待时间
    
        ...
    
    ...
    

    这样,当蛇头碰到蛇身体时,会有一个等待时间,让蛇头有足够的时间继续朝其他方向前进,从而避免了蛇在蛇身体内部转圈子的问题。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 8月17日

悬赏问题

  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振