예제 #1
0
파일: game.py 프로젝트: MetalMethod/sNNake
 def init_game_objects(self):
     self.grid = Grid(GRID_CELL_SIZE, GREY, pygame, self.screen, MAP_SIZE)
     self.player = Player(self.grid.center_x, self.grid.center_y,
                          GRID_CELL_SIZE, BODY_LENGTH)
     self.food = Food(GRID_CELL_SIZE, self.grid.rows - 1,
                      self.grid.columns - 1)
     self.controller = Controller(self.player)
예제 #2
0
 def __init__(self, input_service, output_service):
     """The class constructor.
     
     Args:
         self (Director): an instance of Director.
     """
     self._food = Food()
     self._input_service = input_service
     self._keep_playing = True
     self._output_service = output_service
     self._score = Score()
     self._snake = Snake()
예제 #3
0
 def __init__(self, players):
     highscores = load_highscores()
     self.highscore = highscores[0].score if highscores else 0
     self.players = players
     self.squares = (17, 15)
     self.game_surface: GameSurface = GameSurface(window)
     self.field: GameFieldSurface = GameFieldSurface(
         self.game_surface, self.squares)
     self.food = Food(self.field, Image.food_image)
     self.super_food = SuperFood(self.field, Image.super_food_image)
     self.food.recreate(self.players, self.super_food, self.field.grid_size)
     player_starting_xs = [
         self.field.grid_size * (i * 3 + 4)
         for i in range(len(self.players))
     ]
     for i in range(len(self.players)):
         self.players[i].x = player_starting_xs[i]
예제 #4
0
    def __init__(self, code_id, log=False, visualization=False, fps=60):
        self.code_id = code_id
        self.snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE,
                           WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2)
        self.food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE)
        self.food.spawn(self.snake)

        self.log = log
        self.visualization = visualization
        self.window, self.clock = self.init_visualization()
        self.fps = fps

        # basic infos
        self.alive = True
        self.score = 0
        self.step = 0
        # useful infos
        self.s_obstacles = self.get_surrounding_obstacles()
        self.food_angle = self.get_food_angle()
        self.food_distance = self.get_food_distance()
예제 #5
0
def main():
    window = pygame.display.set_mode(
        (WINDOW_WIDTH * PIXEL_SIZE, WINDOW_HEIGHT * PIXEL_SIZE))
    pygame.display.set_caption('SNAKE GAME')
    clock = pygame.time.Clock()

    score = 0
    snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE, WINDOW_WIDTH / 2,
                  WINDOW_HEIGHT / 2)
    food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE)

    run = True

    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                break
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    snake.change_direction(-1)
                    break
                elif event.key == pygame.K_RIGHT:
                    snake.change_direction(+1)
                    break

        snake.move()

        if snake.collision_food(food.location):
            score += 1
            food.state = False

        food.spawn(snake)

        if snake.collision_obstacles():
            print('over')
            run = False

        if snake.get_length() == WINDOW_WIDTH * WINDOW_HEIGHT:
            print('win')
            run = False

        window.fill((0, 0, 0))
        food.render(window)
        snake.render(window)
        pygame.display.set_caption('SNAKE GAME | Score: ' + str(score))
        pygame.display.update()
        clock.tick(FPS)
