added a prototypal test server
This commit is contained in:
parent
1175c8b5d1
commit
31bb0c1d11
6 changed files with 206 additions and 21 deletions
|
@ -2,8 +2,8 @@ import numpy as np
|
||||||
|
|
||||||
from source.core.Boat 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, InvalidBombPosition
|
||||||
from source.utils import copy_array_offset
|
from source.utils import copy_array_offset, in_bbox
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
|
@ -49,7 +49,8 @@ class Board:
|
||||||
board_mat_sum_old: int = board_mat.sum()
|
board_mat_sum_old: int = board_mat.sum()
|
||||||
|
|
||||||
# add the boat to the board matrice
|
# add the boat to the board matrice
|
||||||
copy_array_offset(boat_mat, board_mat, offset=position)
|
try: copy_array_offset(boat_mat, board_mat, 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_mat_sum_new: int = board_mat.sum()
|
||||||
|
@ -73,6 +74,11 @@ class Board:
|
||||||
:position: the position where to shoot
|
:position: the position where to shoot
|
||||||
:raise: PositionAlreadyShot if the position have already been shot before
|
:raise: PositionAlreadyShot if the position have already been shot before
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# if the bomb is inside the board
|
||||||
|
x, y = 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[position]: raise PositionAlreadyShot(position)
|
if not self._bombs[position]: raise PositionAlreadyShot(position)
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,5 @@ class BombState(Enum):
|
||||||
TOUCHED = 1
|
TOUCHED = 1
|
||||||
SUNKEN = 2
|
SUNKEN = 2
|
||||||
WON = 3
|
WON = 3
|
||||||
|
|
||||||
|
ERROR = 10
|
||||||
|
|
3
source/core/error/InvalidBombPosition.py
Normal file
3
source/core/error/InvalidBombPosition.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
class InvalidBombPosition(Exception):
|
||||||
|
def __init__(self, position: tuple[int, int]):
|
||||||
|
super().__init__(f"The bomb can't be placed at {position}.")
|
|
@ -1,2 +1,3 @@
|
||||||
from .InvalidBoatPosition import InvalidBoatPosition
|
from .InvalidBoatPosition import InvalidBoatPosition
|
||||||
from .PositionAlreadyShot import PositionAlreadyShot
|
from .PositionAlreadyShot import PositionAlreadyShot
|
||||||
|
from .InvalidBombPosition import InvalidBombPosition
|
||||||
|
|
|
@ -1,24 +1,105 @@
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
from source.core.Board import Board
|
from source.core.Board import Board
|
||||||
from source.core.Boat import Boat
|
from source.core.Boat import Boat
|
||||||
from source.core.enums import Orientation
|
from source.core.enums import Orientation, BombState
|
||||||
|
from source.core.error import InvalidBoatPosition, InvalidBombPosition, PositionAlreadyShot
|
||||||
|
|
||||||
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:
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
s.connect(("127.0.0.1", 7878))
|
s.connect(("127.0.0.1", 7878))
|
||||||
|
|
||||||
s.send(board_json.encode())
|
print(f"[Client] Connecté avec {s}")
|
||||||
|
|
||||||
data = s.recv(1024)
|
width: int = int.from_bytes(s.recv(32), "big")
|
||||||
|
height: int = int.from_bytes(s.recv(32), "big")
|
||||||
|
|
||||||
print(data)
|
print(width, height)
|
||||||
|
|
||||||
|
board = Board(width, height)
|
||||||
|
|
||||||
|
boat_count: int = int.from_bytes(s.recv(32), "big")
|
||||||
|
|
||||||
|
for _ in range(boat_count):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print(board)
|
||||||
|
x = int(input("valeur X du bateau ? (int) : "))
|
||||||
|
y = int(input("valeur Y du bateau ? (int) : "))
|
||||||
|
o = input("orientation du bateau ? (H|V) : ")
|
||||||
|
board.add_boat(Boat(3, Orientation(o)), (x, y))
|
||||||
|
|
||||||
|
except InvalidBoatPosition:
|
||||||
|
print("Position du bateau invalide.", file=sys.stderr)
|
||||||
|
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
message = s.recv(32)
|
||||||
|
s.send(b"ready")
|
||||||
|
|
||||||
|
print("Phase de bombardement")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
# tour de l'adversaire
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("En attente du joueur adverse...")
|
||||||
|
|
||||||
|
x = int.from_bytes(s.recv(32), "big")
|
||||||
|
y = int.from_bytes(s.recv(32), "big")
|
||||||
|
|
||||||
|
try:
|
||||||
|
bomb_state = board.bomb((x, y))
|
||||||
|
s.send(bomb_state.value.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
match bomb_state:
|
||||||
|
case bomb_state.NOTHING:
|
||||||
|
print("Raté !")
|
||||||
|
break
|
||||||
|
|
||||||
|
case BombState.TOUCHED:
|
||||||
|
print("Touché !")
|
||||||
|
|
||||||
|
case BombState.SUNKEN:
|
||||||
|
print("Coulé !")
|
||||||
|
|
||||||
|
case BombState.WON:
|
||||||
|
print("Perdu !")
|
||||||
|
break
|
||||||
|
|
||||||
|
except (InvalidBombPosition, PositionAlreadyShot) as e:
|
||||||
|
s.send(BombState.ERROR.value.to_bytes(32, "big"))
|
||||||
|
s.send(f"Error : {str(e)}".encode())
|
||||||
|
|
||||||
|
# mon tour
|
||||||
|
|
||||||
|
while True:
|
||||||
|
x = int(input("valeur X de la bombe ? (int) : "))
|
||||||
|
y = int(input("valeur Y de la bombe ? (int) : "))
|
||||||
|
|
||||||
|
s.send(x.to_bytes(32, "big"))
|
||||||
|
s.send(y.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
bomb_state = BombState(int.from_bytes(s.recv(32), "big"))
|
||||||
|
|
||||||
|
match bomb_state:
|
||||||
|
case BombState.ERROR:
|
||||||
|
error = s.recv(1024)
|
||||||
|
print(error, file=sys.stderr)
|
||||||
|
|
||||||
|
case BombState.NOTHING:
|
||||||
|
print("Raté !")
|
||||||
|
break
|
||||||
|
|
||||||
|
case BombState.TOUCHED:
|
||||||
|
print("Touché !")
|
||||||
|
|
||||||
|
case BombState.SUNKEN:
|
||||||
|
print("Coulé !")
|
||||||
|
|
||||||
|
case BombState.WON:
|
||||||
|
print("Gagné !")
|
||||||
|
break
|
||||||
|
|
|
@ -1,18 +1,110 @@
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
from source.core.Board import Board
|
from source.core.Board import Board
|
||||||
|
from source.core.Boat import Boat
|
||||||
|
from source.core.enums import Orientation, BombState
|
||||||
|
from source.core.error import InvalidBoatPosition, InvalidBombPosition, PositionAlreadyShot
|
||||||
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
s.bind(("127.0.0.1", 7878))
|
s.bind(("127.0.0.1", 7878))
|
||||||
s.listen()
|
s.listen()
|
||||||
conn, addr = s.accept()
|
conn, addr = s.accept()
|
||||||
|
|
||||||
message = conn.recv(1024)
|
print(f"[Serveur] Connecté avec {addr}")
|
||||||
conn.send(b"SALUT")
|
|
||||||
|
|
||||||
print(conn, addr, message)
|
width: int = int(input("Largeur du plateau ? (int) : "))
|
||||||
|
height: int = int(input("Longueur du plateau ? (int) : "))
|
||||||
|
|
||||||
board_json = json.loads(message)
|
conn.send(width.to_bytes(32, "big"))
|
||||||
print(Board.from_json(board_json))
|
conn.send(height.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
board = Board(width, height)
|
||||||
|
|
||||||
|
boat_count: int = int(input("Nombre de bateau ? (int) : "))
|
||||||
|
|
||||||
|
conn.send(boat_count.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
for _ in range(boat_count):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print(board)
|
||||||
|
x = int(input("valeur X du bateau ? (int) : "))
|
||||||
|
y = int(input("valeur Y du bateau ? (int) : "))
|
||||||
|
o = input("orientation du bateau ? (H|V) : ")
|
||||||
|
board.add_boat(Boat(3, Orientation(o)), (x, y))
|
||||||
|
|
||||||
|
except InvalidBoatPosition:
|
||||||
|
print("Position du bateau invalide.", file=sys.stderr)
|
||||||
|
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
conn.send(b"ready")
|
||||||
|
message = conn.recv(32)
|
||||||
|
|
||||||
|
print("Phase de bombardement")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# posé les bombes
|
||||||
|
|
||||||
|
while True:
|
||||||
|
x = int(input("valeur X de la bombe ? (int) : "))
|
||||||
|
y = int(input("valeur Y de la bombe ? (int) : "))
|
||||||
|
|
||||||
|
conn.send(x.to_bytes(32, "big"))
|
||||||
|
conn.send(y.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
bomb_state = BombState(int.from_bytes(conn.recv(32), "big"))
|
||||||
|
|
||||||
|
match bomb_state:
|
||||||
|
case BombState.ERROR:
|
||||||
|
error = conn.recv(1024)
|
||||||
|
print(error, file=sys.stderr)
|
||||||
|
|
||||||
|
case BombState.NOTHING:
|
||||||
|
print("Raté !")
|
||||||
|
break
|
||||||
|
|
||||||
|
case BombState.TOUCHED:
|
||||||
|
print("Touché !")
|
||||||
|
|
||||||
|
case BombState.SUNKEN:
|
||||||
|
print("Coulé !")
|
||||||
|
|
||||||
|
case BombState.WON:
|
||||||
|
print("Gagné !")
|
||||||
|
break
|
||||||
|
|
||||||
|
# tour de l'adversaire
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("En attente du joueur adverse...")
|
||||||
|
|
||||||
|
x = int.from_bytes(conn.recv(32), "big")
|
||||||
|
y = int.from_bytes(conn.recv(32), "big")
|
||||||
|
|
||||||
|
try:
|
||||||
|
bomb_state = board.bomb((x, y))
|
||||||
|
conn.send(bomb_state.value.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
match bomb_state:
|
||||||
|
case bomb_state.NOTHING:
|
||||||
|
print("Raté !")
|
||||||
|
break
|
||||||
|
|
||||||
|
case BombState.TOUCHED:
|
||||||
|
print("Touché !")
|
||||||
|
|
||||||
|
case BombState.SUNKEN:
|
||||||
|
print("Coulé !")
|
||||||
|
|
||||||
|
case BombState.WON:
|
||||||
|
print("Perdu !")
|
||||||
|
break
|
||||||
|
|
||||||
|
except (InvalidBombPosition, PositionAlreadyShot) as e:
|
||||||
|
s.send(BombState.ERROR.value.to_bytes(32, "big"))
|
||||||
|
s.send(f"Error : {str(e)}".encode())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue