Глава 17 · Правила игры
Восемь выигрышных линий
Три строки, три столбца, две диагонали — и одна чистая функция, которая их все проверяет.
Все восемь выигрышных линий
Строки
X
X
X
X
X
X
X
X
X
Столбцы
X
X
X
X
X
X
X
X
X
Диагонали
X
X
X
X
X
X
Константа WINNING_LINES
winning_lines.py
WINNING_LINES = (
(0, 1, 2), (3, 4, 5), (6, 7, 8), # строки
(0, 3, 6), (1, 4, 7), (2, 5, 8), # столбцы
(0, 4, 8), (2, 4, 6), # диагонали
)
ЗАГЛАВНЫМИ — это данные правил, а не алгоритм
WINNING_LINES написана ЗАГЛАВНЫМИ буквами: так в Python принято называть константы модуля (соглашение PEP 8 — договорённость между программистами, а не запрет интерпретатора на изменение). Это данные о правилах игры, отдельные от кода, который их использует. find_winner() сам по себе не знает о размере 3×3 — он просто перебирает готовые линии. Но константа решает не всё: индексная арифметика (// 3, % 3), длина [""] * 9 и сама 3×3-сетка виджетов тоже жёстко зашиты на размер поля — реальная поддержка другого размера потребовала бы менять всё это, а не только WINNING_LINES.find_winner() — чистая функция
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
Возвращает И победителя, И саму линию
Раздел 17.5 возвращал только победителя.
find_winner() возвращает пару (winner, winning_line) — индексы линии нужны, чтобы подсветить именно её (раздел 17.25), не пересчитывая победителя заново.Ничего не знает про Tkinter
find_winner(board) принимает обычный список строк — никаких кнопок, никакого root. Это то, что делает функцию тестируемой без единого открытого окна (раздел 17.28).Практика: find_winner для всех восьми линий
Автоматическая проверка — find_winner на каждой из восьми линий для X и O