Программирование игр и головоломок - [37]

Шрифт
Интервал

Игра 3.

Единственная трудность в этой программе: перетасовать карты. Я уже упомянул об этом, описывая условия игры. Есть много возможных идей:

— приготовить сначала карточную колоду, затем вытаскивать их из стопки одну за другой. В этом случае у вас будет выбор, как поступать:

либо расположить карты в таблицу в 52 полями, либо создать цепочку ив 52 символов. Но нужно ли это на самом деле? Почему бы не исходить из простой начальной ситуации: упорядоченной таблицы или отсортированной цепочки, затем выбирать элемент этого множества с помощью случайного бросания, вынимать его из множества и повторять процедуру с меньшим количеством элементов.

Если так поступать, то применение таблицы становится тонкой задачей: как изъять элемент из множества?

Его можно изъять «физически». Все элементы, расположенные выше него, спускаются в таблице вниз на одну ступеньку. Это сохраняет порядок оставшихся элементов.

Но нужно ли это? Почему бы, что гораздо проще, не переставить выбранный элемент с последним элементом таблицы в процессе выполнения операции?

Как только мы это обнаружили, становится очевидно, что в перетасовывании карт, исходя из начальной колоды, больше никаких трудностей нет: вы размещаете колоду в упорядоченную таблицу из n карт, вы выбираете случайным образом целое число между 1 и n, вы меняете местами соответствующий элемент с элементом n, затем вы уменьшаете n на единицу и повторяете процедуру.

Элементарно, когда все испробовано!

Игра 4.

Я уже дал все необходимые пояснения, кроме порождения лабиринта. Первую попытку я предпринял со следующим алгоритмом:

— поставить i в начальное положение (правый нижний угол),

— выбрать случайным образом направление перемещения (целое от 1 до 8); если это перемещение невозможно — перейти к следующему перемещению, пока не будет найдено возможное перемещение;

— передвинуть i в соответствии с этим перемещением;

— если i оказался на поле прибытия, то все закончено, в противном случае повторить процедуру.

Опыт показывает, что чаще всего эта программа не останавливается.

Так как есть основное направление перемещения, подлежащее реализации (диагональ игры), то я изменил случайный выбор так, чтобы сделать более частными перемещения влево и вверх или вверх и влево.

Так как у меня еще были и другие задачи, я решил останавливать случайный выбор, когда i оказывается в маленьком прямоугольнике вверху слева. Полученный реестр (сделанный из таблицы или цепочки символов) дает тогда путь, ведущий из каждой из точек этого прямоугольника к полю прибытия.

Остальное просто.

Игра 5.

Эта игра не представляет никаких трудностей. Пусть вы не пытаетесь гарантировать Тони возможность выхода. В программе — никакой стратегии: один ход на два поля, два препятствия на горизонтальной линии на двух свободных полях (вы выбираете клетку случайным образом. Если она или ее соседка справа не свободны, то вы повторяете выбор. Если они свободны — вы их помечаете. Тем хуже для Тони, если он накрыт), два препятствия случайным образом на двух вертикальных полях.

Если вы решили оставить Тони шансы на спасение, действуйте, как в предыдущей программе. Вы случайным образом выбираете путь и обозначаете его так, чтобы никакое препятствие на него сверху не падало. Но вы не выводите на экран этих обозначений.

2. Игры с числами

Головоломка 3.

Я нашел это упражнение в монографии, посвященной языку Пролог. Предложенное там решение действует методом проб и ошибок. Но задача решается намного проще.

Как всегда, полностью определим задачу. Искомое число представляется в десятичной системе последовательностью цифр

c>nc>n−1c>25

Умножая на 5, получаем

5c>nc>n−1c>3c>2

Отсюда следует, что c>2 = 5. Все цифры c>i точно так же итеративно вычисляются справа налево, обыгрывая оставшееся от предыдущего умножения «в уме»: когда вы умножаете крайнее справа 5 на 5, вы получаете 5 единиц, что и дает c>2 = 5, и 2 «в уме». Тогда вы можете вычислить c>3 и новую цифру «в уме» и продолжать шаг за шагом. Остается маленькая задача о том, как узнать, когда следует остановиться. Изучите ее сами; как обычно, я не хотел бы сообщать вам все…

Вы можете также действовать слева направо:

5c>nc>n−1c>3c>2 : 5 = c>nc>n−1c>25

Деля левую цифру на 5, вы получаете c>n = 1. Имея c>n, вы можете продолжать деление. И здесь тоже вам нужно будет принимать во внимание перенос результата, полученного при предыдущем делении, и нужно будет знать, когда остановиться. Эти два метода по существу равносильны.

Остальное оставляю исследовать вам.

Головоломка 4.

Обычно я бываю глубоко разочарован тем, что нахожу в книгах по информатике или по математике касательно квадратных корней. Чаще всего вам предлагают метод Ньютона: пусть вам нужно извлечь квадратный корень из числа x. Вы образуете возвратную последовательность u>i по правилу

u>i+1 = (u>i + (x/u>i))/2.

Вне всякого сомнения, вы можете взять u>0 = 1 в качестве начального значения. Эта последовательность очень быстро сходится к квадратному корню из x. Если, например, взять x = 50 и воспользоваться формулой

u>i+1 = целая_часть ((u>i + (x/u>i))/2),

чтобы иметь дело только с целыми числами, то в качестве последовательных значений и вы получите


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.