From 930947adedc5b0976aa4fc8be3e82cd3ed3f41a1 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Mon, 20 Feb 2023 23:25:26 +0100 Subject: [PATCH] simplified and added the possibility to place boat with the given boat size list on the grid --- NOTE.md | 10 +- source/core/Board.py | 5 +- source/gui/scene/Game.py | 2 +- source/gui/texture/Grid.py | 1 + source/gui/widget/grid/GameGridAlly.py | 153 +++++++++++++------------ 5 files changed, 92 insertions(+), 79 deletions(-) diff --git a/NOTE.md b/NOTE.md index 02547a2..a16cc19 100644 --- a/NOTE.md +++ b/NOTE.md @@ -10,4 +10,12 @@ Bug : - / Autre : -- Tester sur Linux \ No newline at end of file +- Tester sur Linux + + + + + + +Bonus ultime : +- Envoyer la texture de la grille à l'adversaire \ No newline at end of file diff --git a/source/core/Board.py b/source/core/Board.py index 27b9171..2a36d7d 100644 --- a/source/core/Board.py +++ b/source/core/Board.py @@ -144,11 +144,10 @@ class Board: if __name__ == "__main__": board = Board(5) - board.add_boat(Boat(3, Orientation.VERTICAL), (0, 4)) - board.add_boat(Boat(4, Orientation.HORIZONTAL), (4, 1)) + board.add_boat(Boat(3, Orientation.VERTICAL), (4, 0)) + board.add_boat(Boat(4, Orientation.HORIZONTAL), (1, 4)) print(board.bomb((4, 1))) print(board.bomb((4, 2))) print(board.bomb((4, 3))) print(board.bomb((4, 4))) print(board) - diff --git a/source/gui/scene/Game.py b/source/gui/scene/Game.py index 8296d4f..411f192 100644 --- a/source/gui/scene/Game.py +++ b/source/gui/scene/Game.py @@ -35,7 +35,7 @@ class Game(Scene): x=75, y=0.25, width=0.35, height=0.5, - boats_length=(5, 5, 4, 3, 2), + boats_length=[5, 5, 4, 3, 2], style=texture.Grid.Style1, rows=8, columns=8, diff --git a/source/gui/texture/Grid.py b/source/gui/texture/Grid.py index 6c69068..9d75be7 100644 --- a/source/gui/texture/Grid.py +++ b/source/gui/texture/Grid.py @@ -14,3 +14,4 @@ class Grid: body = _image_boat_path + "body.png" edge = _image_boat_path + "edge.png" broken = _image_boat_path + "broken.png" + solo = _image_boat_path + "solo.png" diff --git a/source/gui/widget/grid/GameGridAlly.py b/source/gui/widget/grid/GameGridAlly.py index 04ad2b7..a66d5ea 100644 --- a/source/gui/widget/grid/GameGridAlly.py +++ b/source/gui/widget/grid/GameGridAlly.py @@ -4,112 +4,117 @@ import pyglet import numpy as np from source.core.enums import Orientation +from source.core.error import InvalidBoatPosition from source.gui import texture from source.gui.sprite import Sprite from source.gui.widget.grid.abc import GameGrid from source.core import Board, Boat +from source.type import Point2D +from source.utils import dict_filter_prefix if TYPE_CHECKING: from source.gui.scene.abc import Scene class GameGridAlly(GameGrid): - def __init__(self, scene: "Scene", boats_length: tuple[int, ...], **kwargs): + def __init__(self, scene: "Scene", boats_length: list[int], **kwargs): + self.cell_sprites: dict[Point2D, "Sprite"] = {} + super().__init__(scene, **kwargs) - self.orientation = False + self.orientation: Orientation = Orientation.HORIZONTAL self.boats_length = boats_length # the list of the size of the boats to place + self.board = Board(rows=self.rows, columns=self.columns) - self.add_listener("on_hover", - lambda rel_x, rel_y: self.preview_boat(self.get_cell_from_rel(rel_x, rel_y), self.boats_length[0])) + self._cell_kwargs = dict_filter_prefix("cell_", kwargs) - self.cell_sprites: list["Sprite"] = [] - self.boat_sprites_preview: list["Sprite"] = [] + # refresh + def _refresh_size(self): + super()._refresh_size() - def draw_board(self, board: Board): - matrice = board.get_matrice() + for (x, y), sprite in self.cell_sprites.items(): + + # calcul des décalages à cause de la rotation qui est faite par rapport à l'origine de l'image + + offset_x = 0 if sprite.rotation <= 90 else self.cell_width + offset_y = self.cell_height if 90 <= sprite.rotation <= 180 else 0 + + width, height = ( + (self.cell_width, self.cell_height) if sprite.rotation % 180 == 0 else + (self.cell_height, self.cell_width) + ) + + sprite.x = self.x + (x * self.cell_width) + offset_x + sprite.y = self.y + (y * self.cell_height) + offset_y + sprite.width = width + sprite.height = height + + def _refresh_board(self): + self.cell_sprites: dict[Point2D, "Sprite"] = {} + + matrice = self.board.get_matrice() for (y, x), value in np.ndenumerate(matrice): if value == 0: continue # calcul de la forme et de la rotation de cette cellule du bateau - rotation = 0 + form, rotation = ( + # corps + ("body", 0) if 0 < y < (self.rows-1) and matrice[y-1, x] == matrice[y+1, x] == value else # colonne + ("body", 1) if 0 < x < (self.columns-1) and matrice[y, x-1] == matrice[y, x+1] == value else # ligne - # body + # bordure + ("edge", 0) if 0 < y and matrice[y-1, x] == value else # bas + ("edge", 1) if 0 < x and matrice[y, x-1] == value else # droite + ("edge", 2) if y < (self.rows-1) and matrice[y+1, x] == value else # haut + ("edge", 3) if x < (self.columns-1) and matrice[y, x+1] == value else # gauche - if 0 < y < (self.rows-1) and matrice[y-1, x] == matrice[y+1, x] == value: # haut et bas - form = "body" + # aucune bordure (bateau de taille 1) + ("solo", 0) + ) - elif 0 < x < (self.columns-1) and matrice[y, x-1] == matrice[y, x+1] == value: # droite et gauche - form = "body" - rotation = 90 - - # edge - - elif 0 < y and matrice[y-1, x] == value: # haut - form = "edge" - - elif y < (self.rows-1) and matrice[y+1, x] == value: # bas - form = "edge" - rotation = 180 - - elif 0 < x and matrice[y, x-1] == value: # gauche - form = "edge" - rotation = 90 - - elif x < (self.columns-1) and matrice[y, x+1] == value: # droite - form = "edge" - rotation = 270 - - else: # 1 piece boat - form = "solo" - - # calcul des décalages à cause de la rotation qui est faite par rapport à l'origine de l'image - offset_x = 0 if rotation < 180 else self.cell_width - offset_y = self.cell_height if 90 <= rotation <= 180 else 0 - width = self.cell_width if rotation % 180 == 0 else self.cell_height - height = self.cell_height if rotation % 180 == 0 else self.cell_width - - s = Sprite( + sprite = Sprite( img=texture.Grid.Boat.Style1.get(form), - - x=self.x + (x * self.cell_width) + offset_x, - y=self.y + (y * self.cell_height) + offset_y, - width=int(width), - height=int(height), + **self._cell_kwargs ) - s.rotation = rotation - s.draw() + sprite.rotation = rotation * 90 - def preview_boat(self, cell: tuple[int, int], length: int): - cell_x, cell_y = cell + self.cell_sprites[(x, y)] = sprite - self.boat_sprites_preview = [] - - for i in range(length): - self.boat_sprites_preview.append( - Sprite( - img=texture.Grid.Boat.Style1.body, - - x=self.x + (cell_x * self.cell_width) + ((self.cell_width * i) if not self.orientation else 0), - y=self.y + (cell_y * self.cell_height) + ((self.cell_height * i) if self.orientation else 0), - width=int(self.cell_width), - height=int(self.cell_height), - ) - ) + self._refresh_size() def swap_orientation(self): - self.orientation = not self.orientation + self.orientation = ( + Orientation.HORIZONTAL if self.orientation is Orientation.VERTICAL else + Orientation.VERTICAL + ) + + def place_boat(self, x, y): + rel_x, rel_y = x - self.x, y - self.y + cell_x, cell_y = self.get_cell_from_rel(rel_x, rel_y) + + try: + self.board.add_boat( + Boat(self.boats_length[0], orientation=self.orientation), + (cell_x, cell_y) + ) + + except InvalidBoatPosition: + return + + else: + self.boats_length.pop(0) + + self._refresh_board() def on_mouse_release(self, x: int, y: int, button: int, modifiers: int): super().on_mouse_release(x, y, button, modifiers) - if button == pyglet.window.mouse.RIGHT: self.swap_orientation() - def on_draw(self): - b = Board(rows=self.rows, columns=self.columns) - b.add_boat(Boat(length=4, orientation=Orientation.VERTICAL), (0, 0)) - b.add_boat(Boat(length=5, orientation=Orientation.HORIZONTAL), (0, 1)) - b.add_boat(Boat(length=2, orientation=Orientation.HORIZONTAL), (0, 6)) - self.draw_board(b) - for boat_sprite in self.boat_sprites_preview: boat_sprite.draw() + if button == pyglet.window.mouse.RIGHT: self.swap_orientation() + if button == pyglet.window.mouse.LEFT: self.place_boat(x, y) + + def draw(self): + super().draw() + for sprite in self.cell_sprites.values(): + sprite.draw()