diff --git a/main.pyw b/main.pyw index 1852ea7..a618677 100644 --- a/main.pyw +++ b/main.pyw @@ -7,6 +7,7 @@ from source.gui.window import GameWindow from source import path_font from source.gui.better_pyglet import Label + pyglet.font.add_directory(path_font) Label.default_kwargs["font_name"] = "Century Gothic" # NOQA: Label à un "default_kwargs" avec la metaclass diff --git a/source/gui/scene/Game.py b/source/gui/scene/Game.py index 6efbd8a..2e72193 100644 --- a/source/gui/scene/Game.py +++ b/source/gui/scene/Game.py @@ -11,7 +11,7 @@ from source.gui.scene import GameResult from source.gui.scene.abc import Scene from source.gui import widget, texture, scene from source.network.packet import PacketChat, PacketBombPlaced, PacketBoatPlaced, PacketBombState, PacketQuit, \ - PacketAskSave, PacketResponseSave + PacketAskSave, PacketResponseSave, PacketBoatsData from source.type import Point2D from source.utils import StoppableThread @@ -346,6 +346,11 @@ class Game(Scene): self.save_to_path(self.save_path) def game_end(self, won: bool): + # envoie notre planche à l'adversaire + PacketBoatsData(boats=self.grid_ally.board.boats).send_data_connection(self.connection) + packet_boats = PacketBoatsData.from_connection(self.connection) + self.grid_enemy.board.boats = packet_boats.boats + # s'il existe une ancienne sauvegarde, efface la self.save_path.unlink(missing_ok=True) @@ -353,7 +358,7 @@ class Game(Scene): self.save_to_path(self.history_path) self.window.add_scene(GameResult, game_scene=self, won=won) # affiche le résultat - self.thread.stop() # coupe la connexion + self.thread.stop() def chat_new_message(self, author: str, content: str, system: bool = False): deco_left, deco_right = "<>" if system else "[]" diff --git a/source/gui/scene/HistoryMenu.py b/source/gui/scene/HistoryMenu.py new file mode 100644 index 0000000..8d4bac3 --- /dev/null +++ b/source/gui/scene/HistoryMenu.py @@ -0,0 +1,31 @@ +from typing import TYPE_CHECKING + +from source import path_history +from source.gui import widget, texture +from source.gui.scene.abc import Scene + + +if TYPE_CHECKING: + from source.gui.window import Window + + +class HistoryMenu(Scene): + PAGE_SIZE: int = 10 + + def __init__(self, window: "Window", page: int = 0, **kwargs): + super().__init__(window, **kwargs) + + for i, path in enumerate( + list(path_history.iterdir()) + [page*self.PAGE_SIZE:(page+1)*self.PAGE_SIZE] + ): + + button = self.add_widget( + widget.Button, + + x=0.2, y=1.0 - ((i+1) * 0.1), width=0.6, height=0.1, + + label_text=path.stem, + + style=texture.Button.Style1 + ) diff --git a/source/gui/scene/MainMenu.py b/source/gui/scene/MainMenu.py index 34b69a5..d31cfe4 100644 --- a/source/gui/scene/MainMenu.py +++ b/source/gui/scene/MainMenu.py @@ -30,7 +30,7 @@ class MainMenu(Scene): self.game_create = self.add_widget( widget.Button, - x=50, y=0.45, width=0.3, height=0.1, + x=50, y=0.50, width=0.3, height=0.1, label_text="Créer une salle", label_font_size=20, @@ -43,7 +43,7 @@ class MainMenu(Scene): self.game_join = self.add_widget( widget.Button, - x=50, y=0.3, width=0.3, height=0.1, + x=50, y=0.35, width=0.3, height=0.1, label_text="Rejoindre une salle", label_font_size=20, @@ -53,10 +53,23 @@ class MainMenu(Scene): self.game_join.add_listener("on_click_release", lambda *_: self.window.set_scene(scene.RoomJoin)) + self.history = self.add_widget( + widget.Button, + + x=50, y=0.20, width=0.3, height=0.1, + + label_text="Historique", + label_font_size=20, + + style=texture.Button.Style1 + ) + + self.history.add_listener("on_click_release", lambda *_: self.window.set_scene(scene.HistoryMenu)) + self.settings = self.add_widget( widget.Button, - x=50, y=0.15, width=0.3, height=0.1, + x=50, y=0.05, width=0.3, height=0.1, label_text="Paramètres", label_font_size=20, diff --git a/source/gui/scene/__init__.py b/source/gui/scene/__init__.py index b679a3b..7ee22ea 100644 --- a/source/gui/scene/__init__.py +++ b/source/gui/scene/__init__.py @@ -9,5 +9,6 @@ from .Settings import Settings from .RoomHost import RoomHost from .RoomJoin import RoomJoin from .RoomCreate import RoomCreate +from .HistoryMenu import HistoryMenu from .MainMenu import MainMenu diff --git a/source/network/packet/PacketBoatsData.py b/source/network/packet/PacketBoatsData.py new file mode 100644 index 0000000..a515282 --- /dev/null +++ b/source/network/packet/PacketBoatsData.py @@ -0,0 +1,45 @@ +import socket +import struct +from dataclasses import dataclass, field + +import numpy as np + +from source.network.packet.abc import Packet + + +@dataclass +class PacketBoatsData(Packet): + + boats: np.ndarray = field() + + packet_format: str = ">II" + + def to_bytes(self) -> bytes: + width, height = self.boats.shape + size: int = width * height + + return struct.pack( + f"{self.packet_format}{size*2}s", # deux "s" parce qu'un bateau est représenté en ushort + width, + height, + self.boats.tobytes() + ) + + @classmethod + def from_connection(cls, connection: socket.socket) -> "PacketBoatsData": + width, height = struct.unpack( + cls.packet_format, + connection.recv(struct.calcsize(cls.packet_format)) + ) + + size: int = width * height + format_ = f"{size*2}s" # deux "s" parce qu'un bateau est représenté en ushort + + data, *_ = struct.unpack( + format_, + connection.recv(struct.calcsize(format_)) + ) + + return cls( + boats=np.frombuffer(data, dtype=np.ushort).reshape((width, height)) + ) diff --git a/source/network/packet/PacketChat.py b/source/network/packet/PacketChat.py index 130e581..0959650 100644 --- a/source/network/packet/PacketChat.py +++ b/source/network/packet/PacketChat.py @@ -1,10 +1,10 @@ from dataclasses import dataclass, field -from source.network.packet.abc import VariableLengthBytesPacket +from source.network.packet.abc import VariableLengthPacket @dataclass -class PacketChat(VariableLengthBytesPacket): +class PacketChat(VariableLengthPacket): """ A packet that represent a message from the chat """ diff --git a/source/network/packet/PacketUsername.py b/source/network/packet/PacketUsername.py index c7b71df..2792d90 100644 --- a/source/network/packet/PacketUsername.py +++ b/source/network/packet/PacketUsername.py @@ -1,10 +1,10 @@ from dataclasses import dataclass, field -from source.network.packet.abc import VariableLengthBytesPacket +from source.network.packet.abc import VariableLengthPacket @dataclass -class PacketUsername(VariableLengthBytesPacket): +class PacketUsername(VariableLengthPacket): username: str = field() @property diff --git a/source/network/packet/__init__.py b/source/network/packet/__init__.py index c9d7802..35d2b17 100644 --- a/source/network/packet/__init__.py +++ b/source/network/packet/__init__.py @@ -9,3 +9,4 @@ from .PacketUsername import PacketUsername from .PacketQuit import PacketQuit from .PacketLoadOldSave import PacketLoadOldSave from .PacketHaveSaveBeenFound import PacketHaveSaveBeenFound +from .PacketBoatsData import PacketBoatsData diff --git a/source/network/packet/abc/VariableLengthBytesPacket.py b/source/network/packet/abc/VariableLengthPacket.py similarity index 96% rename from source/network/packet/abc/VariableLengthBytesPacket.py rename to source/network/packet/abc/VariableLengthPacket.py index 741d950..6147e0b 100644 --- a/source/network/packet/abc/VariableLengthBytesPacket.py +++ b/source/network/packet/abc/VariableLengthPacket.py @@ -5,7 +5,7 @@ from abc import ABC, abstractmethod from source.network.packet.abc import Packet -class VariableLengthBytesPacket(Packet, ABC): +class VariableLengthPacket(Packet, ABC): """ A Packet that represent a single value that can be encoded with a variable length. The property "data" and the method "from_bytes" need to be defined. diff --git a/source/network/packet/abc/__init__.py b/source/network/packet/abc/__init__.py index 2676067..cbe0ddc 100644 --- a/source/network/packet/abc/__init__.py +++ b/source/network/packet/abc/__init__.py @@ -2,4 +2,4 @@ from .Packet import Packet from .SignalPacket import SignalPacket from .SimplePacket import SimplePacket -from .VariableLengthBytesPacket import VariableLengthBytesPacket +from .VariableLengthPacket import VariableLengthPacket