예제 #6
0
class Game:
    def __init__(self, players):
        highscores = load_highscores()
        self.highscore = highscores[0].score if highscores else 0
        self.players = players
        self.squares = (17, 15)
        self.game_surface: GameSurface = GameSurface(window)
        self.field: GameFieldSurface = GameFieldSurface(
            self.game_surface, self.squares)
        self.food = Food(self.field, Image.food_image)
        self.super_food = SuperFood(self.field, Image.super_food_image)
        self.food.recreate(self.players, self.super_food, self.field.grid_size)
        player_starting_xs = [
            self.field.grid_size * (i * 3 + 4)
            for i in range(len(self.players))
        ]
        for i in range(len(self.players)):
            self.players[i].x = player_starting_xs[i]

    def start(self):
        """Játékmenet vezérlője."""

        end = False
        timer = pygame.time.Clock()
        pygame.event.set_allowed(pygame.KEYDOWN)

        while not end:
            # 60 FPS
            timer.tick(60)

            # Event loop
            events = pygame.event.get()
            for event in events:
                if event.type == pygame.QUIT:
                    return True

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        end = True

                if event.type == pygame.KEYDOWN:
                    for player in self.players:
                        player.controlled_move(event, self.field.grid_size)

            for player in self.players:
                # ha nem mozdult gombokkal akkor mozdítsuk a kigyot a jelenlegi irányba tovább
                if not player.key_pressed:
                    player.move(self.field.grid_size)

                # ha saját magába, vagy a falba ment, akkor a játéknak vége
                if player.detect_self_collision(
                        self.field.grid_size) or player.detect_wall_collision(
                            self.field):
                    player.is_lost = True
                    end = True
                    winsound.PlaySound("assets/sounds/dead.wav", 1)

                # új highscore beállitása ha valamelyik player meghaladta az eddigi legmagasabbat
                if player.score > self.highscore:
                    self.highscore = player.score

                # Alma felvétel kezelése
                if player.detect_food_collision(self.food,
                                                self.field.grid_size):
                    self.food.recreate(self.players, self.super_food,
                                       self.field.grid_size)
                    player.score += 1
                    player.length += 1
                    winsound.PlaySound("assets/sounds/eat.wav", 1)

                # Szuper alma felvétel kezelése
                if player.detect_food_collision(self.super_food,
                                                self.field.grid_size):
                    player.score += 5
                    player.length += 1
                    self.super_food.handle_collision()
                    winsound.PlaySound("assets/sounds/eat.wav", 1)

                # Alapértékre állítás, nem nyomott irányváltoztató gombot
                player.key_pressed = False

                # Esetleges új sebességek beállítása
                player.calculate_velocity()

            # Kétjátékos módban ha egymásba mentek akkor a játéknak vége
            if len(self.players) > 1:
                j = len(self.players) - 1
                for i in range(len(self.players)):
                    if self.players[i].detect_enemy_collision(
                            self.players[j], self.field.grid_size):
                        self.players[i].is_lost = True
                        end = True
                        winsound.PlaySound("assets/sounds/dead.wav", 1)
                    j -= 1

            # Szuper alma megfelelő számlálójának növelése
            self.super_food.update_counters()

            # Megnézzük és eltüntetjük a szuper almát ha kell
            self.super_food.check_for_remove()

            # Ha még nincs szuper almánk és idő van, 30% eséllyel spawnol egy
            self.super_food.check_for_spawn(self.players, self.food,
                                            self.field.grid_size)

            # újra rajzoljuk a képernyőt
            self.redraw()

    def redraw(self):
        """Újra rajzolja a képernyőt a játékállásnak megfelelően."""

        self.game_surface.redraw(self.players, self.highscore)
        self.field.redraw()

        self.food.draw(self.field.surface)

        if self.super_food.visible:
            self.super_food.draw(self.field.surface)

        for i in range(len(self.players)):
            self.players[i].draw(self.field.surface)

        self.field.blit()
        self.game_surface.scaled_blit_to_parent()

        pygame.display.update()
