TypeError:“ NoneType”和“ float”

问题描述

我正在Tech的Tim指导下使用整洁的方式制作flappyBird游戏,并在Bird Class内创建了self.type,这意味着Bird可以通过键盘输入或整洁的类进行控制,但是在上一代完成后出现此错误

     C:/Users/papadi166/Documents/MEGAsync/AppDev/FlappyBird/main.py:185: DeprecationWarning: an integer is required (got type float).  Implicit conversion to integers using __int__ is deprecated,and may be removed in a future version of Python.
  new_rect = rotated_image.get_rect(center = image.get_rect(topleft = topleft).center)
Traceback (most recent call last):
  File "C:/Users/papadi166/Documents/MEGAsync/AppDev/FlappyBird/main.py",line 393,in <module>
    run(config_path,genome_path="dict.pickle")
  File "C:/Users/papadi166/Documents/MEGAsync/AppDev/FlappyBird/main.py",line 364,in run
    winner = p.run(main,2)
  File "C:\Users\papadi166\PycharmProjects\FlappyBird\venv\lib\site-packages\neat\population.py",line 99,in run
    if best is None or g.fitness > best.fitness:
TypeError: '>' not supported between instances of 'nonetype' and 'float'

Process finished with exit code 1

在我将此代码添加到Population.py之前:

        self.population = fitness_function(list(iteritems(self.population)),self.config)
        self.species.species[1].members = self.population

完成一代后,我收到此错误: 如果best为None或g.fitness> best.fitness: TypeError:'nonetype'和'float'实例之间不支持'>'

我了解加载的获胜者对象有问题,但是我不知道如何在代码中修复该问题。

class Bird:
    IMGS = BIRD_IMGS
    P_IMGS = PLAYER_BIRD_IMGS
    MAX_ROTATION = 25
    ROT_VEL = 20
    ANIMATION_TIME = 5
    
    
    def __init__(self,x,y,t):
        self.x = x
        self.y = y
        self.tilt = 0
        self.tick_count = 0
        self.vel = 0
        self.height = self.y
        self.img_count = 0
        self.p_img = self.P_IMGS[0]
        self.img = self.IMGS[0]
        self.type = t
        
    def jump(self):
        self.vel = -10.5
        self.tick_count = 0
        self.height = self.y
    
    def move(self):
        self.tick_count +=1
        
        d = self.vel * (self.tick_count) + 0.5 * (3) * (self.tick_count)**2
        
        if d >= 16:
            d = (d/abs(d)) * 16
        if d < 0:
            d -= 2
        
        self.y = self.y + d
        
        if d < 0 or self.y < self.height + 50:
            if self.tilt < self.MAX_ROTATION:
                self.tilt = self.MAX_ROTATION
        else:
            if self.tilt > -90:
                self.tilt -= self.ROT_VEL
                
    def draw(self,win):
        self.img_count += 1

        if self.type == 0:
            if self.img_count < self.ANIMATION_TIME:
                self.img = self.IMGS[0]
            elif self.img_count < self.ANIMATION_TIME*2:
                self.img = self.IMGS[1]
            elif self.img_count < self.ANIMATION_TIME*3:
                self.img = self.IMGS[2]
            elif self.img_count < self.ANIMATION_TIME*4:
                self.img = self.IMGS[1]
            elif self.img_count < self.ANIMATION_TIME*4 + 1:
                self.img = self.IMGS[0]
                self.img_count = 0

            if self.tilt <= -80:
                self.img = self.IMGS[1]
                self.img_count = self.ANIMATION_TIME*2

            blitRotateCenter(win,self.img,(self.x,self.y),self.tilt)


        if self.type == 1:
            if self.img_count < self.ANIMATION_TIME:
                self.img = self.P_IMGS[0]
            elif self.img_count < self.ANIMATION_TIME * 2:
                self.img = self.P_IMGS[1]
            elif self.img_count < self.ANIMATION_TIME * 3:
                self.img = self.P_IMGS[2]
            elif self.img_count < self.ANIMATION_TIME * 4:
                self.img = self.P_IMGS[1]
            elif self.img_count < self.ANIMATION_TIME * 4 + 1:
                self.img = self.P_IMGS[0]
                self.img_count = 0

            if self.tilt <= -80:
                self.img = self.P_IMGS[1]
                self.img_count = self.ANIMATION_TIME * 2

            blitRotateCenter(win,self.p_img,self.tilt)

    def get_mask(self):
        if self.type == 0:
            return pygame.mask.from_surface(self.img)
        elif self.type == 1:
            return pygame.mask.from_surface(self.p_img)

