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

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

Часть I. Условия задач

1. Случайные числа

Генерация случайного числа

Можно сделать из этого настоящую головоломку: написать программу, выполнение которой на компьютере дает число, случайным образом расположенное в данном интервале, например, между 0 и 1. Но это невозможно.

Некоторые языки содержат функцию, значение которой есть непредсказуемое число в данном интервале. Если ваш компьютер использует LSE, достаточно набрать на клавиатуре

>? ALE(0)

чтобы получить в ответ непредсказуемое число между 0 и 1, которое может рассматриваться как полученное случайным образом.

На языке Бейсик команда RND(0) дает тот же эффект при условии, что предварительно выполнена инструкция RANDOM. Но Бейсик — это скорее общее имя для целого класса языков, чем обозначение совершенно определенного стандартизованного языка, не меняющегося от одной машины к другой. Так что сверьтесь с описанием к вашему компьютеру…

Если используемый вами язык допускает описанные выше или аналогичные возможности, то получить случайное число в интервале (0, 1) — это никакая не головоломка, это тривиально.

Но если в языке такой возможности нет,>; то это больше чем головоломка, это невозможно. Предположим, что мы сделали программу, производящую такое число. Эта программа не может иметь исходных данных, иначе это не она вытаскивает, случайное число, а именно вы при введении данных… Если же у нее нет данных, то она действует, исходя из констант. Но тогда нет переменных элементов, и последовательные запуски программы дают совпадающие результаты. Как же вы получите с помощью такой программы случайное число?[2]

Поэтому если ваш компьютер не допускает функции, дающей стохастическое число, я вижу только одно решение[3]: введите сами случайное число в ваш компьютер. Как это сделать? Вот предложение. Вы берете колоду из 52 карт, перетасовываете. Затем вы делите колоду на верхнюю и нижнюю части и берете из нижней части три верхние карты. Небольшая и очень простая программа читает три целых числа x, y, z. В качестве значений этих целых чисел вы задаете численные значения трех выбранных карт, считая туза за 1, валета — за 11, даму — за 12, короля — за 13. Компьютер вычисляет значение

(((x − 1)/13 + у − 1)/13 + z − 1)/13.

Например, если вы достанете, как только что случилось со мной, семерку бубен, десятку червей и еще шестерку бубен, то

x =7 y= 10 z = 6

и компьютер получит 0.440601.

Эго значение не является воистину непредсказуемым. Как только вы достанете карты, вы уже сможете понять порядок величины результата. С другой стороны, таким способом вы не сможете получить более 13³ = 2197 различных чисел. Но этого на самом деле достаточно для приложений, которые мы рассматриваем в этой книге. А если вы и в самом деле хотите получить что-либо непредсказуемое, прочтите следующий раздел.

Непредсказуемые числовые последовательности

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

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

Может случиться, что используемый вами язык предоставляет эту возможность непосредственно в виде одной из конструкций языка.

Так, на LSE команда ALE(x) дает число, лежащее в интервале (0, 1), значение которого зависит от x, но непредвиденным образом и, кроме того, не специфицированным в языке: значение будет различным на разных машинах. Если вы трижды зададите один и тот же вопрос

>? ALE (0.1)

вы каждый раз получите один и тот же ответ, но между ALE(0.1) и ALE(0.2) нет простого соотношения.

На Бейсике функция RND играет ту же самую роль. Она порождает непредсказуемую последовательность, значения которой зависят только от начального числа — оно одно и то же для данного компьютера. Инструкция RANDOM дает случайное число и ставит его начальным элементом последовательности, что позволяет порождать различные последовательности.

Может быть, интересно посмотреть, как можно строить подобные последовательности. Вот метод, предложенный А. Энгелем [ENG]. Если x — число между 0 и 1, то следующий за x элемент последовательности есть

дробная часть ((x + 3.14159)>8)

Конечно, восьмая степень вычисляется тремя последовательными возведениями в квадрат! Она дает число между 9488 (для x = 0) и 86564. Очень небольшое изменение x вызывает сильное изменение (x + π)>8, и, в частности, оно может перейти через ближайшее целое, так что новое значение (дробная часть результата) может оказаться меньше предыдущей.

Возьмем, например, x = 0.52000; тогда

(x + 3.14159)>8 = 32311.5437

так что за 0.5200 следует 0.5437.

Но для x = 0.52005 имеем

(x + 3.14159)>8 = 32315.0736

и за 0.52005 следует 0.0736.

Так как мы берем дробную часть, то полученное число, разумеется, лежит между 0 и 1.

Упражнение 1. Поведение последовательности.


Рекомендуем почитать
Язык PL/SQL

В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.


Java 7

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


Системное программное обеспечение. Лабораторный практикум

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


Программирование на языке Пролог для искусственного интеллекта

Книга известного специалиста по программированию (Югославия), содержащая основы языка Пролог и его приложения для решения задач искусственного интеллекта. Изложение отличается методическими достоинствами — книга написана в хорошем стиле, живым языком. Книга дополняет имеющуюся на русском языке литературу по языку Пролог.Для программистов разной квалификации, специалистов по искусственному интеллекту, для всех изучающих программирование.


Программирование на Visual C++. Архив рассылки

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.


Язык программирования С# 2005 и платформа .NET 2.0.

В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML.