added Board, Boat, Orientation serialisation

This commit is contained in:
Faraphel 2023-01-10 17:11:18 +01:00
parent dcca925dbe
commit 1175c8b5d1
8 changed files with 108 additions and 16 deletions

View file

@ -11,9 +11,10 @@ window = Window(resizable=True, visible=False)
button_normal_image = pyglet.image.load("./assets/test_button_normal.png") button_normal_image = pyglet.image.load("./assets/test_button_normal.png")
button_hover_image = pyglet.image.load("./assets/test_button_hover.png") button_hover_image = pyglet.image.load("./assets/test_button_hover.png")
# performance and button test
hello_world_scene = HelloWorldScene() hello_world_scene = HelloWorldScene()
# performance and button test
for x in range(10): for x in range(10):
for y in range(10): for y in range(10):
button = Button( button = Button(
@ -22,7 +23,7 @@ for x in range(10):
font_size=10, font_size=10,
on_release=lambda self, *a, **b: setattr(self, "width", self.width + 10), on_release=lambda self, *a, **b: setattr(self, "width", self.width + 10),
normal_image=button_normal_image, normal_image=button_normal_image,
hover_image=button_hover_image, hover_image=button_hover_image
) )
hello_world_scene.add_widget(button) hello_world_scene.add_widget(button)

View file

@ -1,6 +1,6 @@
import numpy as np import numpy as np
from source.core import Boat from source.core.Boat import Boat
from source.core.enums import Orientation, BombState from source.core.enums import Orientation, BombState
from source.core.error import InvalidBoatPosition, PositionAlreadyShot from source.core.error import InvalidBoatPosition, PositionAlreadyShot
from source.utils import copy_array_offset from source.utils import copy_array_offset
@ -9,11 +9,22 @@ from source.utils import copy_array_offset
class Board: class Board:
__slots__ = ("_width", "_height", "_boats", "_bombs") __slots__ = ("_width", "_height", "_boats", "_bombs")
def __init__(self, width: int, height: int = None) -> None: def __init__(
self,
width: int,
height: int = None,
boats: dict[Boat, tuple[int, int]] = None,
bombs: np.array = None
) -> None:
self._width: int = width self._width: int = width
self._height: int = width if height is None else height self._height: int = width if height is None else height
self._boats: dict[Boat, tuple[int, int]] = {} # associate the boats to their position
self._bombs: np.array = np.ones((self._width, self._height), dtype=np.bool_) # associate the boats to their position
self._boats: dict[Boat, tuple[int, int]] = {} if boats is None else boats
# position that have been shot by a bomb
self._bombs: np.array = np.ones((self._width, self._height), dtype=np.bool_) if bombs is None else bombs
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<{self.__class__.__name__} width={self._width}, height={self._height}>" return f"<{self.__class__.__name__} width={self._width}, height={self._height}>"
@ -106,6 +117,23 @@ class Board:
return board return board
def to_json(self) -> dict:
return {
"width": self._width,
"height": self._height,
"boats": [[boat.to_json(), position] for boat, position in self._boats.items()],
"bombs": self._bombs.tolist()
}
@classmethod
def from_json(cls, json_: dict) -> "Board":
return Board(
width=json_["width"],
height=json_["height"],
boats={Boat.from_json(boat_json): tuple(position) for boat_json, position in json_["boats"]},
bombs=np.array(json_["bombs"], dtype=np.bool_)
)
if __name__ == "__main__": if __name__ == "__main__":
board = Board(5) board = Board(5)

View file

@ -10,6 +10,9 @@ class Boat:
self.orientation = orientation self.orientation = orientation
self.length = length self.length = length
def __repr__(self):
return f"<{self.__class__.__name__} orientation={self.orientation}, length={self.length}>"
def get_matrice(self, value: int = 1) -> np.array: def get_matrice(self, value: int = 1) -> np.array:
""" """
:return: the boat represented as a matrice :return: the boat represented as a matrice
@ -21,8 +24,18 @@ class Boat:
dtype=np.ushort dtype=np.ushort
) )
def __repr__(self): def to_json(self) -> dict:
return f"<{self.__class__.__name__} orientation={self.orientation}, length={self.length}>" return {
"length": self.length,
"orientation": self.orientation.to_json(),
}
@classmethod
def from_json(cls, json_: dict) -> "Boat":
return Boat(
length=json_["length"],
orientation=Orientation.from_json(json_["orientation"]),
)
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -4,3 +4,10 @@ from enum import Enum
class Orientation(Enum): class Orientation(Enum):
HORIZONTAL = "H" HORIZONTAL = "H"
VERTICAL = "V" VERTICAL = "V"
def to_json(self) -> str:
return str(self.value)
@classmethod
def from_json(cls, json_: str) -> "Orientation":
return cls(json_)

View file

@ -1,4 +1,4 @@
from source import Boat from source.core.Boat import Boat
class InvalidBoatPosition(Exception): class InvalidBoatPosition(Exception):

View file

@ -27,8 +27,9 @@ class Button(Widget):
normal_image: pyglet.image.AbstractImage = None, normal_image: pyglet.image.AbstractImage = None,
hover_image: pyglet.image.AbstractImage = None, hover_image: pyglet.image.AbstractImage = None,
batch: pyglet.graphics.Batch = None, text_batch: pyglet.graphics.Batch = None,
group: pyglet.graphics.Group = None, normal_batch: pyglet.graphics.Batch = None,
hover_batch: pyglet.graphics.Batch = None,
*args, **kwargs *args, **kwargs
): ):
@ -38,21 +39,21 @@ class Button(Widget):
# TODO: add an image when the mouse click ? # TODO: add an image when the mouse click ?
# TODO: make x, y, width, height, font_size optionally function to allow dynamic sizing # TODO: make x, y, width, height, font_size optionally function to allow dynamic sizing
# initialise the default value for the property # initialise the value for the property
self._x, self._y, self._width, self._height = x, y, width, height self._x, self._y, self._width, self._height = x, y, width, height
# the label used for the text # the label used for the text
self._label = pyglet.text.Label( self._label = pyglet.text.Label(
anchor_x="center", anchor_x="center", anchor_y="center",
anchor_y="center", batch=text_batch,
*args, **kwargs *args, **kwargs
) )
# hovering and background # hovering and background
self._hovering = False self._hovering = False
self._normal_sprite = Sprite(normal_image) self._normal_sprite = Sprite(normal_image, batch=normal_batch)
self._hover_sprite = Sprite(hover_image) self._hover_sprite = Sprite(hover_image, batch=hover_batch)
# the event when the button is clicked # the event when the button is clicked
self.on_press: Optional[Callable[["Self", "Window", "Scene", int, int, int, int], None]] = on_press self.on_press: Optional[Callable[["Self", "Window", "Scene", int, int, int, int], None]] = on_press

View file

@ -0,0 +1,24 @@
import json
import socket
from source.core.Board import Board
from source.core.Boat import Boat
from source.core.enums import Orientation
board = Board(5)
board.add_boat(Boat(3, Orientation.VERTICAL), (0, 4))
board.add_boat(Boat(4, Orientation.HORIZONTAL), (4, 1))
board.bomb((2, 2))
board_json = json.dumps(board.to_json())
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("127.0.0.1", 7878))
s.send(board_json.encode())
data = s.recv(1024)
print(data)

View file

@ -0,0 +1,18 @@
import json
import socket
from source.core.Board import Board
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("127.0.0.1", 7878))
s.listen()
conn, addr = s.accept()
message = conn.recv(1024)
conn.send(b"SALUT")
print(conn, addr, message)
board_json = json.loads(message)
print(Board.from_json(board_json))