From a92145559bd68febda8b300cda300ced34c0f2a8 Mon Sep 17 00:00:00 2001 From: Serhii Chumak Date: Fri, 13 Feb 2026 09:25:19 +0200 Subject: [PATCH 1/5] solution py battleship --- app/main.py | 127 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 102 insertions(+), 25 deletions(-) diff --git a/app/main.py b/app/main.py index 626f41cf..da03d56e 100644 --- a/app/main.py +++ b/app/main.py @@ -1,34 +1,111 @@ 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 + + def fire(self) -> bool: + self.is_alive = False + return self.is_alive + + def __repr__(self) -> str: + return "□" if self.is_alive else "x" 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.is_drowned = is_drowned + self.decks = self.create_decks(start, end) + + @staticmethod + def create_decks(start: tuple, end: tuple) -> List[Deck]: + decks = [] + if start[0] == end[0]: # Horizontal ship + for col in range(start[1], end[1] + 1): + decks.append(Deck(start[0], col)) + elif start[1] == end[1]: # Vertical ship + for row in range(start[0], end[0] + 1): + decks.append(Deck(row, start[1])) + return decks - def get_deck(self, row, column): - # Find the corresponding deck in the list - pass + @staticmethod + def get_deck(row: int, column: int) -> Deck: + return Deck(row, column) - def fire(self, row, column): - # Change the `is_alive` status of the deck - # And update the `is_drowned` value if it's needed - pass + def fire(self, row: int, column: int) -> str: + for deck in self.decks: + if deck.row == row and deck.column == column: + deck.fire() + if all(not deck.is_alive for deck in self.decks): + self.is_drowned = True + return "Sunk!" + return "Hit!" + return "Miss!" + + def __repr__(self) -> str: + return "".join(str(deck) for deck in self.decks) 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[Ship]) -> None: + self.field = [["~" for _ in range(10)] for _ in range(10)] + self.ships = [Ship(start, end) for start, end in ships] + self.place_ships() + self._validate_field() + + def place_ships(self) -> None: + for ship in self.ships: + for deck in ship.decks: + row, col = deck.row, deck.column + self.field[row][col] = "□" + + def fire(self, location: tuple) -> str: + row, col = location + for ship in self.ships: + result = ship.fire(*location) + if result != "Miss!": + self.field[row][col] = "*" if result == "Hit!" else "x" + return result + self.field[row][col] = "o" + return "Miss!" + + def print_field(self) -> None: + for row in self.field: + print(" ".join(row)) + + def _validate_field(self) -> None: + ship_lengths = [len(ship.decks) for ship in self.ships] + if len(self.ships) != 10: + raise ValueError("There should be exactly 10 ships.") + if ship_lengths.count(1) != 4: + raise ValueError("There should be exactly 4 single-deck ships.") + if ship_lengths.count(2) != 3: + raise ValueError("There should be exactly 3 double-deck ships.") + if ship_lengths.count(3) != 2: + raise ValueError("There should be exactly 2 three-deck ships.") + if ship_lengths.count(4) != 1: + raise ValueError("There should be exactly 1 four-deck ship.") + if not self._check_no_neighbors(): + raise ValueError("Ships should not be located " + "in neighboring cells.") + + def _check_no_neighbors(self) -> bool: + directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), + (0, 1), (1, -1), (1, 0), (1, 1) + ] + for ship in self.ships: + for deck in ship.decks: + row, col = deck.row, deck.column + for dr, dc in directions: + nr, nc = row + dr, col + dc + if (0 <= nr < 10 + and 0 <= nc < 10 + and self.field[nr][nc] == "□" + and (nr, nc) + not in [(d.row, d.column) for d in ship.decks]): + return False + return True From 087d3328e79ca3c8d9846f1a3ce99cab5aeeb559 Mon Sep 17 00:00:00 2001 From: Serhii Chumak Date: Fri, 13 Feb 2026 09:27:31 +0200 Subject: [PATCH 2/5] modified solution py battleship by mentors tips --- app/main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/main.py b/app/main.py index da03d56e..4e95e708 100644 --- a/app/main.py +++ b/app/main.py @@ -1,3 +1,6 @@ +from typing import List + + class Deck: def __init__(self, row: int, column: int, is_alive: bool = True) -> None: self.row = row From 9e057e651c83465dd769dd2f1a291a66c52fa323 Mon Sep 17 00:00:00 2001 From: Serhii Chumak Date: Fri, 13 Feb 2026 09:58:13 +0200 Subject: [PATCH 3/5] second modified solution py battleship by mentors advice --- app/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index 4e95e708..e043d32d 100644 --- a/app/main.py +++ b/app/main.py @@ -35,9 +35,9 @@ def create_decks(start: tuple, end: tuple) -> List[Deck]: decks.append(Deck(row, start[1])) return decks - @staticmethod - def get_deck(row: int, column: int) -> Deck: - return Deck(row, column) + # @staticmethod + # def get_deck(row: int, column: int) -> Deck: + # return Deck(row, column) def fire(self, row: int, column: int) -> str: for deck in self.decks: @@ -73,7 +73,7 @@ def fire(self, location: tuple) -> str: if result != "Miss!": self.field[row][col] = "*" if result == "Hit!" else "x" return result - self.field[row][col] = "o" + # self.field[row][col] = "o" return "Miss!" def print_field(self) -> None: From 75923ca2ba254b0ca0d3a23528a0ea5aa1bc95e5 Mon Sep 17 00:00:00 2001 From: Serhii Chumak Date: Fri, 13 Feb 2026 10:25:11 +0200 Subject: [PATCH 4/5] third solution py battleship by mentors advice --- app/main.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/app/main.py b/app/main.py index e043d32d..b754bcaf 100644 --- a/app/main.py +++ b/app/main.py @@ -27,18 +27,16 @@ def __init__(self, @staticmethod def create_decks(start: tuple, end: tuple) -> List[Deck]: decks = [] - if start[0] == end[0]: # Horizontal ship - for col in range(start[1], end[1] + 1): - decks.append(Deck(start[0], col)) - elif start[1] == end[1]: # Vertical ship - for row in range(start[0], end[0] + 1): - decks.append(Deck(row, start[1])) + if start[0] == end[0]: # Horizontal + r = start[0] + for col in range(min(start[1], end[1]), max(start[1], end[1]) + 1): + decks.append(Deck(r, col)) + elif start[1] == end[1]: # Vertical + c = start[1] + for row in range(min(start[0], end[0]), max(start[0], end[0]) + 1): + decks.append(Deck(row, c)) return decks - # @staticmethod - # def get_deck(row: int, column: int) -> Deck: - # return Deck(row, column) - def fire(self, row: int, column: int) -> str: for deck in self.decks: if deck.row == row and deck.column == column: @@ -54,7 +52,7 @@ def __repr__(self) -> str: class Battleship: - def __init__(self, ships: list[Ship]) -> None: + def __init__(self, ships: list[tuple]) -> None: self.field = [["~" for _ in range(10)] for _ in range(10)] self.ships = [Ship(start, end) for start, end in ships] self.place_ships() @@ -69,11 +67,17 @@ def place_ships(self) -> None: def fire(self, location: tuple) -> str: row, col = location for ship in self.ships: - result = ship.fire(*location) - if result != "Miss!": - self.field[row][col] = "*" if result == "Hit!" else "x" + result = ship.fire(row, col) + + if result == "Hit!": + self.field[row][col] = "*" return result - # self.field[row][col] = "o" + + if result == "Sunk!": + for deck in ship.decks: + self.field[deck.row][deck.column] = "x" + return result + return "Miss!" def print_field(self) -> None: From 5124dd29ded2777b260b4bb0445934202c8f3bb3 Mon Sep 17 00:00:00 2001 From: Serhii Chumak Date: Fri, 13 Feb 2026 10:28:20 +0200 Subject: [PATCH 5/5] modified third solution py battleshin --- app/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index b754bcaf..fbaae223 100644 --- a/app/main.py +++ b/app/main.py @@ -28,13 +28,13 @@ def __init__(self, def create_decks(start: tuple, end: tuple) -> List[Deck]: decks = [] if start[0] == end[0]: # Horizontal - r = start[0] + first_row = start[0] for col in range(min(start[1], end[1]), max(start[1], end[1]) + 1): - decks.append(Deck(r, col)) + decks.append(Deck(first_row, col)) elif start[1] == end[1]: # Vertical - c = start[1] + first_col = start[1] for row in range(min(start[0], end[0]), max(start[0], end[0]) + 1): - decks.append(Deck(row, c)) + decks.append(Deck(row, first_col)) return decks def fire(self, row: int, column: int) -> str: