Commit ebbeaee3 authored by Anthony Jacob's avatar Anthony Jacob
Browse files

add multiple class and refactor

now able to have a real snake
parent 514830cf
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
from pythonsnake import controller
from pythonsnake.controller import Controller


if __name__ == "__main__":
    controller = Controller()
    controller.game_menu()

pythonsnake/candy.py

0 → 100644
+55 −0
Original line number Diff line number Diff line
from random import choice
from pythonsnake.snake import Snake


class Candy:
    def __init__(self, grid_width: int, grid_height: int, snake: Snake) -> None:
        self.X = 0
        self.Y = 0
        self.random_coord(grid_width, grid_height, snake)

    def random_coord(
        self, grid_width: int, grid_height: int, snake: Snake
    ) -> None:
        found = False
        x = 0
        y = 0
        while not found:
            correct = True
            x = self.random_coord_X(grid_width, snake)
            y = self.random_coord_Y(grid_height, snake)
            # candy can be on the same line or on the same column but not at
            # the exact same place as the snake
            for snake_part in snake.coord:
                if snake_part["x"] == x and snake_part["y"] == y:
                    correct = False
                    break

            if correct:
                found = True

        self.X = x
        self.Y = y

    def random_coord_X(self, grid_width: int, snake: Snake) -> int:
        coord_to_exclude = []
        for snake_part in snake.coord:
            coord_to_exclude.append(snake_part["x"])

        return choice(
            [i for i in range(0, grid_width) if i not in coord_to_exclude]
        )

    def random_coord_Y(self, grid_height: int, snake: Snake) -> int:
        coord_to_exclude = []
        for snake_part in snake.coord:
            coord_to_exclude.append(snake_part["y"])

        return choice(
            [i for i in range(0, grid_height) if i not in coord_to_exclude]
        )

    def new_coord(
        self, grid_width: int, grid_height: int, snake: Snake
    ) -> None:
        self.random_coord(grid_width, grid_height, snake)
+45 −50
Original line number Diff line number Diff line
from pythonsnake import model, view
from pythonsnake.model import Game
from pythonsnake.terminalview import TerminalView
import keyboard
import time


def game_menu():
class Controller:
    def __init__(self) -> None:
        self.view = TerminalView()
        self.game = None

    def game_menu(self) -> None:
        while True:
        start_game(choose_mode())
            self.start_game(self.choose_mode())


def choose_mode():
    view.menu()
    def choose_mode(self) -> int:
        self.view.menu()

        choice = None
    while choice != "1" and choice != "2" and choice != "3":
        while choice != "1" and choice != "2":

            choice = input("=>")
        if choice != "1" and choice != "2" and choice != "3":
            view.menu_choice_incorrect()
            if choice != "1" and choice != "2":
                self.view.menu_choice_incorrect()

    if choice == "3":
        if choice == "2":
            exit()

        return int(choice)


def start_game(mode):
    gameState = model.Game(29)
    def start_game(self, mode: int) -> None:
        self.game = Game(50, 25)

        if mode == 1:
        start_game_terminal(gameState)
    elif mode == 2:
        start_game_UI(gameState)
            self.start_game_terminal()


def start_game_terminal(gameState):
    def start_game_terminal(self) -> None:

        keyboard.unhook_all()
    listen_escape_game(gameState)
        self.listen_escape_game()

    while not gameState.lost:
        # gameState.step() 
        view.refresh_grid(gameState.move(gameState.current_direction + " arrow"))
        listen_move(gameState)
        while not self.game.lost:
            self.view.display_grid(
                self.game.move(self.game.current_direction + " arrow")
            )
            self.listen_move()
            continue

        time.sleep(1)
        keyboard.unhook_all()

    def listen_escape_game(self) -> None:
        keyboard.on_press_key("esc", lambda _: self.game.exit_game())

def start_game_UI(game):
    pass


def listen_escape_game(gameState):
    keyboard.on_press_key("esc", lambda _: gameState.exit_game())


def listen_move(gameState):
    def listen_move(self) -> None:

        if keyboard.is_pressed("left arrow"):
        view.refresh_grid(gameState.move("left arrow"))
            self.view.display_grid(self.game.move("left arrow"))
        if keyboard.is_pressed("right arrow"):
        view.refresh_grid(gameState.move("right arrow"))
            self.view.display_grid(self.game.move("right arrow"))
        if keyboard.is_pressed("up arrow"):
        view.refresh_grid(gameState.move("up arrow"))
            self.view.display_grid(self.game.move("up arrow"))
        if keyboard.is_pressed("down arrow"):
        view.refresh_grid(gameState.move("down arrow"))
            self.view.display_grid(self.game.move("down arrow"))
+108 −55
Original line number Diff line number Diff line
from copy import copy
import random
from pythonsnake.snake import Snake
from pythonsnake.candy import Candy


