Программирование игр и головоломок
Шрифт:
Ничего нового с точки зрения программирования, за исключением того, что нужно исследовать восемь направлений перемещения вместо четырех.
4. Игры со стратегией
Игра 16. Числа Спрага-Грюнди
В большинстве нижеследующих игр два игрока делают ходы по очереди, и выигрывает тот, кто достигает некоторой намеченной в начале игры позиции. В той игре, которую мы обсуждаем сейчас, позиция может быть полностью охарактеризована числом оставшихся спичек, и выигрывающая позиция соответствует числу спичек, равному нулю. Спраг и Грюнди предложили (соответственно в 1936 и 1939 годах) связывать с каждой игровой позицией неотрицательное целое число следующим образом:
— выигрывающей позиции вы сопоставляете 0;
—
Образуем числа Спрага-Грюнди для этой игры.
Позиции 0 сопоставляется число 0, SG (0) = 0.
Исходя из 1, можно получить 0 (поскольку мы имеем право удалить одну спичку [19] . Следовательно, SG(1) — наименьшее неотрицательное целое, отличное от 0, или SG(1) = 1. Исходя из 2, можно получить 1 и 0. Следовательно, SG(2) — наименьшее неотрицательное целое, отличное от 0 и 1, поэтому SG(2) = 2.
19
Важно и то, что никаких других позиций, кроме 0, из 1 получить нельзя. — Примеч. ред.
Так как можно удалять спички вплоть до 6, то точно так же имеем
SG(3) = 3, SG(4) = 4, SG(5) = 5, SG(6) = 6.
Предположим теперь, что имеется 7 спичек. Можно удалить от 1 до 6. Поэтому в результате можно получить от 6 до 1 спичек, но не 0. Число SG(7) — наименьшее неотрицательное целое, отличное от 1, 2, 3, 4, 5, 6, Следовательно, это 0.
SG(7) = 0,
А теперь из 8 можно получить от 2 до 7, поэтому SG(8) — это не 2, не 3, …, не 6 и не 0, поэтому оно равно 1.
SG(8) = 1.
Теперь вы можете установить общий закон:
SG(p) = остаток от деления p на 7.
Как же выигрывать?
Если вы после своего хода можете оставить кучу, для которой число Спрага-Грюнди равно 0, то ваш противник не сможет достичь ситуации с числом нуль, поскольку по определению число, которое он оставит, отлично от исходного числа. Поскольку он не сможет достичь ситуации p с SG (p) = 0, то он и не может выиграть. Ему придется оставить вам ситуацию с SG(p) /= 0, исходя из которой, вы всегда сможете получить ситуацию с числом Спрага-Грюнди, равным нулю. Следовательно, вам нужно оставлять вашему противнику число спичек с числом SG, равным нулю, иначе говоря, число спичек, кратное 7.
Одно из двух: либо ваш противник не знает этого правила и играет «по нюху»; при первой возможности вы оставляете ему кратное 7 и из ежовых рукавиц не выпускаете; либо он знает правило и ходит первым: он достигает кратного 7. Вы не сможете выиграть, если он не рассеян или не сделает ошибки в счете. Но компьютер не рассеян и не делает ошибок в счете (если ваша программа верна)…
Игра 17.
Выигрывающее положение — 31 декабря. Возьмите листок бумаги в клетку. Расположите по абсциссе месяцы, а по ординате дни. Так как 31 декабря выигрывает, то вы обозначаете эту точку числом Спрага-Грюнди 0. Из каждого дня декабря можно получить 31, но также и любой другой последующий день. Поэтому вы приписываете значение 1 дате 30 декабря, значение 2 дате 29 декабря, и т, д. То же для любого 31 числа; из него можно получить 31 число всех последующих месяцев. Поэтому 31 октября получает 1, 31 августа 2 и т. д.
После этого вы можете закончить значение таблицы и приписать число Спрага-Грюнди всем дням года. Вы увидите также появление дней со значением 0, которые являются выигрывающими днями. Напоминаю вам правило: каждому игровому положению приписывается наименьшее неотрицательное целое значение, отличное от значений тех положений, которые можно получить, исходя из данного, т. е. в настоящем случае — от значений тех положений, которые расположены правее, и тех, которые расположены ниже.
Закон заполнения
Даже если вы мало знаете современную математику, вы слышали разговоры об отношении эквивалентности. Все выигрывающие положения эквивалентны. Игровое положение задается парой д, м, где д — номер дня, а м — номер месяца. Следовательно, вы должны найти такое отношение эквивалентности для пар натуральных чисел, чтобы
д, м' было не эквивалентно д, м при м /= м', и
д', м было не эквивалентно д, м при д /= д'.
Наконец, для выигрывающей позиции д, м должно быть эквивалентно 31, 12. Что-то похожее на это можно видеть в программах лицеев…
Я прекрасно понимаю, что календарь осложняет все, поскольку длина месяца не постоянна и зависит от м, причем к тому же с непростым законом изменения. Но, к счастью, оказывается, что это никак не сказывается на этом замечательном отношении эквивалентности.
После всего сказанного вы должны выпутаться из этой задачи…
Игра 18.
Эта игра — производная от средневековой игры. Сначала попытайтесь достичь 50 с точностью до кратного 7. Но как только все четыре карты, имеющие одинаковое значение, оказываются использованными, так ситуация сразу меняется. Вот пример начала партии,
Я беру туза, компьютер тоже. Сумма 2.
Чтобы получить 8, я беру 6. Компьютер берет туза. Сумма 9.
Чтобы получить 15, я снова беру 6.
Компьютер берет последнего туза. Сумма 16,
Теперь остаются следующие карты:
2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6
Так как тузов больше нет, то числа Спрага-Грюнди изменились [20] . Теперь из 49 больше нельзя получить 50.
SG(50) = 0, SG(49) = 0.
Из (48) можно получить 50. Поэтому SG(48) = 1.
Из 47 можно получить 49 и 50, но не 48. Поэтому SG(47) = 1.
Теперь положения, имеющие нулевое SG, — это
42 41 34 33 26 25 18 17
20
Читатель может вернуться к определению чисел Спрага-Грюнди и убедиться, что эти числа определяются на множестве игровых позиций раз и навсегда, исходя из правил игры, и, разумеется, не могут меняться в процессе разыгрывания конкретной партии. Что же является позицией в этой средневековой игре? — Позицией является состав выложенных на стол карт, а также их значения: сколько карт на столе имеет значение 1, сколько карт имеет значение 2, и т. д. Сумма, набранная игроками в данный момент, равна 84 минус сумма значений карт на столе. Что же имеет в виду автор книги, когда он пишет SG(50)? Почему он приписывает число Спрага-Грюнди не позиции, а сумме карт этой позиции? Дело в том, что для всех позиций с набранной суммой 50 число Спрага-Грюнди одинаково и равно 0. Это и позволяет написать равенство SG(50) = 0. А что могло бы значить SG(49)? Если бы все позиции с суммой 49 имели одинаковое число SG, мы бы обозначили его SG(49). Но, увы! Разные позиции с суммой 49 имеют разные числа Спрага-Грюнди. Так что автор книги дальше рассуждает о несуществующих вещах. Я из этих рассуждений ничего полезного извлечь не смог (кроме подозрения, что у автора нет работающей программы, играющей в 24 карты). — Примеч. ред.