From 2e9e1e1760d34d31c9cdcc44edb1d44905329e07 Mon Sep 17 00:00:00 2001 From: Den Date: Fri, 20 Feb 2026 14:54:45 +0100 Subject: [PATCH 1/3] feat: created battleship --- app/main.py | 105 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 25 deletions(-) diff --git a/app/main.py b/app/main.py index 626f41cf..f3a2b722 100644 --- a/app/main.py +++ b/app/main.py @@ -1,34 +1,89 @@ class Deck: - def __init__(self, row, column, is_alive=True): - pass + def __init__( + self, + row: int, + column: int, + is_alive: bool = True + ) -> None: + self.row = row + self.column = 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: int, + end: int, + is_drowned: bool = False + ) -> None: + self.start_x, self.start_y = start + self.end_x, self.end_y = end + self.is_drowned = is_drowned + self.decks = [] - def get_deck(self, row, column): - # Find the corresponding deck in the list - pass + if self.start_x == self.end_x: + for y_coord in range( + min(self.start_y, self.end_y), + max(self.start_y, self.end_y) + 1): + self.decks.append(Deck(self.start_x, y_coord)) - def fire(self, row, column): - # Change the `is_alive` status of the deck - # And update the `is_drowned` value if it's needed - pass + elif self.start_y < self.end_y: + for x_coord in range( + min(self.start_x, self.end_x), + max(self.start_x, self.end_x) + 1): + self.decks.append(Deck(x_coord, self.start_y)) + else: + return + + def get_deck( + self, + row: int, + column: int + ) -> None: + for deck in self.decks: + if deck.row == row and deck.column == column: + return deck + return None + + def fire( + self, + row: int, + column: int + ) -> None: + deck = self.get_deck(row, column) + if deck: + deck.is_alive = False + for _deck in self.decks: + if _deck.is_alive is True: + return + self.is_drowned = True 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 + ) -> None: + self.ships = [] + self.field = {} + for start, end in ships: + new_ship = Ship(start, end) + self.ships.append(new_ship) + + for ship in self.ships: + for deck in ship.decks: + coord = (deck.row, deck.column) + self.field[coord] = ship + + def fire( + self, + location: tuple + ) -> str: + if location not in self.field: + return "Miss!" + target_ship = self.field[location] + target_ship.fire(*location) + if target_ship.is_drowned: + return "Sunk!" + return "Hit!" From fd497e8b003c147680ca68aade2689a5b1844cfe Mon Sep 17 00:00:00 2001 From: Den Date: Fri, 20 Feb 2026 15:18:22 +0100 Subject: [PATCH 2/3] feat: implement 2 methods --- app/main.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/app/main.py b/app/main.py index f3a2b722..3a78d2a6 100644 --- a/app/main.py +++ b/app/main.py @@ -28,13 +28,13 @@ def __init__( max(self.start_y, self.end_y) + 1): self.decks.append(Deck(self.start_x, y_coord)) - elif self.start_y < self.end_y: + elif self.start_y == self.end_y: for x_coord in range( min(self.start_x, self.end_x), max(self.start_x, self.end_x) + 1): self.decks.append(Deck(x_coord, self.start_y)) else: - return + raise ValueError def get_deck( self, @@ -76,6 +76,39 @@ def __init__( coord = (deck.row, deck.column) self.field[coord] = ship + def print_field(self) -> None: + for row in range(10): + for colum in range(10): + ship = self.field.get((row, colum)) + if ship: + deck = ship.get_deck(row, colum) + if ship.is_drowned: + print("x", end=" ") + elif not deck.is_alive: + print("*", end=" ") + else: + print("□", end=" ") + else: + print("~", end=" ") + print() + + def _validate_field(self) -> None: + lengths = [len(s.decks) for s in self.ships] + if (lengths.count(4) != 1 or lengths.count(3) != 2 + or lengths.count(2) != 3 or lengths.count(1) != 4): + raise ValueError + for ship in self.ships: + for deck in ship.decks: + for dr in range(-1, 2): + for dc in range(-1, 2): + if dr == 0 and dc == 0: + continue + neighbor_coord = (deck.row + dr, deck.column + dc) + neighbor_ship = self.field.get(neighbor_coord) + + if neighbor_ship and neighbor_ship is not ship: + raise ValueError + def fire( self, location: tuple From dcb7e504f8e213cba62ee5fdfcdd22973ad0104e Mon Sep 17 00:00:00 2001 From: Den Date: Fri, 20 Feb 2026 15:26:14 +0100 Subject: [PATCH 3/3] fix: value assignment and add at the end of __init__ call --- app/main.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/main.py b/app/main.py index 3a78d2a6..2056720e 100644 --- a/app/main.py +++ b/app/main.py @@ -17,22 +17,22 @@ def __init__( end: int, is_drowned: bool = False ) -> None: - self.start_x, self.start_y = start - self.end_x, self.end_y = end + start_x, start_y = start + end_x, end_y = end self.is_drowned = is_drowned self.decks = [] - if self.start_x == self.end_x: + if start_x == end_x: for y_coord in range( - min(self.start_y, self.end_y), - max(self.start_y, self.end_y) + 1): - self.decks.append(Deck(self.start_x, y_coord)) + min(start_y, end_y), + max(start_y, end_y) + 1): + self.decks.append(Deck(start_x, y_coord)) - elif self.start_y == self.end_y: + elif start_y == end_y: for x_coord in range( - min(self.start_x, self.end_x), - max(self.start_x, self.end_x) + 1): - self.decks.append(Deck(x_coord, self.start_y)) + min(start_x, end_x), + max(start_x, end_x) + 1): + self.decks.append(Deck(x_coord, start_y)) else: raise ValueError @@ -76,6 +76,8 @@ def __init__( coord = (deck.row, deck.column) self.field[coord] = ship + self._validate_field() + def print_field(self) -> None: for row in range(10): for colum in range(10):