Глава 17 · Правила игры

Победа, ничья и terminal state

Заполненное поле — не всегда ничья. Порядок проверки — часть правил игры.

is_draw() — чистая функция

is_draw.py
def is_draw(board):
    winner, _ = find_winner(board)
    return winner is None and all(board)
«Поле заполнено» — недостаточное условие ничьей
Заполненное поле само по себе не гарантирует ничью — если последний ход одновременно выигрывает линию, это ПОБЕДА, а не ничья. Порядок проверки решает всё.

Последний ход: победа побеждает ничью

O
O
X
X
X
O
X
X
O
9-й ход одновременно заполняет поле И выигрывает диагональ 2-4-6.
Обязательное упражнение-предсказание
Прежде чем читать код — предскажите: если 9-й ход заполняет ПОСЛЕДНЮЮ пустую клетку И выстраивает линию, что покажет программа? «Ничья» или «Победа X»? Правильный ответ — «Победа», если find_winner() проверяется РАНЬШЕ is_draw(). Именно поэтому is_draw внутри себя сначала зовёт find_winner и только потом смотрит на заполненность.

Terminal state

ПОБЕДА и НИЧЬЯ — истинные тупики: как только партия туда попала, обратного пути в «игра продолжается» нет. Ниже это показано буквально — у терминальных узлов нет исходящих стрелок.

После валидного ходаfind_winner(board)естьпобедитель?ДАTERMINAL: ПОБЕДА X/OНЕТall(board)заполнено?ДАTERMINAL: НИЧЬЯНЕТигра продолжаетсясменить игрока
ПОБЕДА и НИЧЬЯ — терминальные состояния: партия закончилась и больше не принимает ходов.

Три терминальных результата в реальном окне

X выиграл верхнюю строку
Реальное состояние полной версии: победа X, выигрышная линия подсвечена, поле заблокировано.
O выиграл средний столбец
Реальное состояние полной версии: та же логика find_winner() работает для O.
Полное поле без выигрышной линии, статус Ничья
Реальное состояние полной версии: поле заполнено, победителя нет, дополнительные ходы заблокированы.
Практика: победа против ничьей — порядок проверки
Автоматическая проверка — в том числе тест на «последний ход выигрывает, а не заканчивается ничьей»
Открыть практику →