Читаем Программирование игр и головоломок полностью

Так, на 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. Поведение последовательности.

Речь идет о том, чтобы увидеть, как ведут себя числовые последовательности, порожденные таким образом. Для этого вычислим большое число членов последовательности, порожденной своим первым элементом. Поместим каждый из этих членов в один из 50 интервалов длины 0.02, составляющих интервал от 0 до 1. Выведем число членов последовательности, попавших в каждый из этих интервалов. Если числа из последовательности равномерно распределены в интервале (0, 1), мы должны будем обнаружить, что их количество в разных интервалах имеет ощутимую тенденцию к постоянству.

Составьте программу для проверки зтого утверждения. Начальное значение может, например, вводиться в начале каждого вычисления.

Упражнение 2. Поиск других последовательностей.

Число π, использованное при вычислении наших последовательностей, не обладает никаким специальным свойством, и можно спросить себя, действительно ли выбор этого числа является наилучшим возможным. Числа (x + π)8 довольно велики, а берем мы от них только дробную часть. При этом мы отбрасываем значащие цифры целой части, и — поскольку вычисления на компьютере проводятся с фиксированным количеством значащих цифр — на дробную часть остается относительно небольшое количество цифр. Предположим, что числа представляются с помощью 24 двоичных цифр. Нужно 14 двоичных цифр, чтобы записать 9488, так как

213 = 8192 < 9488 < 214 = 16384

и 17 цифр, чтобы записать 86564, так что остается лишь от 7 до 10 двоичных цифр на дробную часть.

Используя (x + a)8 вместо (x + π)8 с меньшим значением a, можно ожидать сохранения большего количества значащих цифр для дробной части. Но нельзя взять a слишком близко к 1, так как тогда распределение чисел в интервале (0, 1) окажется плохим. Можете ли вы объяснить, почему?

Например, почему нельзя взять a = 8√2?

Если вы сделали упражнение 1, вы располагаете программой для проверки случайных чисел. Измените ее так, чтобы она осуществляла чтение

— постоянной а,

— начального значения последовательности.

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

Азартные игры

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

Упражнение 3. «Орел» или «решка».

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

— она спрашивает вас, что вы загадали, «орла» или «решку», и читает ваш ответ;

— она порождает случайное число и затем сообщает вам, выиграли вы или проиграли.

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ

Эта книга представляет собой перевод третьего издания американского бестселлера Effective C++ и является руководством по грамотному использованию языка C++. Она поможет сделать ваши программы более понятными, простыми в сопровождении и эффективными. Помимо материала, описывающего общую стратегию проектирования, книга включает в себя главы по программированию с применением шаблонов и по управлению ресурсами, а также множество советов, которые позволят усовершенствовать ваши программы и сделать работу более интересной и творческой. Книга также включает новый материал по принципам обработки исключений, паттернам проектирования и библиотечным средствам.Издание ориентировано на программистов, знакомых с основами C++ и имеющих навыки его практического применения.

Скотт Майерс , Скотт Мейерс

Программирование, программы, базы данных / Программирование / Книги по IT