Python - реализация алгоритма NEAT поверх игры Pacman - PullRequest
0 голосов
/ 21 апреля 2019

Я недавно закончил кодировать свою собственную игру 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 выбирал нажатие влево, вправо, вверх, вниз или ничего не делать.

Что у меня сейчас есть:

  1. У меня есть функция Pacman.distance_from_walls(), которая принимает объект Pacman и вычисляет расстояния от стен в каждом направлении.
  2. У меня есть 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'

Кто-нибудь знает, как это сделать (или направить меня к соответствующим ресурсам ...)? Был бы очень признателен!

...