From cdaebc74358fa72d9f25e5e4f2dd6ad6fe626f1a Mon Sep 17 00:00:00 2001 From: Stepan Date: Thu, 8 Aug 2024 00:20:32 +0300 Subject: [PATCH 1/3] Solution ver:1 --- app/main.py | 183 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 157 insertions(+), 26 deletions(-) diff --git a/app/main.py b/app/main.py index 626f41cf..f8c0f2cb 100644 --- a/app/main.py +++ b/app/main.py @@ -1,34 +1,165 @@ -class Deck: - def __init__(self, row, column, is_alive=True): - pass +from __future__ import annotations + + +class Cell: + def __init__(self, row: int, column: int, symbol: str = "~") -> None: + self.row = row + self.column = column + self.symbol = symbol + + +class Deck(Cell): + def __init__(self, row: int, column: int, is_alive: bool = True) -> None: + super().__init__(row, column, "□") + self.is_alive = is_alive class Ship: - def __init__(self, start, end, is_drowned=False): - # Create decks and save them to a list `self.decks` - pass + def __init__( + self, + start: tuple, + end: tuple, + is_drowned: bool = False + ) -> None: + self.start = start + self.end = end + self.decks = self.create_decs(start, end) + self.is_drowned = is_drowned + + def get_deck(self, row: int, column: int) -> Deck | None: + deck = [ + deck for deck in self.decks + if deck.row == row and deck.column == column + ] + return deck[0] if deck else None + + def fire(self, row: int, column: int) -> str: + if self.is_drowned: + return "The ship in this location already drowned" + + deck = self.get_deck(row, column) + deck.is_alive = False + deck.symbol = "*" + return "Sunk!" if self.if_all_deck_is_damaged() else "Hit!" + + def if_all_deck_is_damaged(self) -> bool: + if not any([deck.is_alive for deck in self.decks]): + self.is_drowned = True + for deck in self.decks: + deck.symbol = "x" + return True + return False + + @staticmethod + def create_decs(start: tuple, end: tuple) -> list[Deck]: + list_of_decks = [] + if start[0] == end[0]: + # ship located horizontally + ship_length = end[1] - start[1] + 1 + for i in range(ship_length): + list_of_decks.append(Deck(start[0], start[1] + i)) + else: + # ship located vertically + ship_length = end[0] - start[0] + 1 + for i in range(ship_length): + list_of_decks.append(Deck(start[0] + i, start[1])) - def get_deck(self, row, column): - # Find the corresponding deck in the list - pass + return list_of_decks - def fire(self, row, column): - # Change the `is_alive` status of the deck - # And update the `is_drowned` value if it's needed - pass + @classmethod + def create_ship(cls, ship_cords: tuple) -> Ship: + return Ship(*ship_cords) class Battleship: - def __init__(self, ships): - # Create a dict `self.field`. - # Its keys are tuples - the coordinates of the non-empty cells, - # A value for each cell is a reference to the ship - # which is located in it - pass - - def fire(self, location: tuple): - # This function should check whether the location - # is a key in the `self.field` - # If it is, then it should check if this cell is the last alive - # in the ship or not. - pass + def __init__(self, ships: list[tuple]) -> None: + self.field = self.create_empty_field() + self.ships = ships + + @property + def ships(self) -> list[Ship]: + return self._ships + + @ships.setter + def ships(self, ships: list[tuple]) -> None: + self._ships = [Ship.create_ship(cords) for cords in ships] + self.add_ships_to_the_field() + + def fire(self, location: tuple) -> str: + try: + if not isinstance(self.field[location], Ship): + return "Miss!" + result = self.field[location].fire(*location) + # If you want to print field -> uncomment func() below + # self.print_field() + return result + except (TypeError, KeyError): + print( + f"Location {location} isn't correct. " + f"Must be in range (0-9, 0-9)" + ) + + def add_ships_to_the_field(self) -> None: + for ship in self.ships: + for deck in ship.decks: + self.field[(deck.row, deck.column)] = ship + + def print_field(self) -> None: + for i, (cords, cell) in enumerate(self.field.items()): + if i % 10 == 0: + print() + print(self.get_symbol_from_cell(cords, cell), end=" ") + print("") + + @staticmethod + def get_symbol_from_cell(cords: tuple[int, int], cell: Cell | Ship) -> str: + if isinstance(cell, Ship): + return cell.get_deck(cords[0], cords[1]).symbol + else: + return cell.symbol + + @staticmethod + def create_empty_field() -> dict[tuple[int, int], Cell]: + return ({ + (i, j): Cell(i, j) + for i in range(10) + for j in range(10) + }) + + +if __name__ == "__main__": + shipss = [ + ((2, 0), (2, 3)), + ((4, 5), (4, 6)), + ((3, 8), (3, 9)), + ((6, 0), (8, 0)), + ((6, 4), (6, 6)), + ((6, 8), (6, 9)), + ((9, 9), (9, 9)), + ((9, 5), (9, 5)), + ((9, 3), (9, 3)), + ((9, 7), (9, 7)) + ] + battle = Battleship(shipss) + # battle.print_field() + # battle.add_ships_to_the_field() + # battle.print_field() + # battle.fire((0, 0)) + # battle.fire((0, 1)) + # battle.fire((0, 2)) + # battle.fire((0, 3)) + # battle.fire((0, 4)) + # print(battle.field) + print(battle.fire((0, 4))) # == "Miss!" + print(battle.fire((1, 7))) # == "Miss!" + print(battle.fire((2, 0))) # == "Hit!" + print(battle.fire((2, 1))) # == "Hit!" + print(battle.fire((2, 2))) # == "Hit!" + print(battle.fire((2, 3))) # == "Sunk!" + print(battle.fire((4, 3))) # == "Miss!" + print(battle.fire((4, 5))) # == "Hit!" + print(battle.fire((5, 5))) # == "Miss!" + print(battle.fire((4, 6))) # == "Sunk!" + print(battle.fire((9, 5))) # == "Sunk!" + print(battle.fire((9, 6))) # + pass From a937dadcafb5fdfcbfa6cc1760c2d297b8e482a9 Mon Sep 17 00:00:00 2001 From: Stepan Date: Thu, 8 Aug 2024 00:21:42 +0300 Subject: [PATCH 2/3] Solution ver:2 --- app/main.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/app/main.py b/app/main.py index f8c0f2cb..f9ebaced 100644 --- a/app/main.py +++ b/app/main.py @@ -125,41 +125,3 @@ def create_empty_field() -> dict[tuple[int, int], Cell]: for i in range(10) for j in range(10) }) - - -if __name__ == "__main__": - shipss = [ - ((2, 0), (2, 3)), - ((4, 5), (4, 6)), - ((3, 8), (3, 9)), - ((6, 0), (8, 0)), - ((6, 4), (6, 6)), - ((6, 8), (6, 9)), - ((9, 9), (9, 9)), - ((9, 5), (9, 5)), - ((9, 3), (9, 3)), - ((9, 7), (9, 7)) - ] - battle = Battleship(shipss) - # battle.print_field() - # battle.add_ships_to_the_field() - # battle.print_field() - # battle.fire((0, 0)) - # battle.fire((0, 1)) - # battle.fire((0, 2)) - # battle.fire((0, 3)) - # battle.fire((0, 4)) - # print(battle.field) - print(battle.fire((0, 4))) # == "Miss!" - print(battle.fire((1, 7))) # == "Miss!" - print(battle.fire((2, 0))) # == "Hit!" - print(battle.fire((2, 1))) # == "Hit!" - print(battle.fire((2, 2))) # == "Hit!" - print(battle.fire((2, 3))) # == "Sunk!" - print(battle.fire((4, 3))) # == "Miss!" - print(battle.fire((4, 5))) # == "Hit!" - print(battle.fire((5, 5))) # == "Miss!" - print(battle.fire((4, 6))) # == "Sunk!" - print(battle.fire((9, 5))) # == "Sunk!" - print(battle.fire((9, 6))) # - pass From 72aaa1ac1c16acc3857b6a87abb46b9b78b7641a Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 27 Aug 2024 15:56:46 +0300 Subject: [PATCH 3/3] "added some changes" --- app/main.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/main.py b/app/main.py index f9ebaced..dfef9b06 100644 --- a/app/main.py +++ b/app/main.py @@ -26,18 +26,20 @@ def __init__( self.decks = self.create_decs(start, end) self.is_drowned = is_drowned - def get_deck(self, row: int, column: int) -> Deck | None: - deck = [ + def get_deck(self, row: int, column: int) -> Deck: + return [ deck for deck in self.decks if deck.row == row and deck.column == column - ] - return deck[0] if deck else None + ][0] def fire(self, row: int, column: int) -> str: if self.is_drowned: return "The ship in this location already drowned" deck = self.get_deck(row, column) + if deck.is_alive is False: + return "The deck has already been struck" + deck.is_alive = False deck.symbol = "*" return "Sunk!" if self.if_all_deck_is_damaged() else "Hit!" @@ -68,7 +70,7 @@ def create_decs(start: tuple, end: tuple) -> list[Deck]: @classmethod def create_ship(cls, ship_cords: tuple) -> Ship: - return Ship(*ship_cords) + return cls(*ship_cords) class Battleship: @@ -115,8 +117,8 @@ def print_field(self) -> None: def get_symbol_from_cell(cords: tuple[int, int], cell: Cell | Ship) -> str: if isinstance(cell, Ship): return cell.get_deck(cords[0], cords[1]).symbol - else: - return cell.symbol + + return cell.symbol @staticmethod def create_empty_field() -> dict[tuple[int, int], Cell]: