boats of the ally grid are now sent to the opposent when the game end

This commit is contained in:
Faraphel 2023-03-06 19:30:07 +01:00
parent 8c7b429d29
commit f3ee475c2e
11 changed files with 108 additions and 11 deletions

View file

@ -7,6 +7,7 @@ from source.gui.window import GameWindow
from source import path_font from source import path_font
from source.gui.better_pyglet import Label from source.gui.better_pyglet import Label
pyglet.font.add_directory(path_font) pyglet.font.add_directory(path_font)
Label.default_kwargs["font_name"] = "Century Gothic" # NOQA: Label à un "default_kwargs" avec la metaclass Label.default_kwargs["font_name"] = "Century Gothic" # NOQA: Label à un "default_kwargs" avec la metaclass

View file

@ -11,7 +11,7 @@ from source.gui.scene import GameResult
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.gui import widget, texture, scene from source.gui import widget, texture, scene
from source.network.packet import PacketChat, PacketBombPlaced, PacketBoatPlaced, PacketBombState, PacketQuit, \ from source.network.packet import PacketChat, PacketBombPlaced, PacketBoatPlaced, PacketBombState, PacketQuit, \
PacketAskSave, PacketResponseSave PacketAskSave, PacketResponseSave, PacketBoatsData
from source.type import Point2D from source.type import Point2D
from source.utils import StoppableThread from source.utils import StoppableThread
@ -346,6 +346,11 @@ class Game(Scene):
self.save_to_path(self.save_path) self.save_to_path(self.save_path)
def game_end(self, won: bool): 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 # s'il existe une ancienne sauvegarde, efface la
self.save_path.unlink(missing_ok=True) self.save_path.unlink(missing_ok=True)
@ -353,7 +358,7 @@ class Game(Scene):
self.save_to_path(self.history_path) self.save_to_path(self.history_path)
self.window.add_scene(GameResult, game_scene=self, won=won) # affiche le résultat 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): def chat_new_message(self, author: str, content: str, system: bool = False):
deco_left, deco_right = "<>" if system else "[]" deco_left, deco_right = "<>" if system else "[]"

View file

@ -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
)

View file

@ -30,7 +30,7 @@ class MainMenu(Scene):
self.game_create = self.add_widget( self.game_create = self.add_widget(
widget.Button, 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_text="Créer une salle",
label_font_size=20, label_font_size=20,
@ -43,7 +43,7 @@ class MainMenu(Scene):
self.game_join = self.add_widget( self.game_join = self.add_widget(
widget.Button, 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_text="Rejoindre une salle",
label_font_size=20, 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.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( self.settings = self.add_widget(
widget.Button, 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_text="Paramètres",
label_font_size=20, label_font_size=20,

View file

@ -9,5 +9,6 @@ from .Settings import Settings
from .RoomHost import RoomHost from .RoomHost import RoomHost
from .RoomJoin import RoomJoin from .RoomJoin import RoomJoin
from .RoomCreate import RoomCreate from .RoomCreate import RoomCreate
from .HistoryMenu import HistoryMenu
from .MainMenu import MainMenu from .MainMenu import MainMenu

View file

@ -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))
)

View file

@ -1,10 +1,10 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from source.network.packet.abc import VariableLengthBytesPacket from source.network.packet.abc import VariableLengthPacket
@dataclass @dataclass
class PacketChat(VariableLengthBytesPacket): class PacketChat(VariableLengthPacket):
""" """
A packet that represent a message from the chat A packet that represent a message from the chat
""" """

View file

@ -1,10 +1,10 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from source.network.packet.abc import VariableLengthBytesPacket from source.network.packet.abc import VariableLengthPacket
@dataclass @dataclass
class PacketUsername(VariableLengthBytesPacket): class PacketUsername(VariableLengthPacket):
username: str = field() username: str = field()
@property @property

View file

@ -9,3 +9,4 @@ from .PacketUsername import PacketUsername
from .PacketQuit import PacketQuit from .PacketQuit import PacketQuit
from .PacketLoadOldSave import PacketLoadOldSave from .PacketLoadOldSave import PacketLoadOldSave
from .PacketHaveSaveBeenFound import PacketHaveSaveBeenFound from .PacketHaveSaveBeenFound import PacketHaveSaveBeenFound
from .PacketBoatsData import PacketBoatsData

View file

@ -5,7 +5,7 @@ from abc import ABC, abstractmethod
from source.network.packet.abc import Packet 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. 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. The property "data" and the method "from_bytes" need to be defined.

View file

@ -2,4 +2,4 @@ from .Packet import Packet
from .SignalPacket import SignalPacket from .SignalPacket import SignalPacket
from .SimplePacket import SimplePacket from .SimplePacket import SimplePacket
from .VariableLengthBytesPacket import VariableLengthBytesPacket from .VariableLengthPacket import VariableLengthPacket