Я недавно закончил кодировать свою собственную игру PACMAN, используя pygame и python 2.7, и сейчас я пытаюсь реализовать алгоритм NEAT поверх него.
Чтобы упростить, я сначала хочу, чтобы Pacman, управляемый ИИ, просто путешествовал по карте, «съедая» очки и набирая очки, без каких-либо призраков или чего-либо еще.
Я пытался следовать некоторым примерам, которые я нашел в Интернете, но все они работают в тренажерном зале, в то время как я пытаюсь реализовать его без использования предварительно созданных условий.
По сути, я хочу, чтобы алгоритм NEAT генерировал ~ 50 Пакманов в каждом поколении (моя игра включает в себя класс Пакмана, поэтому его должно быть довольно легко инициировать).
Затем я хочу, чтобы каждый Пакман получил список расстояний от стен по всем направлениям как input . Список будет выглядеть примерно так:
[3, # the distance from the nearest wall to the right of pacman
5, # the distance from the nearest wall to the left of pacman
1, # the distance from the nearest wall up
2] # the distance from the nearest wall down
В качестве вывода я хочу, чтобы алгоритм NEAT выбирал нажатие влево, вправо, вверх, вниз или ничего не делать.
Что у меня сейчас есть:
- У меня есть функция
Pacman.distance_from_walls()
, которая принимает объект Pacman и вычисляет расстояния от стен в каждом направлении.
- У меня есть
Pacman.fitness()
функция, которая получает объект Pacman и возвращает его текущий счет (это должно служить простой функцией пригодности).
Основная проблема, с которой я столкнулся, заключается в том, как заставить NEAT инициировать эти 50 пакманов.
Это то, что я до сих пор делал - основная функция получает объект Pacman, сгенерированный вручную:
def main(pacman):
config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
neat.DefaultSpeciesSet, neat.DefaultStagnation,
'config.config')
def init(pacman):
return Pacman(pacman.game_settings, pacman.Tile_Map, pacman.win) # using the given Pacman's attributes when initiating more Pacmans
config.genome_config.add_activation('pacman_init', init) # trying to tell NEAT how to generate its genomes
pop = neat.Population(config)
def eval_genomes(genomes, config):
for genome_id, genome in genomes:
done = False
net = neat.nn.RecurrentNetwork.create(genome, config)
while not done:
nn_output = net.activate(genome.distances_from_walls())
print nn_output
keyboard.press(nn_output) # using pynput to do stuff
keyboard.release(nn_output)
current_fitness = genome.fitness() # using Pacman.fitness() to get current score
if current_fitness >= 120: # 120 points is enough...
done = True
print "success!"
По сути, я хочу, чтобы каждый "геном" в моем цикле for был объектом Pacman, поэтому я могу использовать функции Pacman (такие как distance_from_walls и fitness ).
В настоящее время я получаю сообщение об ошибке:
AttributeError: 'DefaultGenome' object has no attribute 'distances_from_walls'
Кто-нибудь знает, как это сделать (или направить меня к соответствующим ресурсам ...)? Был бы очень признателен!