我正在尝试训练一个 NEAT 算法来玩一个名为“curvefever”的简单游戏。我能够创建 pygame 版本的 curvefever,现在我想训练 AI 来玩它。因此,AI 必须学会避开障碍物:围绕游戏的边界并跟踪每个玩家留下的痕迹,就像在 Snake 中一样。
目前我正在通过以下方式执行此操作:
问题是这很慢!运行 'python -m cProfile -s cumtime ai.py' 我认为是检测障碍物导致脚本变慢,占总运行时间的 50% 左右。
请参阅下面我如何创建视线的一些代码:
posx = 玩家的 x 位置
posy = 玩家的 y 位置
dir = 玩家前进的方向
dangle = 是视线之间的度数间距
角度 = 视线的总范围(以度为单位)
def create_lines_of_sight(posx, posy, dir, dangle, angle, length):
dirs = [xdir for xdir in np.ceil(np.arange(dir-angle,dir+angle,dangle))]
d_posx = np.cos(np.deg2rad(dir))
d_posy = np.sin(np.deg2rad(dir))
return list(map(functools.partial(f_lrects,posx,posy,length), dirs))
def create_rects(posx, posy, d_posx, d_posy, i):
return f_rect(posx+i*d_posx,posy+i*d_posy,1,1,0,curvefever.WHITE)
f_create_rect = create_rects
def create_line_of_rects(posx, posy, length,dir):
l = pygame.sprite.Group()
ladd = l.add
d_posx = np.cos(np.deg2rad(dir))
d_posy = np.sin(np.deg2rad(dir))
i = [i for i in range(2,length,8)]
ladd(map(functools.partial(f_create_rect,posx,posy,d_posx,d_posy),i))
return l
f_lrects = create_line_of_rects
Run Code Online (Sandbox Code Playgroud)
所有障碍物都是矩形,定义为:
class Rect(pygame.sprite.Sprite):
def __init__(self,x,y,width,height,dir,color):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.centery = y
Run Code Online (Sandbox Code Playgroud)
并保存在一个精灵组中。
我试过的
我尝试添加一个 map 命令来摆脱 for 循环,但这并没有加快速度。
我尝试添加函数名称以删除函数查找,我读到这使它更快,但事实并非如此。
我尝试使用“Bresenham's Line Algorithm”检测障碍物并检查障碍物 (x,y) 位置是否与视线重叠。虽然这是一个更快的它没有工作,因为它经常错过障碍。发生这种情况是因为视线与障碍物中心 (rectx,recty) 不完全匹配,尽管它确实与矩形本身重叠。
其他人用什么来检测障碍物(可能在 pygame 中)?非常欢迎任何有关如何使其更快或更有效的提示。
非常感谢您的帮助!
小智 0
我一直在从事类似的项目。最后我使用了pygame 的pygame.Rect.clipline()和pygame.Vector2.distance_to()方法:
def intersect_rect(self,other) -> tuple[float,float]:
cl=other.clipline(self.a.x,self.a.y,self.b.x,self.b.y)
if cl:
return cl[0] if self.a.distance_to(cl[0]) <self.a.distance_to(cl[1]) else cl[1]
else:
return
Run Code Online (Sandbox Code Playgroud)
self和other都是一个类,继承自该类pygame.Rect。self.a和self.b是两个pygame.Vector2对象。玩家和视距self.a的原点在哪里。self.b与纯 python 函数相比,这导致速度提高了 100 倍。