2

I'm currently trying to create a NEAT algorithm to solve FlappyBird but am coming across an error while running my code (see title). Currently I have set up my run function and my eval_genomes functions. I've simplified them to remove the pygame stuff and tried to keep it just to the neat-python relevant bits.

I know there are ways I could make this better, but I can someone help in finding how to solve the error I'm seeing below.

The error seems to stem from the neat-python module, but I've uninstalled and reinstalled it so there isn't anything wrong with the module. I've run someone else's code and there's works so again module seems to work fine.

def run(config_path):
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
                         neat.DefaultSpeciesSet, neat.DefaultStagnation,
                         config_path)

    p = neat.Population(config)

    p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)

    winner = p.run(eval_genomes,20)
def eval_genomes(genomes, config):
    run = True
    game = Game(WIN)

    nets = []
    ge = []
    birds = []

    for g in genomes:
        net = neat.nn.FeedForwardNetwork.create(g, config)
        nets.append(net)
        birds.append(Bird(WIN))
        g.fitness = 0
        ge.append(g)

    while run:
        if len(birds) = 0:
            run = False
            break

        for x, bird in enumerate(birds):
            bird.move()
            ge[x].fitness += 0.1

            output = nets[x].activate((bird.y,
                                      abs(bird.y - game.pipes[pipe_ind].height),
                                      abs(bird.y - game.pipes[pipe_ind].bottom)))

            if output[0] > 0.5:
                bird.jump()

        for x, bird in enumerate(birds):
            if game.check_collisions(bird):
                ge[x].fitness -= 1
                birds.pop(x)
                nets.pop(x)
                ge.pop(x)

        if game.pipe_passed(birds[0]):
            for g in ge:
                g.fitness += 5

        game.update()                        # Move all the other pieces

Traceback (most recent call last):
  File "/Users/Ali/Documents/Coding Projects/Python/ToDo/Flappy-Bird-AI/Main.py", line 106, in <module>
    run(config_path)
  File "/Users/Ali/Documents/Coding Projects/Python/ToDo/Flappy-Bird-AI/Main.py", line 99, in run
    winner = p.run(eval_genomes,20)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/neat/population.py", line 89, in run
    fitness_function(list(iteritems(self.population)), self.config)
  File "/Users/Ali/Documents/Coding Projects/Python/ToDo/Flappy-Bird-AI/Main.py", line 34, in eval_genomes
    net = neat.nn.FeedForwardNetwork.create(g, config)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/neat/nn/feed_forward.py", line 33, in create
    connections = [cg.key for cg in itervalues(genome.connections) if cg.enabled]
AttributeError: 'tuple' object has no attribute 'connections'
  • 1
    error show problem with `connections` and there it shows also `genome.connections` sO I would try to check what is in `genome` - ie. `print(genome)` and `print(type(genome))`. It seems you use wrong value - `tuple` - but it should be some special object. – furas Dec 31 '20 at 22:37
  • 1
    Got it sorted, thanks! By printing genome I saw it was giving me (1, genome object<>) and so I changed my for loop to iterate as the following `for genome_id, genome in genomes:` – Alastair McNeill Jan 01 '21 at 20:29

1 Answers1

0

This is very late, but I just had this problem and after a while I figured it out. I thought I would just post the solution here for anyone else who experiences this in the future. Your problem is when you are unpacking genomes.

for g in genomes:
    net = neat.nn.FeedForwardNetwork.create(g, config)
    nets.append(net)
    birds.append(Bird(WIN))
    g.fitness = 0
    ge.append(g)

To properly unpack genomes, it be must unpacked into 2 separate objects genome and genome_ID as so:

for genome_id, g in genomes:
    net = neat.nn.FeedForwardNetwork.create(g, config)
    nets.append(net)
    birds.append(Bird(WIN))
    g.fitness = 0
    ge.append(g)