예제 #7
0
class Agent:
    def __init__(self, code_id, log=False, visualization=False, fps=60):
        self.code_id = code_id
        self.snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE,
                           WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2)
        self.food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE)
        self.food.spawn(self.snake)

        self.log = log
        self.visualization = visualization
        self.window, self.clock = self.init_visualization()
        self.fps = fps

        # basic infos
        self.alive = True
        self.score = 0
        self.step = 0
        # useful infos
        self.s_obstacles = self.get_surrounding_obstacles()
        self.food_angle = self.get_food_angle()
        self.food_distance = self.get_food_distance()

    def init_visualization(self):
        if self.visualization:
            window = pygame.display.set_mode(
                (WINDOW_WIDTH * PIXEL_SIZE, WINDOW_HEIGHT * PIXEL_SIZE))
            fps = pygame.time.Clock()
            return window, fps
        else:
            return None, None

    def get_random_move(self, random_n=10):

        # real random move, 1/random_n
        if random_n is not 0 and random.randint(1, random_n) == 1:
            return random.randint(-1, 1)

        s, a, d = self.get_state()
        # random move depend on state
        ops = []
        # select move based on following the food angle and avoiding the obstacles
        if not s[0] and a < 0:
            ops.insert(-1, -1)
        if not s[1] and a == 0:
            ops.insert(-1, 0)
        if not s[2] and a > 0:
            ops.insert(-1, +1)

        # if no option
        if not ops:
            # select move based on avoiding obstacles
            if not s[0]:
                ops.insert(-1, -1)
            if not s[1]:
                ops.insert(-1, 0)
            if not s[2]:
                ops.insert(-1, +1)

            # again, if no option -> just die
            if not ops:
                return random.randint(-1, 1)
            else:
                return ops[random.randint(0, len(ops) - 1)]
        else:
            return ops[random.randint(0, len(ops) - 1)]

    def next_state(self, move_direction):
        self.step += 1
        info = 'CodeID: {} | Step: {} | Score: {}'.format(
            self.code_id, self.step, self.score)

        self.snake.change_direction(move_direction)
        self.snake.move()

        if self.snake.collision_food(self.food.location):
            self.score += 1
            self.food.state = False

        self.food.spawn(self.snake)

        if self.snake.collision_obstacles():
            info += ' >> Game Over!'
            self.alive = False

        if self.snake.get_length() == WINDOW_WIDTH * WINDOW_HEIGHT:
            info += ' >> Win!'
            self.alive = False

        if self.log:
            print(info)

        if self.visualization:
            self.window.fill((0, 0, 0))
            self.food.render(self.window)
            self.snake.render(self.window)
            pygame.display.set_caption(info)
            pygame.display.update()
            pygame.event.get()
            self.clock.tick(self.fps)

        return self.get_state()

    def get_state(self):
        return self.get_surrounding_obstacles(), self.get_food_angle(
        ), self.get_food_distance()

    def get_surrounding_obstacles(self):
        # check front
        snake_head = self.snake.head
        snake_heading_direction = self.snake.heading_direction
        left = self.snake.moves[(snake_heading_direction - 1) %
                                len(self.snake.moves)]
        front = self.snake.moves[snake_heading_direction]
        right = self.snake.moves[(snake_heading_direction + 1) %
                                 len(self.snake.moves)]
        l_location = [snake_head[0] + left[0], snake_head[1] + left[1]]
        f_location = [snake_head[0] + front[0], snake_head[1] + front[1]]
        r_location = [snake_head[0] + right[0], snake_head[1] + right[1]]

        s_locations = [l_location, f_location, r_location]
        self.s_obstacles = [0, 0, 0]

        # check wall
        for i in range(0, len(s_locations)):
            if s_locations[i][0] < 0 or s_locations[i][0] >= WINDOW_WIDTH \
                    or s_locations[i][1] < 0 or s_locations[i][1] >= WINDOW_HEIGHT:
                self.s_obstacles[i] = 1

        # check body
        for b in self.snake.body:
            if b in s_locations:
                self.s_obstacles[s_locations.index(b)] = 1

        return self.s_obstacles

    def get_food_angle(self):
        # get direction of heading
        heading_direction = numpy.array(
            self.snake.moves[self.snake.heading_direction])
        # get direction of food (distant)
        food_direction = numpy.array(self.food.location) - numpy.array(
            self.snake.head)

        h = heading_direction / numpy.linalg.norm(heading_direction)
        f = food_direction / numpy.linalg.norm(food_direction)

        fa = math.atan2(h[0] * f[1] - h[1] * f[0],
                        h[0] * f[0] + h[1] * f[1]) / math.pi

        if fa == -1 or fa == 1:
            fa = 1

        self.food_angle = fa

        return self.food_angle

    def get_food_distance(self):
        head = numpy.array(self.snake.head)
        food = numpy.array(self.food.location)

        max_dis = numpy.linalg.norm(
            numpy.array([0, 0]) -
            numpy.array([WINDOW_WIDTH - 1, WINDOW_HEIGHT - 1]))
        dis = numpy.linalg.norm(head - food)

        # normalize distance to the range 0 - 1
        self.food_distance = dis / max_dis

        return self.food_distance
