NEAT를 사용하여 AI를 가르치는 Pygame을 사용하여 게임을 만들었지 만, 갑자기 파이 게임이 아무것도 그리지 않습니다.

코이 투트

파이 게임을 사용하여 만든 게임을하기 위해 AI를 구축하는 중이고 간단한 게임을 구축했는데 예상대로 작동했습니다. NEAT를 구현하기 시작했고 마침내 오류가 발생하지 않는 코드를 얻었지만 실행하면 파이 게임 창이 검은 색으로 만 채워지고 이유를 모르겠습니다. 나는 그 문제에 대해 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)
Kingsley

코드가 전혀 작동하지 않습니다 neat. 내 머리 위에서 디버깅 하는 모듈에 익숙하지 않습니다 . 그러나 문제 설명에 따르면 main()함수의 들여 쓰기 오류처럼 보입니다 . 나는 기대 while not done:루프 필요가 화면에 도면, 그리고 현재하지 않는 이벤트의 처리를 포함 할 수 있습니다.

그것은 당신이 같은 것을 통해 코드를 실행하기 위해 behoove 것 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)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관