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

View file

@ -6,3 +6,5 @@ class BombState(Enum):
TOUCHED = 1 TOUCHED = 1
SUNKEN = 2 SUNKEN = 2
WON = 3 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 .InvalidBoatPosition import InvalidBoatPosition
from .PositionAlreadyShot import PositionAlreadyShot from .PositionAlreadyShot import PositionAlreadyShot
from .InvalidBombPosition import InvalidBombPosition

View file

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

View file

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