Rozdział 17 · Zasady gry

Osiem linii płatnych

Trzy wiersze, trzy kolumny, dwie przekątne i jedna czysta funkcja, która sprawdza je wszystkie.

Wszystkie osiem linii płatnych

Strings

X
X
X
Linia 1
X
X
X
Linia 2
X
X
X
Linia 3

Kolumny

X
X
X
Kolumna 1
X
X
X
Kolumna 2
X
X
X
Kolumna 3

Diagonale

X
X
X
Diagonala 0-4-8
X
X
X
Przekątna 2-4-6

Ciągłe WINNING_LINES

winning_lines.py
WINNING_LINES = (
    (0, 1, 2), (3, 4, 5), (6, 7, 8),  # Linie
    (0, 3, 6), (1, 4, 7), (2, 5, 8),  # kolumny
    (0, 4, 8), (2, 4, 6),             # przekątne
)
WIELKĄ LITERĄ to dane reguły, a nie algorytm
WINNING_LINES jest zapisane wielkimi literami: tak nazywa się stałe modułu w Python (umowa PEP 8 to umowa między programistami, a nie zakaz zmiany przez interpretera). Są to dane dotyczące zasad gry, oddzielne od kodu, który je używa. find_winner() sam w sobie nie wie o rozmiarze 3×3 — po prostu przegląda gotowe linie. Ale stała nie rozwiązuje wszystkiego: arytmetyka indeksów (// 3, % 3), długość [""] * 9 a sama siatka 3×3 widżetów też jest sztywno ustalona względem rozmiaru pola — rzeczywiste wsparcie innego rozmiaru wymagałoby zmiany całego tego układu, a nie tylko WINNING_LINES.

find_winner() jest czystą funkcją

find_winner.py
def find_winner(board):
    for a, b, c in WINNING_LINES:
        mark = board[a]
        if mark and mark == board[b] == board[c]:
            return mark, (a, b, c)
    return None, None
Returns Zarówno zwycięzca, jak i sama linia
Rozdział 17.5 zwracał tylko zwycięzcę. find_winner() odwzajemnia parę (winner, winning_line) — indeksy linii są potrzebne, aby ją podkreślić (sekcja 17.25) bez konieczności ponownego obliczania zwycięzcy.
Nic nie wie o Tkinter
find_winner(board) stosuje zwykłe lista — bez guzików, bez root. To właśnie sprawia, że cecha jest testowalna bez żadnego otwartego okna (Rozdział 17.28).
Praktyka: find_winner dla wszystkich ośmiu linijek
Automatyczny sprawdzenie – find_winner na każdej z ośmiu linii dla X i O
Otwórz praktykę →