commit 9812452e1f4d285f3a86f8589de1e05cf052ae90 Author: Tim McCarthy Date: Mon Apr 25 11:09:51 2022 -0700 [WIP] diff --git a/battleship.py b/battleship.py new file mode 100644 index 0000000..2a8285b --- /dev/null +++ b/battleship.py @@ -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!")