[WIP]
This commit is contained in:
121
battleship.py
Normal file
121
battleship.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from os import system
|
||||||
|
from typing import Tuple, List, Set, Optional
|
||||||
|
from enum import Enum, auto
|
||||||
|
|
||||||
|
|
||||||
|
class ShipOrientation(Enum):
|
||||||
|
RIGHT = auto()
|
||||||
|
DOWN = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class ShipType(Enum):
|
||||||
|
PATROL_BOAT = (2, "P")
|
||||||
|
DESTROYER = (3, "D")
|
||||||
|
SUBMARINE = (3, "S")
|
||||||
|
BATTLESHIP = (4, "B")
|
||||||
|
CARRIER = (5, "C")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self) -> int:
|
||||||
|
return self.value[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def symbol(self) -> str:
|
||||||
|
return self.value[1]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Ship:
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
ship_type: ShipType
|
||||||
|
orientation: ShipOrientation
|
||||||
|
|
||||||
|
def __init__(self, x: int, y: int, ship_type: ShipType, orientation: ShipOrientation):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.ship_type = ship_type
|
||||||
|
self.orientation = orientation
|
||||||
|
|
||||||
|
if self.orientation == ShipOrientation.RIGHT:
|
||||||
|
self.squares = {(x_i, self.y) for x_i in range(self.x, self.x+self.ship_type.size)}
|
||||||
|
else:
|
||||||
|
self.squares = {(self.x, y_i) for y_i in range(self.y, self.y+self.ship_type.size)}
|
||||||
|
|
||||||
|
|
||||||
|
def sunk(self, guesses: Set[Tuple[int, int]]) -> bool:
|
||||||
|
return self.squares.issubset(guesses)
|
||||||
|
|
||||||
|
def hit(self, guess) -> bool:
|
||||||
|
return guess in self.squares
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Player:
|
||||||
|
def __init__(self, name: str, board_shape: Tuple[int, int]):
|
||||||
|
self.name = name
|
||||||
|
self.board_shape = board_shape
|
||||||
|
self.guesses = set()
|
||||||
|
self.ships: List[Ship] = []
|
||||||
|
|
||||||
|
def place_ships(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def symbol_at(self, position: Tuple[int, int]) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def guess(self, opponent: Player) -> Tuple[int, int]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def defeated(self, guesses: Set[Tuple[int, int]]):
|
||||||
|
return all(ship.sunk(guesses) for ship in self.ships)
|
||||||
|
|
||||||
|
def hit(self, position: Tuple[int, int]) -> Optional[Ship]:
|
||||||
|
for ship in self.ships:
|
||||||
|
if ship.hit(position):
|
||||||
|
return ship
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HumanPlayer(Player):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AIPlayer(Player):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def grid_input(prompt: str, board_shape: Tuple[int, int]) -> Tuple[int, int]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def format_board(viewer: Player, opponent: Player) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def play_turn(player: Player, opponent: Player):
|
||||||
|
print(format_board(player, opponent))
|
||||||
|
player.guesses.add(player.guess(opponent))
|
||||||
|
window if isinstance(player, HumanPlayer) and isinstance(opponent, HumanPlayer):
|
||||||
|
system("clear")
|
||||||
|
|
||||||
|
|
||||||
|
def play_battleship(player_1: Player, player_2: Player):
|
||||||
|
player_1.place_ships()
|
||||||
|
player_2.place_ships()
|
||||||
|
|
||||||
|
while not (player_1.defeated(player_2.guesses) or player_2.defeated(player_1.guesses)):
|
||||||
|
play_turn(player_1, player_2)
|
||||||
|
play_turn(player_2, player_1)
|
||||||
|
|
||||||
|
if player_1.defeated(player_2.guesses) and player_2.defeated(player_1.guesses):
|
||||||
|
print("It's a draw!")
|
||||||
|
elif player_1.defeated(player_2.guesses):
|
||||||
|
print(f"{player_2.name} wins!")
|
||||||
|
else:
|
||||||
|
print(f"{player_1.name} wins!")
|
||||||
Reference in New Issue
Block a user