def main(genomes,config):

    """
    We need to keep track of neural network that controls each bird,because these genomes when they come in
    are really just a bunch of neural networks that are gonna control each of our birds,I need to keep track of the bird
    that that neural networks controlling so where that position is in the screen and I need to keep track of our genomes so
    that I actually change their fitness based on you kNow for they move or if they hit a pipe or if they do all this stuff
    so i do three lists to do this maybe not the most efficient way but should work fine
    """
    global GEN
    GEN += 1
    nets = []
    birds = []
    ge = []
    # Change bird = Bird(230,350) to

    x = 0
    for _,g in genomes:
        if (x < len(genomes) -1) :
            net = neat.nn.FeedForwardNetwork.create(g,config)
            nets.append(net)
            birds.append(Bird(230,350,0))
            g.fitness = 0
            ge.append(g)
            x += 1
        if (x == len(genomes) -1):
            net = neat.nn.FeedForwardNetwork.create(g,1))
            g.fitness = 0
            ge.append(g)
            x += 1

    base = Base(730)
    pipes = [Pipe(600)]
    win = pygame.display.set_mode((WIN_WIDTH,WIN_HEIGHT))
    run = True
    clock = pygame.time.Clock()

    score = 0

    while run:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    for bird in birds:
                        if bird.type == 1:
                            bird.jump()


        pipe_ind = 0
        if len(birds) > 0:
            if len(pipes) > 1 and birds[0].x > pipes[0].x + pipes[0].PIPE_TOP.get_width():
                pipe_ind = 1
        else:
            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 - pipes[pipe_ind].height),abs(bird.y - pipes[pipe_ind].bottom)))

            if output[0] > 0.5:
                if bird.type != 1:
                    bird.jump()

        #bird.move()
        add_pipe = False
        rem = []
        
        for pipe in pipes:
            for x,bird in enumerate(birds):
                # indent only this collision if becouse the rest of code don't have to be running at this for loop.
                if pipe.collide(bird):
                    ge[x].fitness -= 1 # Every time a bird hits a pipe is gonna have one removed from its fitness score
                    birds.pop(x)
                    nets.pop(x)
                    ge.pop(x)


                #Change bird.x to birds[0]... OR NOT..  better put that function into this for loop,because mian will runs 50 times so caling birds[0] 50 times isn't.. IDK. Efficient?
                if not pipe.passed and pipe.x < bird.x:
                    pipe.passed = True
                    add_pipe = True

            if pipe.x + pipe.PIPE_TOP.get_width() < 0:
                rem.append(pipe)

            pipe.move()

        if add_pipe:
            score += 1
            for g in ge:
                g.fitness += 5
            pipes.append(Pipe(700))

        for r in rem:
            pipes.remove(r)
        for x,bird in enumerate(birds):
            if bird.y + bird.img.get_height() >= 730 or bird.y < 0:
                birds.pop(x)
                nets.pop(x)
                ge.pop(x)

        base.move()
        draw_window(win,birds,pipes,base,score,GEN)

        if score >= 50:
            for x,bird in enumerate(birds):
                # indent only this collision if becouse the rest of code don't have to be running at this for loop.
                ge[x].fitness -= 1  # Every time a bird hits a pipe is gonna have one removed from its fitness score
                birds.pop(x)
                nets.pop(x)
                ge.pop(x)

def run(config_path,genome_path="dict.pickle"):
    import pickle
    genomes = []
    # Load the configuration
    config = neat.config.Config(neat.DefaultGenome,neat.DefaultReproduction,neat.DefaultSpeciesSet,neat.DefaultStagnation,config_path)
    # Setup population
    p = neat.Population(config)

    #Set the output that we gonna see
    p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)

    # Set the fitness funnction ( This func. runs main func. 50 times and pass it all of the genoms so                                                                                   like that population current generation populations  )


    winner = p.run(main,2)

    with open("dict.pickle","wb") as infile:
        pickle.dump(winner,infile)
        infile.close()

    # Unpickle saved winner
    with open(genome_path,"rb") as infile:
        genome = pickle.load(infile)

    # Convert loaded genome into required data structure
    genomes = [(1,genome)]
    type = "test"
    # Call game with only the loaded genome
    main(genomes,config)
    print("LOL")
  
if __name__ == '__main__':
    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir,"config-Feedforward.txt")
    run(config_path,genome_path="dict.pickle")

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)