예제 #8
0
파일: game.py 프로젝트: MetalMethod/sNNake
class Game:
    def __init__(self, max_games):
        pygame.init()
        pygame.display.set_caption('sNNake')
        self.icon = pygame.Surface((32, 32))
        pygame.display.set_icon(self.icon)
        self.screen = pygame.display.set_mode(WINDOW_SIZE)
        self.clock = pygame.time.Clock()
        self.count = 1
        self.max_games = max_games
        self.init_game_objects()

    def init_game_objects(self):
        self.grid = Grid(GRID_CELL_SIZE, GREY, pygame, self.screen, MAP_SIZE)
        self.player = Player(self.grid.center_x, self.grid.center_y,
                             GRID_CELL_SIZE, BODY_LENGTH)
        self.food = Food(GRID_CELL_SIZE, self.grid.rows - 1,
                         self.grid.columns - 1)
        self.controller = Controller(self.player)

    def game_status(self):
        #print("##### GAME START ##### game count: ", self.count)
        return

    def draw(self):
        # erase the screen
        self.screen.fill(BLACK)
        #draw objects
        self.food.draw(pygame, self.screen, WHITE)
        #draw body
        for el in self.player.body_list:
            el.draw(pygame, self.screen, WHITE)

        self.grid.draw()

    def exit_conditions(self):
        if (pygame.key.get_pressed()[pygame.K_RETURN] == 1): return  #break
        if (pygame.key.get_pressed()[pygame.K_ESCAPE] == 1): sys.exit()
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()

    def check_isAlive(self, sensors):
        if (sensors.detect_walls(self.grid, self.player.position)):
            self.player.alive = False
            #self.player.position = [10,10]
            #print("WALL HIT")

        if (sensors.detect_body(self.player.position)):
            self.player.alive = False
            #print("BODY HIT")
        return

    def reset(self):
        self.init_game_objects()
        self.score = 0

    def update_objects(self, sensors):
        self.controller.detect_keyboard()
        self.player.turn()
        self.player.update_body()
        self.check_isAlive(sensors)
        if (self.food.detect_colision(self.player)):
            self.score = self.score + 1

    ### update pygame and close the step
    def finish_step(self):
        #msElapsed = clock.tick(30)
        pygame.display.update()
        pygame.time.delay(TIME_DELAY)

    def observation(self):
        return self.player, self.food

    # concept of step function from open ai: one step receaves a input and generates a observation.
    def step(self, sensors, action):
        self.exit_conditions()
        self.draw()
        self.update_objects(sensors)
        self.controller.input(action)

        ### STEP OBSERVATION CODE

        ### update all and close the step
        self.finish_step()
예제 #9
0
class Director:
    """A code template for a person who directs the game. The responsibility of 
    this class of objects is to control the sequence of play.
    
    Stereotype:
        Controller

    Attributes:
        food (Food): The snake's target.
        input_service (InputService): The input mechanism.
        keep_playing (boolean): Whether or not the game can continue.
        output_service (OutputService): The output mechanism.
        score (Score): The current score.
        snake (Snake): The player or snake.
    """

    def __init__(self, input_service, output_service):
        """The class constructor.
        
        Args:
            self (Director): an instance of Director.
        """
        self._food = Food()
        self._input_service = input_service
        self._keep_playing = True
        self._output_service = output_service
        self._score = Score()
        self._snake = Snake()
        
    def start_game(self):
        """Starts the game loop to control the sequence of play.
        
        Args:
            self (Director): an instance of Director.
        """
        while self._keep_playing:
            self._get_inputs()
            self._do_updates()
            self._do_outputs()
            sleep(constants.FRAME_LENGTH)

    def _get_inputs(self):
        """Gets the inputs at the beginning of each round of play. In this case,
        that means getting the desired direction and moving the snake.

        Args:
            self (Director): An instance of Director.
        """
        direction = self._input_service.get_direction()
        self._snake.move_head(direction)

    def _do_updates(self):
        """Updates the important game information for each round of play. In 
        this case, that means checking for a collision and updating the score.

        Args:
            self (Director): An instance of Director.
        """
        self._handle_body_collision()
        self._handle_food_collision()
        
    def _do_outputs(self):
        """Outputs the important game information for each round of play. In 
        this case, that means checking if there are stones left and declaring 
        the winner.

        Args:
            self (Director): An instance of Director.
        """
        self._output_service.clear_screen()
        self._output_service.draw_actor(self._food)
        self._output_service.draw_actors(self._snake.get_all())
        self._output_service.draw_actor(self._score)
        self._output_service.flush_buffer()

    def _handle_body_collision(self):
        """Handles collisions between the snake's head and body. Stops the game 
        if there is one.

        Args:
            self (Director): An instance of Director.
        """
        head = self._snake.get_head()
        body = self._snake.get_body()
        for segment in body:
            if head.get_position().equals(segment.get_position()):
                self._keep_playing = False
                break

    def _handle_food_collision(self):
        """Handles collisions between the snake's head and the food. Grows the 
        snake, updates the score and moves the food if there is one.

        Args:
            self (Director): An instance of Director.
        """
        head = self._snake.get_head()
        if head.get_position().equals(self._food.get_position()):
            points = self._food.get_points()
            for n in range(points):
                self._snake.grow_tail()
            self._score.add_points(points)
            self._food.reset()