def test_snake_check_collision_with_fruit_while_moving(self):
        """
        A Snake instance will be created at given coordinates.
        It will then be moved in a pattern around a fruit,
        not being able to take it before the last move. 
        After each movement, a test will be conducted.
        """

        fruit_coordinates = (60, 60)
        fruit_size = (30, 30)
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [
            False, False, False, False, False, False, False, True
        ]

        test_vector = [
            Snake.move_down, Snake.move_down, Snake.move_right,
            Snake.move_right, Snake.move_up, Snake.move_up, Snake.move_left,
            Snake.move_down
        ]
        for expected, test_move in zip(expected_results, test_vector):
            with self.subTest("Snake.{}".format(test_move.__name__)):
                test_move(snake)

                self.assertEqual(
                    snake.check_collision_with_fruit(fruit_coordinates,
                                                     fruit_size), expected)
    def test_snake_growing_while_moving(self):
        """
        A snake instance will be created at given coordinates.
        It will then be moved in a pattern, growing after each movement.
        Each movement will carry with it a control to make sure that
        the entire body moves as expected.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [[(30, 0), (30, 30)], [(60, 0), (30, 0), (30, 30)],
                            [(60, 30), (60, 0), (30, 0), (30, 30)],
                            [(60, 60), (60, 30), (60, 0), (30, 0), (30, 30)],
                            [(30, 60), (60, 60), (60, 30), (60, 0), (30, 0),
                             (30, 30)],
                            [(0, 60), (30, 60), (60, 60), (60, 30), (60, 0),
                             (30, 0), (30, 30)],
                            [(0, 90), (0, 60), (30, 60), (60, 60), (60, 30),
                             (60, 0), (30, 0), (30, 30)],
                            [(30, 90), (0, 90), (0, 60), (30, 60), (60, 60),
                             (60, 30), (60, 0), (30, 0), (30, 30)]]
        test_vector = [
            Snake.move_up, Snake.move_right, Snake.move_down, Snake.move_down,
            Snake.move_left, Snake.move_left, Snake.move_down, Snake.move_right
        ]

        for expected, test_move in zip(expected_results, test_vector):
            with self.subTest("Snake.{}".format(test_move.__name__)):
                snake.grow()
                test_move(snake)
                result = []
                for parts in snake:
                    result.append(parts.get_coordinates())

                self.assertListEqual(result, expected)
Example #3
0
def mode_1(screen):
    snake = Snake(screen)
    apple = Apple(screen)

    def Key_Board_Ev(event):
        if event.keysym == 'd':
            snake.KeyBoard(1, 0)
        if event.keysym == 'a':
            snake.KeyBoard(-1, 0)
        if event.keysym == 'w':
            snake.KeyBoard(0, -1)
        if event.keysym == 's':
            snake.KeyBoard(0, 1)

    screen.root.bind('<Key>', Key_Board_Ev)

    while True:
        snake.S_Update()
        if snake.Is_Exit:
            break
        if snake.body_pos[0] == apple.apple_pos:
            apple.Apple_Is_Eatten()
            snake.Apple_Is_Eatten()
        snake.Wall()
        screen.root.update()
    def test_snake_check_collision_with_self(self):
        """
        This test will create a Snake instance at given coordinates.
        A collision with self check will then be conducted.
        This check is expected to be false.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        self.assertEqual(snake.check_collision_with_self(), False)
    def test_snake_grow(self):
        """
        This test will create a Snake instance at given coordinates.
        Grow will then be called to make sure that no chrash occour.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        self.assertIsNone(
            snake.grow(),
            "Snake.grow() should neither return an object nor raise an error.")
Example #6
0
def mode_2(screen):
    leader_table = Leader_Table(screen)
    snake = Snake(screen)
    apple = Apple(screen)

    def Key_Board_Ev(event):
        if event.keysym == 'd':
            snake.KeyBoard(1, 0)
        if event.keysym == 'a':
            snake.KeyBoard(-1, 0)
        if event.keysym == 'w':
            snake.KeyBoard(0, -1)
        if event.keysym == 's':
            snake.KeyBoard(0, 1)

    screen.root.bind('<Key>', Key_Board_Ev)

    otimer = Timer(screen)
    bufs = Bufs(screen)
    score = Score(screen)

    while True:
        otimer.Update()
        snake.S_Update()
        if (otimer.min_col < 0 or snake.Is_Exit):
            break
        if snake.body_pos[0] == apple.apple_pos:
            apple.Apple_Is_Eatten()
            snake.Apple_Is_Eatten()
            bufs.Is_Gen()
            score.Apple_Is_Eatten()
        snake.Wall()
        nbuf = bufs.Is_Buffed(snake.body_pos[0])
        bufs.Clean_buf()
        if nbuf != -1:
            if nbuf == 'tplus':
                otimer.sec_col += 40
                otimer.min_col += int(otimer.sec_col // 60)
                otimer.sec_col = otimer.sec_col % 60
            if nbuf == 'lucky':
                ind = bufs.Gen_Rand_Int(0, 1)
                if ind == 1:
                    score.score += 100
                    score.Set_Score()
                else:
                    break
        screen.root.update()
    leader_table.Update_T(score.score)
    leader_table.Table_Visual()
    def test_snake_iterable(self):
        """
        This test will create a Snake instance at given coordinates.
        An attempt will then be made to iterate over the instance.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        self.assertIsInstance(snake, Iterable)
    def test_snake_check_collision(self):
        """
        This test will create a Snake instance at given coordinates.
        Two collision checks will then be conducted.
            One of the collision checks will be true.
            The other will be false.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [True, False]
        results = []
        test_vectors = [[(30, 30), (5, 5)], [(70, 70), (10, 10)]]

        for test_vector in test_vectors:
            results.append(
                snake.check_collision(test_vector[0], test_vector[1]))

        self.assertListEqual(results, expected_results)
    def test_snake_inside_bounds(self):
        """
        This test will create a Snake instance at given coordinates.
        Three bounds will then be created.
            One of the bounds will the Snake be completely inside of
            One will it be partially inside of
            And the last one will it be outside of
        """

        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [True, False, False]
        results = []
        test_vectors = [[(0, 0), (150, 150)], [(30, 30), (35, 35)],
                        [(70, 70), (100, 100)]]

        for test_vector in test_vectors:
            results.append(snake.inside_bounds(test_vector[0], test_vector[1]))

        self.assertListEqual(results, expected_results)
Example #10
0
def main():
    #global vars
    global s, snack
    st.init()
    s = Snake(st.snake_color, (st.snake_x, st.snake_y))
    snack = Cube(randomSnack(st.rows, s), color=st.snack_color)

    #create window
    window = pygame.display.set_mode((st.width, st.width))

    #Display elements
    flag = True
    clock = pygame.time.Clock()
    delay_time = 50
    tick_time = 10

    while flag:
        pygame.time.delay(delay_time)
        clock.tick(tick_time)
        s.move()
        snack_check()
        # snake_check()
        for x in range(len(s.body)):
            if s.body[x].pos in list(map(lambda z: z.pos, s.body[x + 1:])):
                print('Score: ', len(s.body))
                # message_box('You Lost!', 'Play again...')
                s.reset((10, 10))
                break
        redrawWindow(window)
    pass
Example #11
0
def run_game():
    #initializing game
    pygame.init()
    #creating an object so as to access variables values in class settings
    sn_settings = Settings()
    #drawing screen
    screen = pygame.display.set_mode(
        (sn_settings.screen_width, sn_settings.screen_height))
    #creating an object snake so as to access variables values in class Snake
    snake = Snake(screen, sn_settings)
    #a list to store values of snake body to track it's movement
    snake_list = []
    ##creating an object food so as to access variables values in class Food
    food = Food(screen, sn_settings)
    #adding screen caption
    pygame.display.set_caption("kings snake game")

    #to keep track of time while playing the game
    clock = pygame.time.Clock()
    # Make the Play button.
    play_button = Button(sn_settings, screen, "Play")
    #game statistics
    game_stats = GameStats(sn_settings)
    #game scores
    sb = Scoreboard(sn_settings, screen, game_stats)

    while True:
        #start main loop for the game
        if game_stats.game_active == True:
            #calling update in Snake class to automate snake movement
            snake.update(sn_settings)
        #watch for keyboard / mouse input
        Gf.check_event(screen, sn_settings, snake, game_stats, snake_list,
                       play_button, sb)
        #displaying screen objects

        Gf.update(screen, sn_settings, snake_list, snake, food, play_button,
                  game_stats, sb)
        #rate at which the screen is update
        clock.tick(sn_settings.snake_speed)
Example #12
0
    def test_snake_collision_while_growing_and_moving(self):
        """
        A Snake instance will be created at given coordinates.
        It will then be moved in a pattern. After each movement,
        a inside_bounds test will be conducted.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results_inside_bounds = [
            True, True, True, True, True, True, False, False, True
        ]

        expected_results_collision_with_self = [
            False, False, False, False, False, False, False, False, True
        ]

        test_vector = [
            Snake.move_up, Snake.move_right, Snake.move_down, Snake.move_down,
            Snake.move_left, Snake.move_left, Snake.move_down,
            Snake.move_right, Snake.move_up
        ]

        for expected_bounds, expected_collision, test_move in zip(
                expected_results_inside_bounds,
                expected_results_collision_with_self, test_vector):
            with self.subTest("Snake.{}".format(test_move.__name__)):
                snake.grow()
                test_move(snake)

                self.assertEqual(snake.inside_bounds((0, 0), (90, 90)),
                                 expected_bounds)
                self.assertEqual(snake.check_collision_with_self(),
                                 expected_collision)
Example #13
0
    def __init__(self, background_colour, width, height):
        """Initialize the game. The parameters are passed on to the init function of Window


        Parameters:
        ------------------------------------------
        colour : list(int, int, int)
            A triple of values between 0 and 255 indicating the r, g, b value of the rectangle

        top_left : tuple(int, int)
            The x- and y-coordinates for the top left corner of the rectangle

        size : tuple(int, int)
            The width and height of the rectangle
        """
        self.window = Window(background_colour, width, height)
        self.snake_size = (30, 30)
        self.snake = Snake((width//2, height//2), self.snake_size, (75, 75, 75))
        self.current_movement = Snake.move_up
        self.fruit_coordinates = (0, 0)
        self.fruit_size = (30, 30)
        self.running = True
        self.last_update_time = pygame.time.get_ticks()
Example #14
0
    def test_snake_inside_bounds_while_moving(self):
        """
        A snake instance will be created at given coordinates.
        It will then be moved in a pattern, growing after each movement.
        After each movement is done, a collision_with_self check will be conducted.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [
            False, False, False, False, False, False, False, False, True
        ]
        test_vector = [
            Snake.move_up, Snake.move_right, Snake.move_down, Snake.move_down,
            Snake.move_left, Snake.move_left, Snake.move_down,
            Snake.move_right, Snake.move_up
        ]

        for expected, test_move in zip(expected_results, test_vector):
            with self.subTest("Snake.{}".format(test_move.__name__)):

                snake.grow()
                test_move(snake)

                self.assertEqual(snake.check_collision_with_self(), expected)
Example #15
0
    def test_snake_internal_get_size(self):
        """
        A Snake instance will be created at given coordinates.
        The instance will then be iterated over, and get_size called,
        on the internal structure to make sure that the size match the
        provided one.
        """
        snake = Snake((30, 30), (30, 30), (0, 0, 0))

        expected_results = [(30, 30)]
        results = []

        for part in snake:
            results.append(part.get_size())

        self.assertListEqual(results, expected_results)
Example #16
0
class SnakeGame:
    """
    A simple structure for a Snake-like game.

    Attributes:
    -----------------
        window : Window
            The main window of the game.
            Makes sure that the implementation is visible to the user.

        snake_size : tuple(int, int)
            The size of the snake.

        snake : Snake
            The controllable snake.

        current_movement : Callable
            One of the four directional functions from the Snake class.
            Saved for convenience and used to call movement on the snake-attribute.

        fruit_coordinates : list(int, int)
            The positional coordinates of the fruit that the snake is to eat.

        fruit_size : tuple(int, int)
            The size of the fruit.

        running : bool
            Used to control the state of the game.
            If false, the player has either exited or lost the game.

        last_update_time : int
            If the difference between this and a clock check is above 150
            the method update_movement is called and this attribute
            updated.

    Methods:
    -----------------
        handle_keydown(event):
            Function to handle user input events incoming from the underlying pygame module.

        draw():
            Draw the game to the screen.

        move_fruit():
            Randomly moves the fruit until it does not collide with the snake anymore.
            Used after the fruit is picked up.

        fruit_pickup():
            Used to control if the snake is able to pick up the fruit.
            If the snake is able to pick the fruit up, the snake will grow
            and the fruit will be moved to a new position.

        check_if_inside_window():
            Used to control whether the snake is inside the boundaries of
            the screen or not. If the snake is not inside the boundaries,
            the game is over.

        run_game_logic():
            The main function used to run the game logic.
            Makes sure that all other functions are called as they should.

        game_loop():
            The entry point of the game.
            Clears the screen, runs the game logic, and make sure that the
            screen is presented at the end.

        update_move():
        Function to update the movement and control if the
        snake collides with itself.
    """
    #pylint: disable=no-member

    def __init__(self, background_colour, width, height):
        """Initialize the game. The parameters are passed on to the init function of Window


        Parameters:
        ------------------------------------------
        colour : list(int, int, int)
            A triple of values between 0 and 255 indicating the r, g, b value of the rectangle

        top_left : tuple(int, int)
            The x- and y-coordinates for the top left corner of the rectangle

        size : tuple(int, int)
            The width and height of the rectangle
        """
        self.window = Window(background_colour, width, height)
        self.snake_size = (30, 30)
        self.snake = Snake((width//2, height//2), self.snake_size, (75, 75, 75))
        self.current_movement = Snake.move_up
        self.fruit_coordinates = (0, 0)
        self.fruit_size = (30, 30)
        self.running = True
        self.last_update_time = pygame.time.get_ticks()

    def handle_keydown(self, event):
        """Handle key input from the user.

        Check if the key pressed is any of the keys used to control the snake,
        that is any of the WASD-keys or the arrow keys, or ESC for quiting the game.

        If any of the WASD-keys or arrow keys are pressed, change direction of the snake
        to the appropiate direction.

        Parameters:
            event : pygame.event
                An event containing a pressed key.
        """

        pressed_key = event.key

        if pressed_key in (pygame.K_a, pygame.K_LEFT):
            self.current_movement = Snake.move_left
        elif pressed_key in (pygame.K_d, pygame.K_RIGHT):
            self.current_movement = Snake.move_right
        elif pressed_key in (pygame.K_w, pygame.K_UP):
            self.current_movement = Snake.move_up
        elif pressed_key in (pygame.K_s, pygame.K_DOWN):
            self.current_movement = Snake.move_down
        elif pressed_key == pygame.K_ESCAPE:
            self.running = False

    def draw(self):
        """Makes sure all the components of the game are presented on the screen."""
        self.window.draw_rect(
            (255, 0, 0),
            self.fruit_coordinates,
            self.fruit_size
        )

        for part in self.snake:
            coordinates = part.get_coordinates()
            size = part.get_size()
            colour = part.get_colour()
            self.window.draw_rect(
                colour,
                coordinates,
                size
            )

    def move_fruit(self):
        """
        Randomly moves the fruit until it does not collide with the snake anymore.
        Used after the fruit is picked up.
        """
        while True:
            screen_size = (self.window.width(), self.window.height())
            new_x = randrange(0, screen_size[0] - self.fruit_size[0], self.fruit_size[0])
            new_y = randrange(0, screen_size[1] - self.fruit_size[1], self.fruit_size[1])
            self.fruit_coordinates = (new_x, new_y)

            position_ok = True

            if self.snake.check_collision(self.fruit_coordinates, self.fruit_size):
                position_ok = False

            if position_ok:
                break

    def fruit_pickup(self):
        """
        Used to control if the snake is able to pick up the fruit.
        If the snake is able to pick the fruit up, the snake will grow
        and the fruit will be moved to a new position.
        """
        if self.snake.check_collision_with_fruit(self.fruit_coordinates, self.fruit_size):
            self.move_fruit()
            self.snake.grow()

    def is_inside_window(self):
        """
        Used to control whether the snake is inside the boundaries of
        the screen or not. If the snake is not inside the boundaries,
        the game is over.

        Return: bool
            True: Inside window
            False: Not inside window
        """
        screen_size = (self.window.width(), self.window.height())
        
        if self.snake.inside_bounds(
                (0, 0),
                (screen_size[0] - self.snake_size[0],
                 screen_size[1] - self.snake_size[1])):

            return True
        return False

    def update_move(self):
        """
        Function to update the movement and control if the
        snake collides with itself.

        Called through a pygame registered event.
        """
        self.current_movement(self.snake)
        if self.snake.check_collision_with_self() or not self.is_inside_window():
            self.running = False

    def run_game_logic(self):
        """
        The entry point of the game.
        Clears the screen, runs the game logic, and make sure that the
        screen is presented at the end.
        """
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN:
                self.handle_keydown(event)

        time_since_update = pygame.time.get_ticks() - self.last_update_time

        if time_since_update > 150:
            self.last_update_time = pygame.time.get_ticks()
            self.update_move()

        self.fruit_pickup()

        self.draw()

    def game_loop(self):
        """
        The main loop of the game.

        Will continue to play until running is set to false.
        """
        self.running = True
        while self.running:
            self.window.clear()
            self.run_game_logic()
            pygame.display.flip()