added a prototypal test server

This commit is contained in:
Faraphel 2023-01-10 18:16:58 +01:00
parent 1175c8b5d1
commit 31bb0c1d11
6 changed files with 206 additions and 21 deletions

View file

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

View file

@ -6,3 +6,5 @@ class BombState(Enum):
TOUCHED = 1
SUNKEN = 2
WON = 3
ERROR = 10

View 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}.")

View file

@ -1,2 +1,3 @@
from .InvalidBoatPosition import InvalidBoatPosition
from .PositionAlreadyShot import PositionAlreadyShot
from .InvalidBombPosition import InvalidBombPosition

View file

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

View file

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