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.enums import Orientation, BombState
|
||||
from source.core.error import InvalidBoatPosition, PositionAlreadyShot
|
||||
from source.utils import copy_array_offset
|
||||
from source.core.error import InvalidBoatPosition, PositionAlreadyShot, InvalidBombPosition
|
||||
from source.utils import copy_array_offset, in_bbox
|
||||
|
||||
|
||||
class Board:
|
||||
|
@ -49,7 +49,8 @@ class Board:
|
|||
board_mat_sum_old: int = board_mat.sum()
|
||||
|
||||
# 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
|
||||
board_mat_sum_new: int = board_mat.sum()
|
||||
|
@ -73,6 +74,11 @@ class Board:
|
|||
:position: the position where to shoot
|
||||
: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 not self._bombs[position]: raise PositionAlreadyShot(position)
|
||||
|
||||
|
|
|
@ -6,3 +6,5 @@ class BombState(Enum):
|
|||
TOUCHED = 1
|
||||
SUNKEN = 2
|
||||
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 .PositionAlreadyShot import PositionAlreadyShot
|
||||
from .InvalidBombPosition import InvalidBombPosition
|
||||
|
|
|
@ -1,24 +1,105 @@
|
|||
import json
|
||||
import socket
|
||||
import sys
|
||||
|
||||
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())
|
||||
|
||||
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:
|
||||
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 socket
|
||||
import sys
|
||||
|
||||
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:
|
||||
s.bind(("127.0.0.1", 7878))
|
||||
s.listen()
|
||||
conn, addr = s.accept()
|
||||
|
||||
message = conn.recv(1024)
|
||||
conn.send(b"SALUT")
|
||||
print(f"[Serveur] Connecté avec {addr}")
|
||||
|
||||
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)
|
||||
print(Board.from_json(board_json))
|
||||
conn.send(width.to_bytes(32, "big"))
|
||||
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