class Game:
    def __init__(self, grid_size) -> None:
        self.grid_size = grid_size
        self.grid = [[i for i in range(grid_size)] for j in range(grid_size)]
        self.player_coord = [0, 0]
        self.player_length = 1
    def __init__(self, grid_width: int, grid_height: int) -> None:
        self.grid_width = grid_width
        self.grid_height = grid_height
        self.snake = Snake()
        self.lost = False
        self.current_direction = "right"
        self.candy = self.new_candy()
        self.candy = Candy(grid_width, grid_height, self.snake)
        self.grid = self.init_grid(grid_width, grid_height)
        self.update_grid()

    def move(self, direction):
    def move(self, direction: str):
        # if the User is not trying to U turn, process the move
        if not self.is_U_turn(direction):

        # the snake can't make a U turn 
        if(direction == "left arrow" and self.current_direction == "right"
           or direction == "right arrow" and self.current_direction == "left"
           or direction == "up arrow" and self.current_direction == "down"
           or direction == "down arrow" and self.current_direction == "up"):
            return self
            # if the move is allowed (not off grid or snake not biting itself)
            if self.is_move_allowed(direction):
                self.current_direction = direction.replace(" arrow", "")
                self.snake.move(direction)
                if self.check_candy():
                    self.snake.eat_candy()
                    self.candy.new_coord(
                        self.grid_width, self.grid_height, self.snake
                    )

        if direction == "left arrow" and self.check_move(
            self.player_coord[0] - 1, self.player_coord[1]
        ):
            self.player_coord[0] -= 1
            self.current_direction = "left"
        elif direction == "right arrow" and self.check_move(
            self.player_coord[0] + 1, self.player_coord[1]
        ):
            self.player_coord[0] += 1
            self.current_direction = "right"
        elif direction == "up arrow" and self.check_move(
            self.player_coord[0], self.player_coord[1] - 1
        ):
            self.player_coord[1] -= 1
            self.current_direction = "up"
        elif direction == "down arrow" and self.check_move(
            self.player_coord[0], self.player_coord[1] + 1
        ):
            self.player_coord[1] += 1
            self.current_direction = "down"
                self.update_grid()
            else:
                self.lost = True

        self.check_candy()

        return self

    def exit_game(self):
        self.lost = True

    """
    check if the move is still in the grid
    check if the move is allowed in the grid
    """

    def check_move(self, coordX, coordY):
    def is_move_allowed(self, direction: str):

        snake_head = copy(self.snake.coord[0])
        if direction == "left arrow":
            snake_head["x"] -= 1
        elif direction == "right arrow":
            snake_head["x"] += 1
        elif direction == "up arrow":
            snake_head["y"] -= 1
        elif direction == "down arrow":
            snake_head["y"] += 1

        # check if next position of snake head is off grid
        if (
            coordX >= 0
            and coordX <= len(self.grid) - 1
            and coordY >= 0
            and coordY <= len(self.grid[0]) - 1
            snake_head["x"] < 0
            or snake_head["x"] >= self.grid_width
            or snake_head["y"] < 0
            or snake_head["y"] >= self.grid_height
        ):
            return False

        # check if next position of snake haed is not another snake piece
        for snake_piece in self.snake.coord:
            if (
                snake_piece["x"] == snake_head["x"]
                and snake_piece["y"] == snake_head["y"]
            ):
            return True
        else:
                return False

        return True

    def new_candy(self):
        return [random.randint(0, self.grid_size), random.randint(0, self.grid_size)]
        return [
            random.randint(0, self.grid_size),
            random.randint(0, self.grid_size),
        ]

    def check_candy(self) -> bool:
        if (
            self.snake.coord[0]["x"] == self.candy.X
            and self.snake.coord[0]["y"] == self.candy.Y
        ):
            return True

        return False

    def check_candy(self):
    def is_U_turn(self, direction: str) -> bool:
        # the User/snake can't make a U turn
        if (
            self.player_coord[0] == self.candy[0]
            and self.player_coord[1] == self.candy[1]
            direction == "left arrow"
            and self.current_direction == "right"
            or direction == "right arrow"
            and self.current_direction == "left"
            or direction == "up arrow"
            and self.current_direction == "down"
            or direction == "down arrow"
            and self.current_direction == "up"
        ):
            self.eat_candy()
            return True

    def eat_candy(self):
        self.player_length += 1
        self.candy = self.new_candy()
        return False

        """
        _summary_

        init the playing grid with format
                            column = width
        height = Y1 = line = [ [X1],[X2],[X3],[X4] ]
                        Y2     [X1],[X2],[X3],[X4]
                        Y3     [X1],[X2],[X3],[X4]
                        Y4     [X1],[X2],[X3],[X4]
        """

    def init_grid(self, grid_width: int, grid_height: int) -> None:
        return [
            [{"snake": False, "candy": False} for i in range(0, grid_width)]
            for j in range(0, grid_height)
        ]

    def update_grid(self) -> None:
        # reset grid
        for line in self.grid:
            for column in line:
                column["snake"] = False
                column["candy"] = False

        for snake_piece in self.snake.coord:
            self.grid[snake_piece["y"]][snake_piece["x"]]["snake"] = True

        self.grid[self.candy.Y][self.candy.X]["candy"] = True

pythonsnake/snake.py

0 → 100644
+42 −0
Original line number Diff line number Diff line
from copy import deepcopy


class Snake:
    def __init__(self) -> None:
        self.coord = []
        self.coord.append({"x": 0, "y": 0})
        self.piece_pending = None

    def eat_candy(self) -> None:
        self.piece_pending = {
            "x": self.coord[-1]["x"],
            "y": self.coord[-1]["y"],
        }

    def move(self, direction) -> None:
        snake_to_shift = deepcopy(self.coord)

        # move the snake head
        if direction == "left arrow":
            self.coord[0]["x"] -= 1
        elif direction == "right arrow":
            self.coord[0]["x"] += 1
        elif direction == "up arrow":
            self.coord[0]["y"] -= 1
        elif direction == "down arrow":
            self.coord[0]["y"] += 1

        # move the body
        for i, piece in enumerate(snake_to_shift):
            # except the snake head
            if i != 0:
                self.coord[i] = {
                    "x": snake_to_shift[i - 1]["x"],
                    "y": snake_to_shift[i - 1]["y"],
                }

        if self.piece_pending != None:
            self.coord.append(
                {"x": self.piece_pending["x"], "y": self.piece_pending["y"]}
            )
            self.piece_pending = None
Loading