Пример #1
0
    def test_model(self, model):
        steps_list = []
        scores_list = []

        for test_game in range(self.test_games):
            steps = 0
            game = Board()
            prev_observation = self.generate_observation(game)

            for goal_step in range(self.goal_steps):
                predictions = []
                for action in [-1, 0, 1]:
                    predictions.append(model.predict(np.reshape(self.add_act_to_observ(prev_observation, action), (-1, 5, 1))))
                action = np.argmax(np.array(predictions)) - 1
                game_move = self.generate_game_move(game.snake, action)
                try:
                    game.run(game_move)
                    prev_observation = self.generate_observation(game)
                    steps += 1
                except GameOver as g:
                    print("Test game %d had score %d and took %d steps" % (test_game, game.score, steps))
                    break

            steps_list.append(steps)
            scores_list.append(game.score)

        print('Average steps: ', mean(steps_list))
        print(Counter(steps_list))

        print('Average score: ', mean(scores_list))
        print(Counter(scores_list))
Пример #2
0
    def generate_population(self):
        training_data = []

        for init_game in range(self.initial_games):
            game = Board()
            prev_observation = self.generate_observation(game)
            prev_food_distance = np.linalg.norm(np.array(game.food) - np.array(game.snake[-1]))
            prev_score = game.score

            for step in range(self.goal_steps):
                action, direction = self.generate_action(game.snake)
                try:
                    game.run(direction)
                    food_distance = np.linalg.norm(np.array(game.food) - np.array(game.snake[-1]))
                    score = game.score

                    if score > prev_score or food_distance < prev_food_distance:
                        training_data.append([self.add_act_to_observ(prev_observation, action), 1])
                    else:
                        training_data.append([self.add_act_to_observ(prev_observation, action), 0])

                    prev_observation = self.generate_observation(game)
                    prev_food_distance = food_distance
                except GameOver as g:
                    if str(g) == "You Win":
                        training_data.append([self.add_act_to_observ(prev_observation, action), 1])
                    else:
                        training_data.append([self.add_act_to_observ(prev_observation, action), -1])
                    break

        return training_data
Пример #3
0
class SnakeInterface:
    # TODO: draw borders?

    def __init__(self):
        self._running = True
        self._game_over = False
        self._game_over_message = ""
        self._no_keys_pressed = True
        self._game = Board()
        # self._frame_rate = 7 Perhaps we do not need this since we are using clock ticks?
        self._clock = pygame.time.Clock()

        self._surface = pygame.display.set_mode((600, 600), pygame.RESIZABLE)

    def run(self):
        """Game loop"""
        pygame.init()
        #self._surface = pygame.display.set_mode((600, 600), pygame.RESIZABLE)

        try:
            while self._running:
                self._clock.tick(2)
                self._no_keys_pressed = True

                # handles various events in PyGame
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        self._running = False
                    elif event.type == pygame.KEYDOWN and not self._game_over:
                        self._no_keys_pressed = False
                        self._handle_keys(event)

                # snake moves forward if no keys are pressed
                if self._no_keys_pressed:
                    try:
                        if not self._game_over:
                            self._game.run()
                    except GameOver as g:
                        # this is how interface knows when to stop
                        self._game_over = True
                        self._game_over_message = str(g)

                self._draw_frame()
        finally:
            pygame.quit()

    def _handle_keys(self, event):
        """Handles key presses"""
        # gets whatever key was pressed
        #keys = pygame.key.get_pressed()

        try:
            if event.key == pygame.K_LEFT:
                self._game.run(LEFT)
            elif event.key == pygame.K_RIGHT:
                self._game.run(RIGHT)
            elif event.key == pygame.K_UP:
                self._game.run(UP)
            elif event.key == pygame.K_DOWN:
                self._game.run(DOWN)
        except GameOver as g:
            self._game_over = True
            self._game_over_message = str(g)

    def _draw_frame(self):
        """Draws frame based on game state"""
        self._surface.fill(pygame.Color(255, 255, 255))
        self._draw_board()
        if self._game_over:
            self._display_game_over()
        pygame.display.flip()

    def _draw_board(self):
        """Draws board based on game state"""
        block_size = self._surface.get_width() / BOARD_SIZE - 5
        for y in range(BOARD_SIZE):
            for x in range(BOARD_SIZE):
                rect = pygame.Rect(x * (block_size + 1), y * (block_size + 1),
                                   block_size, block_size)
                if self._game.board[y][x].foodTile:
                    pygame.draw.rect(self._surface, (255, 0, 0), rect)
                elif self._game.board[y][x].snakeTile:
                    pygame.draw.rect(self._surface, (0, 255, 0), rect)
                else:
                    pygame.draw.rect(self._surface, (0, 0, 0), rect)

    def _display_game_over(self):
        """Displays game over message"""
        width = self._surface.get_width()
        height = self._surface.get_height()
        fontsize = int(.1 * width)
        x_ratio = .2
        y_ratio = .75
        new_x = x_ratio * width
        new_y = y_ratio * height
        font = pygame.font.SysFont("comicsansms", fontsize)
        game_over_label = font.render(self._game_over_message, 1, (0, 0, 0))
        self._surface.blit(game_over_label, (int(new_x), int(new_y)))