我在制作一个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()
【以下回答由 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) # 增加等待时间
...
...
这样,当蛇头碰到蛇身体时,会有一个等待时间,让蛇头有足够的时间继续朝其他方向前进,从而避免了蛇在蛇身体内部转圈子的问题。
【相关推荐】