changed some grid code to be easier to manipulate
2
.gitignore
vendored
|
@ -137,3 +137,5 @@ dmypy.json
|
||||||
/.idea/inspectionProfiles/Project_Default.xml
|
/.idea/inspectionProfiles/Project_Default.xml
|
||||||
/.idea/Projet_S6.iml
|
/.idea/Projet_S6.iml
|
||||||
/.idea/vcs.xml
|
/.idea/vcs.xml
|
||||||
|
|
||||||
|
/.save/
|
||||||
|
|
|
@ -1,227 +0,0 @@
|
||||||
{
|
|
||||||
"grid_ally": {
|
|
||||||
"columns": 8,
|
|
||||||
"rows": 8,
|
|
||||||
"boats": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"length": 5,
|
|
||||||
"orientation": "H"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"length": 4,
|
|
||||||
"orientation": "V"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"length": 4,
|
|
||||||
"orientation": "H"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
3,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"length": 3,
|
|
||||||
"orientation": "V"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
5
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"length": 2,
|
|
||||||
"orientation": "H"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
2,
|
|
||||||
6
|
|
||||||
]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"bombs": [
|
|
||||||
[
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"grid_enemy": {
|
|
||||||
"columns": 8,
|
|
||||||
"rows": 8,
|
|
||||||
"boats": [],
|
|
||||||
"bombs": [
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
4
NOTE.md
|
@ -12,13 +12,13 @@ A faire :
|
||||||
- Changer les images, rajouter les fonds, ...
|
- Changer les images, rajouter les fonds, ...
|
||||||
|
|
||||||
3. Hypothétique :
|
3. Hypothétique :
|
||||||
- Vrai musique
|
- Vraie musique
|
||||||
- Voir si les event listener intégré à pyglet sont plus pratiques que l'event propagation (?)
|
- Voir si les event listener intégré à pyglet sont plus pratiques que l'event propagation (?)
|
||||||
- Faire une scène incluant par défaut les boutons "Retour" (?)
|
- Faire une scène incluant par défaut les boutons "Retour" (?)
|
||||||
|
|
||||||
|
|
||||||
Bug :
|
Bug :
|
||||||
- /
|
- Dans de rare cas (souvent en fermant brutalement la fenêtre) le processus ne s'arrête pas
|
||||||
|
|
||||||
|
|
||||||
Autre :
|
Autre :
|
||||||
|
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 156 B |
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 572 B |
Before Width: | Height: | Size: 609 B After Width: | Height: | Size: 609 B |
Before Width: | Height: | Size: 644 B After Width: | Height: | Size: 644 B |
Before Width: | Height: | Size: 695 B After Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 712 B |
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 708 B |
Before Width: | Height: | Size: 691 B After Width: | Height: | Size: 691 B |
Before Width: | Height: | Size: 533 B After Width: | Height: | Size: 533 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 213 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 467 B |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 498 B After Width: | Height: | Size: 498 B |
Before Width: | Height: | Size: 621 B After Width: | Height: | Size: 621 B |
|
@ -13,27 +13,24 @@ class Board:
|
||||||
Boat can be added and bomb can be placed.
|
Boat can be added and bomb can be placed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_columns", "_rows", "_boats", "_bombs")
|
__slots__ = ("width", "height", "boats", "bombs")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
rows: int,
|
width: int, height: int = None,
|
||||||
columns: int = None,
|
|
||||||
boats: dict[Boat, Point2D] = None,
|
|
||||||
bombs: np.array = None
|
|
||||||
) -> None:
|
|
||||||
|
|
||||||
self._rows: int = rows
|
boats: np.array = None,
|
||||||
self._columns: int = rows if columns is None else columns
|
bombs: np.array = None) -> None:
|
||||||
|
|
||||||
# associate the boats to their position
|
self.height: int = width
|
||||||
self._boats: dict[Boat, Point2D] = {} if boats is None else boats
|
self.width: int = width if height is None else height
|
||||||
|
|
||||||
# position that have been shot by a bomb
|
# associate the boats and the bombs to array
|
||||||
self._bombs: np.array = np.ones((self._rows, self._columns), dtype=np.bool_) if bombs is None else bombs
|
self.boats: np.array = np.zeros((self.height, self.width), dtype=np.ushort) if boats is None else boats
|
||||||
|
self.bombs: np.array = np.ones((self.height, self.width), dtype=np.bool_) if bombs is None else bombs
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<{self.__class__.__name__} width={self._columns}, height={self._rows}>"
|
return f"<{self.__class__.__name__} width={self.width}, height={self.height}>"
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return str(self.get_matrice())
|
return str(self.get_matrice())
|
||||||
|
@ -46,33 +43,31 @@ class Board:
|
||||||
:raise: InvalidBoatPosition if the boat position is not valid
|
:raise: InvalidBoatPosition if the boat position is not valid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# get the sum of the boat
|
|
||||||
boat_mat: np.array = boat.get_matrice()
|
|
||||||
boat_mat_sum: int = boat_mat.sum()
|
|
||||||
|
|
||||||
# get the old board matrice sum
|
# get the old board matrice sum
|
||||||
board_mat: np.array = self.get_matrice()
|
board_matrice = self.boats.copy()
|
||||||
board_mat_sum_old: int = board_mat.sum()
|
board_matrice_sum_old: int = board_matrice.sum()
|
||||||
|
board_matrice_max = np.max(board_matrice)
|
||||||
|
|
||||||
|
# get the sum of the boat
|
||||||
|
boat_matrice: np.array = boat.get_matrice(board_matrice_max+1)
|
||||||
|
boat_matrice_sum: int = boat_matrice.sum()
|
||||||
|
|
||||||
# add the boat to the board matrice
|
# add the boat to the board matrice
|
||||||
try: copy_array_offset(boat_mat, board_mat, offset=position)
|
try:
|
||||||
except ValueError: raise InvalidBoatPosition(boat, position)
|
copy_array_offset(boat_matrice, board_matrice, offset=position)
|
||||||
|
except ValueError:
|
||||||
|
raise InvalidBoatPosition(boat, position)
|
||||||
|
|
||||||
# get the new board matrice sum
|
# get the new board matrice sum
|
||||||
board_mat_sum_new: int = board_mat.sum()
|
board_matrice_sum_new: int = board_matrice.sum()
|
||||||
|
|
||||||
# if the sum of the old board plus the boat sum is different from the new board sum,
|
# if the sum of the old board plus the boat sum is different from the new board sum,
|
||||||
# then the boat have been incorrectly placed (overlapping, outside of bounds, ...)
|
# then the boat have been incorrectly placed (overlapping, outside of bounds, ...)
|
||||||
if board_mat_sum_old + boat_mat_sum != board_mat_sum_new: raise InvalidBoatPosition(boat, position)
|
if board_matrice_sum_old + boat_matrice_sum != board_matrice_sum_new:
|
||||||
|
raise InvalidBoatPosition(boat, position)
|
||||||
|
|
||||||
# otherwise accept the boat in the boats dict
|
# otherwise accept the boat in the boats dict
|
||||||
self._boats[boat] = position
|
self.boats = board_matrice
|
||||||
|
|
||||||
def remove_boat(self, boat: Boat) -> None:
|
|
||||||
"""
|
|
||||||
Remove a boat from the boat dict
|
|
||||||
"""
|
|
||||||
self._boats.pop(boat)
|
|
||||||
|
|
||||||
def bomb(self, position: Point2D) -> BombState:
|
def bomb(self, position: Point2D) -> BombState:
|
||||||
"""
|
"""
|
||||||
|
@ -83,16 +78,16 @@ class Board:
|
||||||
|
|
||||||
# if the bomb is inside the board
|
# if the bomb is inside the board
|
||||||
x, y = position
|
x, y = position
|
||||||
if x >= self._columns or y >= self._rows: raise InvalidBombPosition(position)
|
if x >= self.width or y >= self.height: raise InvalidBombPosition(position)
|
||||||
|
|
||||||
# if this position have already been shot
|
# if this position have already been shot
|
||||||
if not self._bombs[y, x]: raise PositionAlreadyShot(position)
|
if not self.bombs[y, x]: raise PositionAlreadyShot(position)
|
||||||
|
|
||||||
# get the old board matrice
|
# get the old board matrice
|
||||||
board_mat_old_sum = self.get_matrice().sum()
|
board_mat_old_sum = self.get_matrice().sum()
|
||||||
|
|
||||||
# place the bomb (setting the position to False cause the matrice multiplication to remove the boat if any)
|
# place the bomb (setting the position to False cause the matrice multiplication to remove the boat if any)
|
||||||
self._bombs[y, x] = False
|
self.bombs[y, x] = False
|
||||||
|
|
||||||
# get the new board matrice
|
# get the new board matrice
|
||||||
board_mat_new = self.get_matrice()
|
board_mat_new = self.get_matrice()
|
||||||
|
@ -116,42 +111,34 @@ class Board:
|
||||||
|
|
||||||
def get_matrice(self) -> np.array:
|
def get_matrice(self) -> np.array:
|
||||||
"""
|
"""
|
||||||
:return: the boat represented as a matrice
|
:return: the boats and bombs represented as a matrice
|
||||||
"""
|
"""
|
||||||
board = np.zeros((self._rows, self._columns), dtype=np.ushort)
|
|
||||||
|
|
||||||
for index, (boat, position) in enumerate(self._boats.items(), start=1):
|
return self.boats * self.bombs # Remove the position that have been bombed
|
||||||
# Paste the boat into the board at the correct position.
|
|
||||||
# The boat is represented by a number representing its order in the boats list
|
|
||||||
copy_array_offset(boat.get_matrice(value=index), board, offset=position)
|
|
||||||
|
|
||||||
board *= self._bombs # Remove the position that have been bombed
|
|
||||||
|
|
||||||
return board
|
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
return {
|
return {
|
||||||
"columns": self._columns,
|
"columns": self.width,
|
||||||
"rows": self._rows,
|
"rows": self.height,
|
||||||
"boats": [[boat.to_json(), position] for boat, position in self._boats.items()],
|
"boats": [[boat.to_json(), position] for boat, position in self.boats.items()],
|
||||||
"bombs": self._bombs.tolist()
|
"bombs": self.bombs.tolist()
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json_: dict) -> "Board":
|
def from_json(cls, json_: dict) -> "Board":
|
||||||
return Board(
|
return Board(
|
||||||
rows=json_["columns"],
|
width=json_["columns"],
|
||||||
columns=json_["rows"],
|
height=json_["rows"],
|
||||||
boats={Boat.from_json(boat_json): tuple(position) for boat_json, position in json_["boats"]},
|
boats={Boat.from_json(boat_json): tuple(position) for boat_json, position in json_["boats"]},
|
||||||
bombs=np.array(json_["bombs"], dtype=np.bool_)
|
bombs=np.array(json_["bombs"], dtype=np.bool_)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
return self.__class__(
|
return self.__class__(
|
||||||
rows=self._rows,
|
height=self.height,
|
||||||
columns=self._columns,
|
width=self.width,
|
||||||
boats=self._boats.copy(),
|
boats=self.boats.copy(),
|
||||||
bombs=self._bombs.copy(),
|
bombs=self.bombs.copy(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,13 @@ class Game(Scene):
|
||||||
boats_length: list,
|
boats_length: list,
|
||||||
name_ally: str,
|
name_ally: str,
|
||||||
name_enemy: str,
|
name_enemy: str,
|
||||||
grid_width: int,
|
|
||||||
grid_height: int,
|
|
||||||
my_turn: bool,
|
my_turn: bool,
|
||||||
|
|
||||||
|
grid_width: int = None,
|
||||||
|
grid_height: int = None,
|
||||||
|
board_ally_data: dict = None,
|
||||||
|
board_enemy_data: dict = None,
|
||||||
|
|
||||||
**kwargs):
|
**kwargs):
|
||||||
super().__init__(window, **kwargs)
|
super().__init__(window, **kwargs)
|
||||||
|
|
||||||
|
@ -57,8 +60,9 @@ class Game(Scene):
|
||||||
|
|
||||||
grid_style=texture.Grid.Style1,
|
grid_style=texture.Grid.Style1,
|
||||||
boat_style=texture.Grid.Boat.Style1,
|
boat_style=texture.Grid.Boat.Style1,
|
||||||
bomb_style=texture.Grid.Bomb.Style1,
|
rows=self.grid_height, columns=self.grid_width,
|
||||||
rows=self.grid_height, columns=self.grid_width
|
|
||||||
|
board_data=board_ally_data
|
||||||
)
|
)
|
||||||
|
|
||||||
def board_ally_ready(widget):
|
def board_ally_ready(widget):
|
||||||
|
@ -74,8 +78,9 @@ class Game(Scene):
|
||||||
|
|
||||||
grid_style=texture.Grid.Style1,
|
grid_style=texture.Grid.Style1,
|
||||||
boat_style=texture.Grid.Boat.Style1,
|
boat_style=texture.Grid.Boat.Style1,
|
||||||
bomb_style=texture.Grid.Bomb.Style1,
|
rows=self.grid_height, columns=self.grid_width,
|
||||||
rows=self.grid_height, columns=self.grid_width
|
|
||||||
|
board_data=board_enemy_data
|
||||||
)
|
)
|
||||||
|
|
||||||
def board_enemy_bomb(widget, cell: Point2D):
|
def board_enemy_bomb(widget, cell: Point2D):
|
||||||
|
@ -167,6 +172,11 @@ class Game(Scene):
|
||||||
)
|
)
|
||||||
|
|
||||||
def ask_save(widget, x, y, button, modifiers):
|
def ask_save(widget, x, y, button, modifiers):
|
||||||
|
if not (self._boat_ready_ally and self._boat_ready_enemy):
|
||||||
|
self.chat_new_message("System", "Veuillez poser vos bateaux avant de sauvegarder.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO: Pas spam le bouton
|
||||||
PacketAskSave().send_connection(self.connection)
|
PacketAskSave().send_connection(self.connection)
|
||||||
self.chat_new_message("System", "demande de sauvegarde envoyé.")
|
self.chat_new_message("System", "demande de sauvegarde envoyé.")
|
||||||
|
|
||||||
|
@ -201,6 +211,10 @@ class Game(Scene):
|
||||||
self._boat_broken_ally: int = 0
|
self._boat_broken_ally: int = 0
|
||||||
self._boat_broken_enemy: int = 0
|
self._boat_broken_enemy: int = 0
|
||||||
|
|
||||||
|
if len(boats_length) == 0: # s'il n'y a pas de bateau à placé
|
||||||
|
self._boat_ready_ally = True # défini l'état de notre planche comme prête
|
||||||
|
PacketBoatPlaced().send_connection(connection) # indique à l'adversaire que notre planche est prête
|
||||||
|
|
||||||
self._refresh_turn_text()
|
self._refresh_turn_text()
|
||||||
|
|
||||||
# refresh
|
# refresh
|
||||||
|
@ -273,10 +287,35 @@ class Game(Scene):
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
return {
|
return {
|
||||||
|
"my_turn": self.my_turn,
|
||||||
"grid_ally": self.grid_ally.board.to_json(),
|
"grid_ally": self.grid_ally.board.to_json(),
|
||||||
"grid_enemy": self.grid_enemy.board.to_json(),
|
"grid_enemy": self.grid_enemy.board.to_json(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls,
|
||||||
|
data: dict,
|
||||||
|
|
||||||
|
window: "Window",
|
||||||
|
thread: StoppableThread,
|
||||||
|
connection: socket.socket,
|
||||||
|
name_ally: str,
|
||||||
|
name_enemy: str) -> "Game":
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
window=window,
|
||||||
|
thread=thread,
|
||||||
|
connection=connection,
|
||||||
|
boats_length=[],
|
||||||
|
name_ally=name_ally,
|
||||||
|
name_enemy=name_enemy,
|
||||||
|
|
||||||
|
my_turn=data["my_turn"],
|
||||||
|
|
||||||
|
board_ally_data=data["grid_ally"],
|
||||||
|
board_enemy_data=data["grid_enemy"]
|
||||||
|
)
|
||||||
|
|
||||||
def save(self, value: bool):
|
def save(self, value: bool):
|
||||||
self.chat_new_message(
|
self.chat_new_message(
|
||||||
"System",
|
"System",
|
||||||
|
@ -284,9 +323,12 @@ class Game(Scene):
|
||||||
)
|
)
|
||||||
if not value: return
|
if not value: return
|
||||||
|
|
||||||
ip_address, _ = self.connection.getpeername()
|
ip_address, port = self.connection.getpeername()
|
||||||
|
# Le nom du fichier est l'IP de l'opposent, suivi d'un entier indiquant si c'est à notre tour ou non.
|
||||||
|
# Cet entier permet aux localhost de toujours pouvoir sauvegarder et charger sans problème.
|
||||||
|
filename: str = f"{ip_address}-{int(self.my_turn)}.bn-save"
|
||||||
|
|
||||||
with open(path_save / (ip_address + ".bn-save"), "w", encoding="utf-8") as file:
|
with open(path_save / filename, "w", encoding="utf-8") as file:
|
||||||
json.dump(self.to_json(), file, ensure_ascii=False, indent=4)
|
json.dump(self.to_json(), file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
def game_end(self, won: bool):
|
def game_end(self, won: bool):
|
||||||
|
|
|
@ -4,7 +4,6 @@ from .type import Texture, Animation
|
||||||
|
|
||||||
path = path / "grid"
|
path = path / "grid"
|
||||||
path_boat = path / "boat"
|
path_boat = path / "boat"
|
||||||
path_bomb = path / "bomb"
|
|
||||||
|
|
||||||
|
|
||||||
class Grid:
|
class Grid:
|
||||||
|
@ -13,16 +12,14 @@ class Grid:
|
||||||
|
|
||||||
class Boat:
|
class Boat:
|
||||||
class Style1(Style):
|
class Style1(Style):
|
||||||
|
_animation = sorted(
|
||||||
|
(path_boat / "animation").iterdir(),
|
||||||
|
key=lambda path: int(path.stem)
|
||||||
|
)
|
||||||
|
|
||||||
body = Texture(path_boat / "body.png")
|
body = Texture(path_boat / "body.png")
|
||||||
edge = Texture(path_boat / "edge.png")
|
edge = Texture(path_boat / "edge.png")
|
||||||
solo = Texture(path_boat / "solo.png")
|
solo = Texture(path_boat / "solo.png")
|
||||||
|
|
||||||
class Bomb:
|
missed = Animation([*_animation, path_boat / "missed.png"], 0.03, False)
|
||||||
class Style1(Style):
|
touched = Animation([*_animation, path_boat / "touched.png"], 0.03, False)
|
||||||
_animation = sorted(
|
|
||||||
(path_bomb / "animation").iterdir(),
|
|
||||||
key=lambda path: int(path.stem)
|
|
||||||
)
|
|
||||||
|
|
||||||
missed = Animation([*_animation, path_bomb / "missed.png"], 0.03, False)
|
|
||||||
touched = Animation([*_animation, path_bomb / "touched.png"], 0.03, False)
|
|
||||||
|
|
|
@ -24,12 +24,8 @@ class GameGrid(BoxWidget):
|
||||||
|
|
||||||
def __init__(self, scene: "Scene",
|
def __init__(self, scene: "Scene",
|
||||||
|
|
||||||
rows: int,
|
|
||||||
columns: int,
|
|
||||||
|
|
||||||
grid_style: Type[Style],
|
grid_style: Type[Style],
|
||||||
boat_style: Type[Style],
|
boat_style: Type[Style],
|
||||||
bomb_style: Type[Style],
|
|
||||||
|
|
||||||
x: Distance = 0,
|
x: Distance = 0,
|
||||||
y: Distance = 0,
|
y: Distance = 0,
|
||||||
|
@ -39,29 +35,36 @@ class GameGrid(BoxWidget):
|
||||||
preview_color: ColorRGB = (150, 255, 150),
|
preview_color: ColorRGB = (150, 255, 150),
|
||||||
boats_length: list[int] = None,
|
boats_length: list[int] = None,
|
||||||
|
|
||||||
|
rows: int = None,
|
||||||
|
columns: int = None,
|
||||||
|
board_data: dict = None,
|
||||||
|
|
||||||
**kwargs):
|
**kwargs):
|
||||||
self.cell_sprites: dict[Point2D, "Sprite"] = {}
|
if (rows is None or columns is None) and board_data is None:
|
||||||
|
raise ValueError(f"{self.__class__} object need to set rows and columns, or the board_data")
|
||||||
|
|
||||||
|
self.cell_sprites: dict[Point2D, tuple["Sprite", hash]] = {}
|
||||||
|
|
||||||
super().__init__(scene, x, y, width, height)
|
super().__init__(scene, x, y, width, height)
|
||||||
|
|
||||||
self.group_cursor = pyglet.graphics.Group(order=1)
|
self.group_cursor = pyglet.graphics.Group(order=1)
|
||||||
self.group_line = pyglet.graphics.Group(order=2)
|
self.group_line = pyglet.graphics.Group(order=2)
|
||||||
|
|
||||||
self.rows = rows
|
|
||||||
self.columns = columns
|
|
||||||
|
|
||||||
# the list of the size of the boats to place
|
# the list of the size of the boats to place
|
||||||
self.boats_length = [] if boats_length is None else sorted(boats_length, reverse=True)
|
self.boats_length = [] if boats_length is None else sorted(boats_length, reverse=True)
|
||||||
self.preview_color = preview_color
|
self.preview_color = preview_color
|
||||||
|
|
||||||
self.board = Board(rows=self.rows, columns=self.columns)
|
# créer la planche du jeu
|
||||||
|
self.board = Board(width=rows, height=columns) if board_data is None else Board.from_json(board_data)
|
||||||
|
self.rows = self.board.height
|
||||||
|
self.columns = self.board.width
|
||||||
|
|
||||||
self.orientation: Orientation = Orientation.HORIZONTAL
|
self.orientation: Orientation = Orientation.HORIZONTAL
|
||||||
|
|
||||||
self._boat_kwargs = dict_filter_prefix("boat_", kwargs)
|
self._boat_kwargs = dict_filter_prefix("boat_", kwargs)
|
||||||
self._bomb_kwargs = dict_filter_prefix("bomb_", kwargs)
|
self._bomb_kwargs = dict_filter_prefix("bomb_", kwargs)
|
||||||
self.grid_style = grid_style
|
self.grid_style = grid_style
|
||||||
self.boat_style = boat_style
|
self.boat_style = boat_style
|
||||||
self.bomb_style = bomb_style
|
|
||||||
|
|
||||||
self.background = Sprite(
|
self.background = Sprite(
|
||||||
img=grid_style.get("background"),
|
img=grid_style.get("background"),
|
||||||
|
@ -91,6 +94,7 @@ class GameGrid(BoxWidget):
|
||||||
self.add_listener("on_hover", lambda _, *args: self._refresh_cursor(*args))
|
self.add_listener("on_hover", lambda _, *args: self._refresh_cursor(*args))
|
||||||
|
|
||||||
self._refresh_size()
|
self._refresh_size()
|
||||||
|
self.display_board(self.board)
|
||||||
|
|
||||||
def get_cell_from_rel(self, rel_x: int, rel_y: int) -> tuple[int, int]:
|
def get_cell_from_rel(self, rel_x: int, rel_y: int) -> tuple[int, int]:
|
||||||
"""
|
"""
|
||||||
|
@ -124,7 +128,7 @@ class GameGrid(BoxWidget):
|
||||||
|
|
||||||
# sprites
|
# sprites
|
||||||
|
|
||||||
for (x, y), sprite in self.cell_sprites.items():
|
for (x, y), (sprite, hash_) in self.cell_sprites.items():
|
||||||
# calcul des décalages à cause de la rotation qui est faite par rapport à l'origine de l'image
|
# 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_x = 0 if sprite.rotation <= 90 else self.cell_width
|
||||||
|
@ -147,7 +151,7 @@ class GameGrid(BoxWidget):
|
||||||
self.cursor.y = self.y + cell_y * self.height / self.rows
|
self.cursor.y = self.y + cell_y * self.height / self.rows
|
||||||
self.cursor.width, self.cursor.height = self.cell_size
|
self.cursor.width, self.cursor.height = self.cell_size
|
||||||
|
|
||||||
self.preview_boat((cell_x, cell_y)) # display the previsualisation of the boat on this cell
|
self.preview_boat((cell_x, cell_y)) # display the preview of the boat on this cell
|
||||||
|
|
||||||
# function
|
# function
|
||||||
|
|
||||||
|
@ -155,17 +159,28 @@ class GameGrid(BoxWidget):
|
||||||
self.cursor.width, self.cursor.height = 0, 0
|
self.cursor.width, self.cursor.height = 0, 0
|
||||||
|
|
||||||
def display_board(self, board: Board, preview: bool = False):
|
def display_board(self, board: Board, preview: bool = False):
|
||||||
self.cell_sprites: dict[Point2D, "Sprite"] = {}
|
# remplacer par l'utilisation de board.boats ?
|
||||||
|
|
||||||
matrice = board.get_matrice()
|
matrice = board.boats
|
||||||
max_boat: int = matrice.max()
|
max_boat: int = np.max(matrice)
|
||||||
|
|
||||||
for (y, x), value in np.ndenumerate(matrice):
|
for (y, x), value in np.ndenumerate(matrice):
|
||||||
if value == 0: continue
|
bombed: bool = not board.bombs[y, x] # cette case a déjà été attaqué si la valeur est "False".
|
||||||
|
|
||||||
|
if value == 0 and not bombed:
|
||||||
|
|
||||||
|
if (x, y) in self.cell_sprites:
|
||||||
|
self.cell_sprites.pop((x, y))
|
||||||
|
|
||||||
|
continue # ignore s'il n'y a ni bombe, ni bateau.
|
||||||
|
|
||||||
# calcul de la forme et de la rotation de cette cellule du bateau
|
# calcul de la forme et de la rotation de cette cellule du bateau
|
||||||
|
|
||||||
form, rotation = (
|
form, rotation = (
|
||||||
|
# bombe
|
||||||
|
("touched", 0) if bombed and value != 0 else
|
||||||
|
("missed", 0) if bombed else
|
||||||
|
|
||||||
# corps
|
# corps
|
||||||
("body", 0) if 0 < y < (self.rows-1) and matrice[y-1, x] == matrice[y+1, x] == value else # colonne
|
("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", 1) if 0 < x < (self.columns-1) and matrice[y, x-1] == matrice[y, x+1] == value else # ligne
|
||||||
|
@ -180,17 +195,25 @@ class GameGrid(BoxWidget):
|
||||||
("solo", 0)
|
("solo", 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# si le bateau est le dernier placé et qu'on est en prévisualisation, change sa teinte.
|
||||||
|
color: ColorRGB = self.preview_color if preview and value == max_boat else (255, 255, 255)
|
||||||
|
|
||||||
|
hash_new = hash((form, rotation, color))
|
||||||
|
sprite_old, hash_old = self.cell_sprites.get((x, y), (None, None))
|
||||||
|
|
||||||
|
if hash_old == hash_new:
|
||||||
|
# si la texture n'a pas changé, ne rafraichi pas le sprite
|
||||||
|
continue
|
||||||
|
|
||||||
sprite = Sprite(
|
sprite = Sprite(
|
||||||
img=self.boat_style.get(form),
|
img=self.boat_style.get(form),
|
||||||
batch=self.scene.batch,
|
batch=self.scene.batch,
|
||||||
**self._boat_kwargs
|
**self._boat_kwargs
|
||||||
)
|
)
|
||||||
sprite.rotation = rotation * 90
|
sprite.rotation = rotation * 90
|
||||||
|
sprite.color = color
|
||||||
|
|
||||||
if preview and value == max_boat: # if in preview and it is the latest boat
|
self.cell_sprites[x, y] = (sprite, hash_new)
|
||||||
sprite.color = self.preview_color # make the image more greenish
|
|
||||||
|
|
||||||
self.cell_sprites[(x, y)] = sprite
|
|
||||||
|
|
||||||
self._refresh_size()
|
self._refresh_size()
|
||||||
|
|
||||||
|
@ -208,14 +231,15 @@ class GameGrid(BoxWidget):
|
||||||
Boat(self.boats_length[0], orientation=self.orientation),
|
Boat(self.boats_length[0], orientation=self.orientation),
|
||||||
cell
|
cell
|
||||||
)
|
)
|
||||||
except InvalidBoatPosition: pass # if the boat can't be placed, ignore
|
except InvalidBoatPosition:
|
||||||
|
pass # if the boat can't be placed, ignore
|
||||||
|
|
||||||
else: # if the boat have been placed
|
else: # if the boat have been placed
|
||||||
self.boats_length.pop(0) # remove the boat from the list of boat to place
|
self.boats_length.pop(0) # remove the boat from the list of boat to place
|
||||||
if len(self.boats_length) == 0:
|
if len(self.boats_length) == 0:
|
||||||
self.trigger_event("on_all_boats_placed")
|
self.trigger_event("on_all_boats_placed")
|
||||||
|
|
||||||
self.display_board(self.board)
|
self.display_board(self.board) # rafraichi l'affichage
|
||||||
|
|
||||||
def preview_boat(self, cell: Point2D):
|
def preview_boat(self, cell: Point2D):
|
||||||
if len(self.boats_length) == 0: return
|
if len(self.boats_length) == 0: return
|
||||||
|
@ -226,23 +250,19 @@ class GameGrid(BoxWidget):
|
||||||
Boat(self.boats_length[0], orientation=self.orientation),
|
Boat(self.boats_length[0], orientation=self.orientation),
|
||||||
cell
|
cell
|
||||||
)
|
)
|
||||||
|
except InvalidBoatPosition:
|
||||||
|
self.display_board(self.board) # if the boat can't be placed, ignore
|
||||||
|
|
||||||
except InvalidBoatPosition: self.display_board(self.board) # if the boat can't be placed, ignore
|
|
||||||
else: self.display_board(preview_board, preview=True)
|
else: self.display_board(preview_board, preview=True)
|
||||||
|
|
||||||
def place_bomb(self, cell: Point2D, force_touched: bool = None) -> BombState:
|
def place_bomb(self, cell: Point2D, force_touched: bool = None) -> BombState:
|
||||||
bomb_state = self.board.bomb(cell)
|
bomb_state = self.board.bomb(cell)
|
||||||
|
|
||||||
self.cell_sprites[cell] = Sprite(
|
if force_touched is not None:
|
||||||
img=self.bomb_style.get(
|
x, y = cell
|
||||||
"touched" if (bomb_state.success if force_touched is None else force_touched) else "missed"
|
self.board.boats[y, x] = int(force_touched)
|
||||||
),
|
|
||||||
batch=self.scene.batch,
|
|
||||||
**self._bomb_kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
self._refresh_size()
|
|
||||||
|
|
||||||
|
self.display_board(self.board)
|
||||||
return bomb_state
|
return bomb_state
|
||||||
|
|
||||||
def on_click_release(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
def on_click_release(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
||||||
|
|
|
@ -38,7 +38,8 @@ class Image(BoxWidget):
|
||||||
# refresh
|
# refresh
|
||||||
|
|
||||||
def _refresh_size(self):
|
def _refresh_size(self):
|
||||||
self.image.x, self.image.y, self.image.width, self.image.height = self.bbox
|
self.image.x, self.image.y = self.xy
|
||||||
|
self.image.width, self.image.height = self.size
|
||||||
|
|
||||||
# event
|
# event
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, Optional
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
|
@ -37,17 +38,21 @@ class Client(StoppableThread):
|
||||||
|
|
||||||
# sauvegarde
|
# sauvegarde
|
||||||
|
|
||||||
# attend que l'hôte indique s'il a trouvé une ancienne sauvegarde
|
load_old_save: bool = False
|
||||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection)
|
|
||||||
|
|
||||||
if packet_save_found.value:
|
# attend que l'hôte indique s'il a trouvé une ancienne sauvegarde
|
||||||
|
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||||
|
|
||||||
|
if packet_save_found:
|
||||||
# si l'hôte a trouvé une ancienne sauvegarde, vérifier de notre côté également.
|
# si l'hôte a trouvé une ancienne sauvegarde, vérifier de notre côté également.
|
||||||
|
|
||||||
path_old_save: Optional[Path] = None
|
path_old_save: Optional[Path] = None
|
||||||
ip_address, _ = connection.getpeername()
|
ip_address, _ = connection.getpeername()
|
||||||
|
|
||||||
for file in path_save.iterdir():
|
for file in reversed(list(path_save.iterdir())):
|
||||||
if file.stem == ip_address:
|
# la liste est inversée dans le cas où le fichier est en localhost, afin que l'hôte
|
||||||
|
# prenne le fichier en -0.bn-save et le client en -1.bn-save
|
||||||
|
if file.stem.startswith(ip_address):
|
||||||
path_old_save = file
|
path_old_save = file
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -63,23 +68,38 @@ class Client(StoppableThread):
|
||||||
while True:
|
while True:
|
||||||
# attend la décision de l'hôte
|
# attend la décision de l'hôte
|
||||||
try:
|
try:
|
||||||
load_old_save = PacketLoadOldSave.from_connection(connection)
|
load_old_save = PacketLoadOldSave.from_connection(connection).value
|
||||||
break
|
break
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
if self.stopped: return
|
if self.stopped: return
|
||||||
|
|
||||||
print("accept load", load_old_save)
|
if load_old_save:
|
||||||
|
|
||||||
if load_old_save.value:
|
# charge la sauvegarde
|
||||||
...
|
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||||
# TODO: Charger nos données
|
save_data = json.load(file)
|
||||||
|
|
||||||
# paramètres & jeu
|
# paramètres & jeu
|
||||||
|
|
||||||
settings: Any = PacketSettings.from_connection(connection)
|
settings: Any = PacketSettings.from_connection(connection)
|
||||||
PacketUsername(username=self.username).send_data_connection(connection)
|
PacketUsername(username=self.username).send_data_connection(connection)
|
||||||
packet_username = PacketUsername.from_connection(connection)
|
enemy_username = PacketUsername.from_connection(connection).username
|
||||||
|
|
||||||
|
if load_old_save:
|
||||||
|
game_scene = in_pyglet_context(
|
||||||
|
self.window.set_scene,
|
||||||
|
scene.Game.from_json, # depuis le fichier json
|
||||||
|
|
||||||
|
data=save_data,
|
||||||
|
|
||||||
|
thread=self,
|
||||||
|
connection=connection,
|
||||||
|
|
||||||
|
name_ally=self.username,
|
||||||
|
name_enemy=enemy_username,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
game_scene = in_pyglet_context(
|
game_scene = in_pyglet_context(
|
||||||
self.window.set_scene,
|
self.window.set_scene,
|
||||||
scene.Game,
|
scene.Game,
|
||||||
|
@ -89,7 +109,7 @@ class Client(StoppableThread):
|
||||||
|
|
||||||
boats_length=settings.boats_length,
|
boats_length=settings.boats_length,
|
||||||
name_ally=self.username,
|
name_ally=self.username,
|
||||||
name_enemy=packet_username.username,
|
name_enemy=enemy_username,
|
||||||
grid_width=settings.grid_width,
|
grid_width=settings.grid_width,
|
||||||
grid_height=settings.grid_height,
|
grid_height=settings.grid_height,
|
||||||
my_turn=not settings.host_start
|
my_turn=not settings.host_start
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
@ -29,7 +30,7 @@ class Host(StoppableThread):
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
self.condition_load = Condition()
|
self.condition_load = Condition()
|
||||||
self.accept_load: Optional[bool] = None
|
self.accept_load: bool = False
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
print("[Serveur] Thread démarré")
|
print("[Serveur] Thread démarré")
|
||||||
|
@ -55,7 +56,7 @@ class Host(StoppableThread):
|
||||||
path_old_save: Optional[Path] = None
|
path_old_save: Optional[Path] = None
|
||||||
|
|
||||||
for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'ip de l'adversaire
|
for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'ip de l'adversaire
|
||||||
if file.stem == ip_address:
|
if file.stem.startswith(ip_address):
|
||||||
path_old_save = file
|
path_old_save = file
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -64,10 +65,10 @@ class Host(StoppableThread):
|
||||||
|
|
||||||
if path_old_save is not None:
|
if path_old_save is not None:
|
||||||
# si une ancienne sauvegarde a été trouvée, attend que l'adversaire confirme avoir également la save
|
# si une ancienne sauvegarde a été trouvée, attend que l'adversaire confirme avoir également la save
|
||||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection)
|
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||||
|
|
||||||
# si l'adversaire à également la sauvegarde, demande à l'hôte de confirmer l'utilisation de la save
|
# si l'adversaire à également la sauvegarde, demande à l'hôte de confirmer l'utilisation de la save
|
||||||
if packet_save_found.value:
|
if packet_save_found:
|
||||||
|
|
||||||
from source.gui.scene import GameLoad
|
from source.gui.scene import GameLoad
|
||||||
in_pyglet_context(self.window.set_scene, GameLoad, thread_host=self)
|
in_pyglet_context(self.window.set_scene, GameLoad, thread_host=self)
|
||||||
|
@ -77,15 +78,32 @@ class Host(StoppableThread):
|
||||||
PacketLoadOldSave(value=self.accept_load).send_data_connection(connection)
|
PacketLoadOldSave(value=self.accept_load).send_data_connection(connection)
|
||||||
|
|
||||||
if self.accept_load:
|
if self.accept_load:
|
||||||
...
|
|
||||||
# TODO: Charger nos données
|
|
||||||
|
|
||||||
# paramètres & jeu
|
# charge la sauvegarde
|
||||||
|
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||||
|
save_data = json.load(file)
|
||||||
|
|
||||||
|
# paramètres et jeu
|
||||||
|
|
||||||
self.settings.send_data_connection(connection)
|
self.settings.send_data_connection(connection)
|
||||||
packet_username = PacketUsername.from_connection(connection)
|
enemy_username = PacketUsername.from_connection(connection).username
|
||||||
PacketUsername(username=self.username).send_data_connection(connection)
|
PacketUsername(username=self.username).send_data_connection(connection)
|
||||||
|
|
||||||
|
if self.accept_load:
|
||||||
|
game_scene = in_pyglet_context(
|
||||||
|
self.window.set_scene,
|
||||||
|
scene.Game.from_json, # depuis le fichier json
|
||||||
|
|
||||||
|
data=save_data,
|
||||||
|
|
||||||
|
thread=self,
|
||||||
|
connection=connection,
|
||||||
|
|
||||||
|
name_ally=self.username,
|
||||||
|
name_enemy=enemy_username,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
game_scene = in_pyglet_context(
|
game_scene = in_pyglet_context(
|
||||||
self.window.set_scene,
|
self.window.set_scene,
|
||||||
scene.Game,
|
scene.Game,
|
||||||
|
@ -95,7 +113,7 @@ class Host(StoppableThread):
|
||||||
|
|
||||||
boats_length=self.settings.boats_length,
|
boats_length=self.settings.boats_length,
|
||||||
name_ally=self.username,
|
name_ally=self.username,
|
||||||
name_enemy=packet_username.username,
|
name_enemy=enemy_username,
|
||||||
grid_width=self.settings.grid_width,
|
grid_width=self.settings.grid_width,
|
||||||
grid_height=self.settings.grid_height,
|
grid_height=self.settings.grid_height,
|
||||||
my_turn=self.settings.host_start
|
my_turn=self.settings.host_start
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import builtins
|
||||||
import socket
|
import socket
|
||||||
from typing import Type, Callable
|
from typing import Type, Callable
|
||||||
|
|
||||||
|
@ -47,9 +48,14 @@ def game_network(
|
||||||
|
|
||||||
if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as exception:
|
||||||
# TODO: meilleur messages
|
message: str = "Erreur :\n"
|
||||||
|
|
||||||
|
match type(exception):
|
||||||
|
case builtins.ConnectionResetError:
|
||||||
|
message += "Perte de connexion avec l'adversaire."
|
||||||
|
case _:
|
||||||
|
message += str(exception)
|
||||||
|
|
||||||
from source.gui.scene import GameError
|
from source.gui.scene import GameError
|
||||||
in_pyglet_context(game_scene.window.set_scene, GameError, text=f"Une erreur est survenu :\n{str(e)}")
|
in_pyglet_context(game_scene.window.set_scene, GameError, text=message)
|
||||||
print(type(e), e)
|
|
||||||
|
|