使用 Pygame 构建了一个游戏,使用 NEAT 教 AI,但是 pygame 突然不画任何东西
Built a game using Pygame, using NEAT to teach an AI, but pygame all the sudden does not draw anything
我正在构建一个 AI 来玩我使用 pygame 创建的游戏,我构建了这个简单的游戏并且它按预期运行。我开始实施 NEAT 并最终让我的代码不出现任何错误,但是当我 运行 它时 pygame window 只充满黑色,我不确定为什么。我是 NEAT 的新手,pygame 因此代码对于大多数标准来说可能很难看,但感谢您的帮助。
import pygame
import neat
import math
import os
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
YELLOW = (255, 255, 0)
screen = pygame.display.set_mode([1500, 1000])
pygame.display.set_caption('Maze Runner')
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def get_x(self):
return self.rect.x
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color, speed_x, speed_y):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.speed_x = speed_x
self.speed_y = speed_y
def get_x(self):
return self.rect.x
def get_y(self):
return self.rect.y
def enemymove(self, walls, dt):
self.rect.x += self.speed_x * dt
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.speed_x > 0:
self.rect.right = block.rect.left
self.speed_x = -self.speed_x
else:
self.rect.left = block.rect.right
self.speed_x = -self.speed_x
self.rect.y += self.speed_y * dt
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.speed_y > 0:
self.rect.bottom = block.rect.top
self.speed_y = -self.speed_y
else:
self.rect.top = block.rect.bottom
self.speed_y = -self.speed_y
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface([15, 15])
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.deaths = 0
self.change_x = 10
self.change_y = 10
def num_deaths(self):
return self.deaths
def get_x(self):
return self.rect.x
def get_y(self):
return self.rect.y
def get_closest_wall(self, walls):
wall_list = walls
min = -1000
distance = 0
for wall in wall_list:
distace = self.rect.x - wall.get_x()
if distance < min:
min = distance
return abs(distance)
def get_closest_enemy(self, enemies):
enemy_list = enemies
min = -1000
distance = 0
for enemy in enemy_list:
distace = self.rect.x - enemy.get_x()
if distance < min:
min = distance
return abs(distance)
def collide_with_enemy(self, enemies):
return pygame.sprite.spritecollide(self, enemies, False)
def move_right(self, walls, enemies, starting_x, starting_y):
self.rect.x += self.change_x
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_left(self, walls, enemies, starting_x, starting_y):
self.rect.x -= self.change_x
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_x < 0:
self.rect.left = block.rect.right
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_up(self, walls, enemies, starting_x, starting_y):
self.rect.y -= self.change_y
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.top = block.rect.bottom
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_down(self, walls, enemies, starting_x, starting_y):
self.rect.y += self.change_y
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_y < 0:
self.rect.bottom = block.rect.top
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
class Level(object):
wall_list = None
enemy_list = None
starting_x = 0
starting_y = 0
def __init__(self):
self.wall_list = pygame.sprite.Group()
self.enemy_list = pygame.sprite.Group()
class Level1(Level):
def __init__(self):
super().__init__()
starting_x = 210
starting_y = 775
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[100, 100, 3, 700, WHITE],
[100, 800, 1200, 3, YELLOW],
[1300, 100, 3, 700, YELLOW],
[100, 100, 250, 3, YELLOW],
[350, 100, 3, 550, YELLOW],
[350, 650, 90, 3, YELLOW],
[450, 100, 3, 550, YELLOW],
[450, 100, 850, 3, YELLOW]
]
enemies = [[500, 410, 20, 375, BLUE, 300, 0],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
class Level2(Level):
def __init__(self):
super().__init__()
starting_x = 225
starting_y = 775
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[150, 150, 3, 250, YELLOW],
[150, 150, 1150, 3, YELLOW],
[1300, 150, 3, 750, YELLOW],
[150, 900, 1150, 3, YELLOW],
[150, 650, 3, 250, YELLOW],
[150, 650, 900, 3, YELLOW],
[1050, 400, 3, 250, YELLOW],
[150, 400, 900, 3, YELLOW]
]
enemies = [[350, 770, 20, 20, BLUE, 0, -400],
[500, 770, 20, 20, BLUE, 0, 400],
[650, 770, 20, 20, BLUE, 0, -400],
[800, 770, 20, 20, BLUE, 0, 400],
[950, 770, 20, 20, BLUE, 0, -400],
[350, 250, 20, 20, BLUE, 0, 400],
[500, 250, 20, 20, BLUE, 0, -400],
[650, 250, 20, 20, BLUE, 0, 400],
[800, 250, 20, 20, BLUE, 0, -400],
[950, 250, 20, 20, BLUE, 0, 400],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
class Level3(Level):
def __init__(self):
super().__init__()
starting_x = 200
starting_y = 895
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[150, 950, 1200, 6, YELLOW],
[1350, 200, 6, 750, YELLOW],
[1350, 200, 100, 6, YELLOW],
[1450, 100, 6, 100, YELLOW],
[250, 100, 1200, 6, YELLOW],
[250, 100, 6, 750, YELLOW],
[150, 850, 100, 6, YELLOW],
[150, 850, 6, 100, YELLOW]
]
enemies = [[780, 220, 40, 118, BLUE, -1000, 0],
[780, 340, 40, 118, BLUE, 1000, 0],
[780, 460, 40, 118, BLUE, -1000, 0],
[780, 580, 40, 118, BLUE, 1000, 0],
[780, 700, 40, 118, BLUE, -1000, 0],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
def main(genomes, config):
pygame.init()
levels = []
level = Level1()
levels.append(level)
level = Level2()
levels.append(level)
level = Level3()
levels.append(level)
current_level_num = 0
current_level = levels[current_level_num]
movingsprites = pygame.sprite.Group()
clock = pygame.time.Clock()
done = False
players = []
ge = []
nets = []
for genome_id, g in genomes:
g.fitness = 0
net = neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
players.append(Player(15,15))
ge.append(g)
for player in players:
movingsprites.add(player)
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.QUIT()
quit()
break
for x, player in enumerate(players):
ge[x].fitness += .01
output = nets[players.index(player)].activate((player.rect.x, player.rect.y, player.get_closest_enemy(current_level.enemy_list), player.get_closest_wall(current_level.wall_list)))
if output[0] > .5:
player.move_right(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[1] > .5:
player.move_left(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[2] > .5:
player.move_down(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[3] > .5:
player.move_up(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
for player in players:
movingsprites.add(player)
if player.collide_with_enemy(current_level.enemy_list):
ge[players.index(player)].fitness -= 1
player.num_deaths += 1
if player.num_deaths() > 5:
ge[players.index(player)].fitness -= 5
nets.pop(players.index(player))
ge.pop(players.index(player))
players.pop(players.index(player))
screen.fill(BLACK)
player_sprites.draw(screen)
current_level.wall_list.draw(screen)
current_level.enemy_list.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
def run(config_file):
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
neat.DefaultSpeciesSet, neat.DefaultStagnation,
config_file)
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main, 50)
print('\nBest genome:\n{!s}'.format(winner))
if __name__ == '__main__':
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
run(config_path)
我根本无法让您的代码正常工作,我不熟悉 neat
模块,因此无法随意调试它。但是,根据问题描述,在我看来它像是 main()
函数中的缩进错误。我希望 while not done:
循环需要包括屏幕上的绘图和事件处理,而目前它还没有。
您应该通过 reindent
或 autopep8 之类的方式 运行 您的代码,这样可以使您的代码更易于阅读,从而更易于调试。
无论如何,您当前的主循环是:
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
而它的本意可能类似于以下内容。如果缩进更标准,这将是相当明显的。绝大多数专业软件工程师严格使用 4 个空格的缩进是有充分理由的。不是代码“丑”或“漂亮”,而是保持效率和正确性。
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.QUIT()
quit()
break
for x, player in enumerate(players):
ge[x].fitness += .01
output = nets[players.index(player)].activate((player.rect.x, player.rect.y, player.get_closest_enemy(current_level.enemy_list), player.get_closest_wall(current_level.wall_list)))
if output[0] > .5:
player.move_right(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[1] > .5:
player.move_left(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[2] > .5:
player.move_down(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[3] > .5:
player.move_up(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
for player in players:
movingsprites.add(player)
if player.collide_with_enemy(current_level.enemy_list):
ge[players.index(player)].fitness -= 1
player.num_deaths += 1
if player.num_deaths() > 5:
ge[players.index(player)].fitness -= 5
nets.pop(players.index(player))
ge.pop(players.index(player))
players.pop(players.index(player))
screen.fill(BLACK)
player_sprites.draw(screen)
current_level.wall_list.draw(screen)
current_level.enemy_list.draw(screen)
pygame.display.flip()
clock.tick(60)
我正在构建一个 AI 来玩我使用 pygame 创建的游戏,我构建了这个简单的游戏并且它按预期运行。我开始实施 NEAT 并最终让我的代码不出现任何错误,但是当我 运行 它时 pygame window 只充满黑色,我不确定为什么。我是 NEAT 的新手,pygame 因此代码对于大多数标准来说可能很难看,但感谢您的帮助。
import pygame
import neat
import math
import os
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
YELLOW = (255, 255, 0)
screen = pygame.display.set_mode([1500, 1000])
pygame.display.set_caption('Maze Runner')
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def get_x(self):
return self.rect.x
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color, speed_x, speed_y):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.speed_x = speed_x
self.speed_y = speed_y
def get_x(self):
return self.rect.x
def get_y(self):
return self.rect.y
def enemymove(self, walls, dt):
self.rect.x += self.speed_x * dt
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.speed_x > 0:
self.rect.right = block.rect.left
self.speed_x = -self.speed_x
else:
self.rect.left = block.rect.right
self.speed_x = -self.speed_x
self.rect.y += self.speed_y * dt
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.speed_y > 0:
self.rect.bottom = block.rect.top
self.speed_y = -self.speed_y
else:
self.rect.top = block.rect.bottom
self.speed_y = -self.speed_y
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface([15, 15])
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.deaths = 0
self.change_x = 10
self.change_y = 10
def num_deaths(self):
return self.deaths
def get_x(self):
return self.rect.x
def get_y(self):
return self.rect.y
def get_closest_wall(self, walls):
wall_list = walls
min = -1000
distance = 0
for wall in wall_list:
distace = self.rect.x - wall.get_x()
if distance < min:
min = distance
return abs(distance)
def get_closest_enemy(self, enemies):
enemy_list = enemies
min = -1000
distance = 0
for enemy in enemy_list:
distace = self.rect.x - enemy.get_x()
if distance < min:
min = distance
return abs(distance)
def collide_with_enemy(self, enemies):
return pygame.sprite.spritecollide(self, enemies, False)
def move_right(self, walls, enemies, starting_x, starting_y):
self.rect.x += self.change_x
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_left(self, walls, enemies, starting_x, starting_y):
self.rect.x -= self.change_x
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_x < 0:
self.rect.left = block.rect.right
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_up(self, walls, enemies, starting_x, starting_y):
self.rect.y -= self.change_y
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.top = block.rect.bottom
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
def move_down(self, walls, enemies, starting_x, starting_y):
self.rect.y += self.change_y
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
if self.change_y < 0:
self.rect.bottom = block.rect.top
if self.collide_with_enemy(enemies):
self.rect.x = starting_x
self.rect.y = starting_y
class Level(object):
wall_list = None
enemy_list = None
starting_x = 0
starting_y = 0
def __init__(self):
self.wall_list = pygame.sprite.Group()
self.enemy_list = pygame.sprite.Group()
class Level1(Level):
def __init__(self):
super().__init__()
starting_x = 210
starting_y = 775
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[100, 100, 3, 700, WHITE],
[100, 800, 1200, 3, YELLOW],
[1300, 100, 3, 700, YELLOW],
[100, 100, 250, 3, YELLOW],
[350, 100, 3, 550, YELLOW],
[350, 650, 90, 3, YELLOW],
[450, 100, 3, 550, YELLOW],
[450, 100, 850, 3, YELLOW]
]
enemies = [[500, 410, 20, 375, BLUE, 300, 0],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
class Level2(Level):
def __init__(self):
super().__init__()
starting_x = 225
starting_y = 775
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[150, 150, 3, 250, YELLOW],
[150, 150, 1150, 3, YELLOW],
[1300, 150, 3, 750, YELLOW],
[150, 900, 1150, 3, YELLOW],
[150, 650, 3, 250, YELLOW],
[150, 650, 900, 3, YELLOW],
[1050, 400, 3, 250, YELLOW],
[150, 400, 900, 3, YELLOW]
]
enemies = [[350, 770, 20, 20, BLUE, 0, -400],
[500, 770, 20, 20, BLUE, 0, 400],
[650, 770, 20, 20, BLUE, 0, -400],
[800, 770, 20, 20, BLUE, 0, 400],
[950, 770, 20, 20, BLUE, 0, -400],
[350, 250, 20, 20, BLUE, 0, 400],
[500, 250, 20, 20, BLUE, 0, -400],
[650, 250, 20, 20, BLUE, 0, 400],
[800, 250, 20, 20, BLUE, 0, -400],
[950, 250, 20, 20, BLUE, 0, 400],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
class Level3(Level):
def __init__(self):
super().__init__()
starting_x = 200
starting_y = 895
walls = [[0, 0, 20, 1000, WHITE],
[1480, 0, 20, 1000, WHITE],
[20, 0, 1500, 20, WHITE],
[0, 980, 1500, 20, WHITE],
[150, 950, 1200, 6, YELLOW],
[1350, 200, 6, 750, YELLOW],
[1350, 200, 100, 6, YELLOW],
[1450, 100, 6, 100, YELLOW],
[250, 100, 1200, 6, YELLOW],
[250, 100, 6, 750, YELLOW],
[150, 850, 100, 6, YELLOW],
[150, 850, 6, 100, YELLOW]
]
enemies = [[780, 220, 40, 118, BLUE, -1000, 0],
[780, 340, 40, 118, BLUE, 1000, 0],
[780, 460, 40, 118, BLUE, -1000, 0],
[780, 580, 40, 118, BLUE, 1000, 0],
[780, 700, 40, 118, BLUE, -1000, 0],
]
for item in walls:
wall = Wall(item[0], item[1], item[2], item[3], item[4])
self.wall_list.add(wall)
for item in enemies:
enemy = Enemy(item[0], item[1], item[2], item[3], item[4], item[5],
item[6])
self.enemy_list.add(enemy)
def main(genomes, config):
pygame.init()
levels = []
level = Level1()
levels.append(level)
level = Level2()
levels.append(level)
level = Level3()
levels.append(level)
current_level_num = 0
current_level = levels[current_level_num]
movingsprites = pygame.sprite.Group()
clock = pygame.time.Clock()
done = False
players = []
ge = []
nets = []
for genome_id, g in genomes:
g.fitness = 0
net = neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
players.append(Player(15,15))
ge.append(g)
for player in players:
movingsprites.add(player)
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.QUIT()
quit()
break
for x, player in enumerate(players):
ge[x].fitness += .01
output = nets[players.index(player)].activate((player.rect.x, player.rect.y, player.get_closest_enemy(current_level.enemy_list), player.get_closest_wall(current_level.wall_list)))
if output[0] > .5:
player.move_right(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[1] > .5:
player.move_left(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[2] > .5:
player.move_down(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[3] > .5:
player.move_up(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
for player in players:
movingsprites.add(player)
if player.collide_with_enemy(current_level.enemy_list):
ge[players.index(player)].fitness -= 1
player.num_deaths += 1
if player.num_deaths() > 5:
ge[players.index(player)].fitness -= 5
nets.pop(players.index(player))
ge.pop(players.index(player))
players.pop(players.index(player))
screen.fill(BLACK)
player_sprites.draw(screen)
current_level.wall_list.draw(screen)
current_level.enemy_list.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
def run(config_file):
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
neat.DefaultSpeciesSet, neat.DefaultStagnation,
config_file)
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main, 50)
print('\nBest genome:\n{!s}'.format(winner))
if __name__ == '__main__':
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
run(config_path)
我根本无法让您的代码正常工作,我不熟悉 neat
模块,因此无法随意调试它。但是,根据问题描述,在我看来它像是 main()
函数中的缩进错误。我希望 while not done:
循环需要包括屏幕上的绘图和事件处理,而目前它还没有。
您应该通过 reindent
或 autopep8 之类的方式 运行 您的代码,这样可以使您的代码更易于阅读,从而更易于调试。
无论如何,您当前的主循环是:
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
而它的本意可能类似于以下内容。如果缩进更标准,这将是相当明显的。绝大多数专业软件工程师严格使用 4 个空格的缩进是有充分理由的。不是代码“丑”或“漂亮”,而是保持效率和正确性。
while not done:
dt = clock.tick(60) / 1000
for enemy in current_level.enemy_list:
enemy.enemymove(current_level.wall_list, dt)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.QUIT()
quit()
break
for x, player in enumerate(players):
ge[x].fitness += .01
output = nets[players.index(player)].activate((player.rect.x, player.rect.y, player.get_closest_enemy(current_level.enemy_list), player.get_closest_wall(current_level.wall_list)))
if output[0] > .5:
player.move_right(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[1] > .5:
player.move_left(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[2] > .5:
player.move_down(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
elif output[3] > .5:
player.move_up(current_level.wall_list, current_level.enemy_list, current_level.starting_x, current_level.starting_y)
for player in players:
movingsprites.add(player)
if player.collide_with_enemy(current_level.enemy_list):
ge[players.index(player)].fitness -= 1
player.num_deaths += 1
if player.num_deaths() > 5:
ge[players.index(player)].fitness -= 5
nets.pop(players.index(player))
ge.pop(players.index(player))
players.pop(players.index(player))
screen.fill(BLACK)
player_sprites.draw(screen)
current_level.wall_list.draw(screen)
current_level.enemy_list.draw(screen)
pygame.display.flip()
clock.tick(60)