Zpět na domů

Knihovna Mořské bitvy v Pythonu: třídy Field a Ship

Článek rozebírá vytvoření knihovny logiky Mořské bitvy v Pythonu. Jsou popsány třídy Field a Ship, metody validace souřadnic, umístění lodí a typické chyby. Uvedeny příklady kódu a doporučení k refaktoringu pro optimální architekturu.

Vytvoření knihovny Mořské bitvy: Field a Ship v Pythonu
Advertisement 728x90

Vývoj knihovny logiky hry Lodě v Pythonu: architektura a typické chyby

Knihovna implementuje logiku klasické hry Lodě s důrazem na matematicky optimální algoritmy. Hlavní třídy jsou Field pro reprezentaci herního pole a Ship pro správu lodí. Pole je uloženo jako matice 10x10 se seznamy seznamů, kde symboly označují stavy: mezera — prázdné políčko, '1' — živá část lodi, '.' — minutí, 'X' — zničené políčko.

Třída Field zodpovídá za vytvoření hrací desky, validaci souřadnic, umístění lodí a zpracování výstřelů. Souřadnice se zadávají ve formátu 'a1', kde písmena A-J odpovídají řádkům, čísla 1-10 — sloupcům. Pravidla jsou pevná: 1 loď 4-políčková, 2 třípolíčkové, 3 dvoupolíčkové, 4 jednopolíčkové; lodě se nedotýkají ani rohy.

Implementace třídy Field

Inicializace vytvoří prázdnou mřížku:

Google AdInline article slot
class Field:
    def __init__(self):
        height = 10
        width = 10
        self.grid = [[' ' for i in range(width)] for i in range(height)]

Metoda display() vypíše pole do konzole se souřadnicemi. První verze obsahovala chybu — metoda line.insert(0, letter) mutovala původní grid, přidávala písmena při opakovaných voláních. Oprava: tisk písmena zvlášť bez změny struktury.

def display(self):
    print('  1 2 3 4 5 6 7 8 9 10')
    letters = 'ABCDEFGHIJ'
    count_letters = 0
    for line in self.grid:
        print(letters[count_letters], *line)
        count_letters += 1

Validace souřadnic je vyčleněna do privátní metody _validation_coordinate(). Kontroluje délku řetězce (2-3 znaky), přítomnost písmena v A-J a čísla v 1-10. Metoda find_coordinate() určuje stav políčka: clear, hitted, destroyed, not_damaged, was_beaten.

Slovníky pro převod souřadnic jsou uloženy jako atributy self.rows a self.columns:

Google AdInline article slot
  • rows: {'a': 0, 'b': 1, ..., 'j': 9}
  • columns: {'1': 0, '2': 1, ..., '10': 9}

Třída Ship a umístění lodí

Třída Ship ukládá parametry ve slovníku:

class Ship:
    def __init__(self):
        self.parameters = {
            'alive coordinates': [],
            'hitted coordinates': [],
            'alive': True
        }
        self.field = None
    def set_field(self, field):
        self.field = field

Metoda add_ship(ship, coordinate_line, length) v Field umístí loď podle řetězce typu 'a1-a2-a3'. Nejprve validace linie _ship_line_validation(): rozklad na souřadnice, kontrola linearity (horizontální/vertikální), shoda délky. Poté pro každou souřadnici volání ship.set_coordinate_in_ship(coordinate), nastavení '1' v grid.

def add_ship(self, ship, coordinate_line, length):   
    ship.set_field(self)
    if not self._ship_line_validation(coordinate_line):
        return False
    coordinates = coordinate_line.split('-')   
    if length != len(coordinates):
        return False
    for coordinate in coordinates:
        result = ship.set_coordinate_in_ship(coordinate)
        if result:
            rows = self.rows[coordinate[0]]
            columns = self.columns[coordinate[1:]]
            self.grid[rows][columns] = '1'
    return True

Vazba Field-Ship je obousměrná: Field volá ship.set_field(self), Ship používá self.field pro validaci. To porušuje princip zapouzdření základních vrstev, ale zjednodušuje API.

Google AdInline article slot

Závěry k refaktoringu

Projekt odhalil klíčové problémy začátečníků:

  • Přetížení metod: find_coordinate() kombinoval validaci, hledání a výstup — rozdělit na _validation_coordinate() a get_cell_state().
  • Mutace dat: Vyhnout se insert() v display(), pracovat s kopiemi.
  • Pevně zakódované slovníky: Vyčlenit do třídních konstant nebo použít ord() pro převody.
  • Návratové hodnoty: Sjednotit: True/False pro úspěch, řetězce pro chyby.

Pro optimální hru integrovat algoritmy pravděpodobnostního hledání: při zásahu skenovat sousední políčka, při zničení — vyloučit paluby z pravděpodobností.

Co je důležité

  • Field jako matice seznamů se symboly pro stavy; validace souřadnic přes slovníky self.rows/self.columns.
  • Ship ukládá alive/hitted coordinates; obousměrná vazba s Field přes set_field().
  • Umístění podle coordinate_line ('a1-a2'); kontrola linearity a nárazníkových zón.
  • Vyhnout se mutaci grid v display(); vyčleňovat společné kontroly do privátních metod.
  • Pro pokročilé algoritmy: ukládat pravděpodobnostní mapu výstřelů odděleně od grid.

— Editorial Team

Advertisement 728x90

Číst dál