Программирование >>  Структурное программирование 

1 ... 65 66 67 [ 68 ] 69 70 71 ... 342


который присваивает переменной face целое (и случайное) значение в диапазоне 1 < face < 6. Заметим, что ширина этого диапазона (т.е. число последовательных целых значений, расположенных в нем) равна 6, а начало диапазона равно 1. Обращаясь к предыдущему оператору, мы видим, что ширина диапазона определяется числом, используемым для масштабирования rand с помощью операции вычисления остатка (т. е. 6), а начало диапазона равно числу, которое прибавляется к rand % 6 (т. е. 1). Мы можем записать этот результат в общем виде:

п = а + rand() % b;

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

Типичная ошибка программирования 3.12

Использование srand вместо rand для генерации случайных чисел.

3.9. Пример: азартная игра

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

Игрок бросает две кости. Каждая кость имеет шесть граней. Эти грани помечены как 1, 2, 3, 4, 5 и 6. После броска вычисляется сумма цифр двух верхних граней. Если сумма после первого броска равна 7 или 11, игрок выиграл. Если после первого броска сумма равна 2, 3 или 12 (это называется крепе ), игрок проигрывает (т. е. выигрывает банк ). Если после первого броска сумма равна 4, 5, 6, 8, 9 или 10, то эта сумма становится очками игрока. Чтобы выиграть, игрок должен продолжать бросать кости до тех пор, пока не выпадет сумма, равная его очкам. Игрок проигрывает, если во время этих бросков ему выпадет сумма 7.

Программа на рис. 3.10 моделирует игру крепе. На рис 3.11 показано несколько примеров ее выполнения.

Заметим, что игрок должен бросать каждый раз по две кости. Мы описали функцию roUDice, которая имитирует бросок костей, подсчитывает выпавшую сумму и печатает ее. Функция roUDice описана один раз, но она вызывается из двух мест программы. Интересно, что rollDice не требует аргументов, поэтому в списке параметров мы указали void. Функция roUDice возвращает сумму двух костей, возвращаемый тип int указывается в заголовочном файле.

Игра разумно запутана. Игрок может выиграть или проиграть после первого же броска или после серии бросков. Переменная gameStatus используется для запоминания состояния игры. Переменная gameStatus объявлена как имеющая тип с именем Status. Строка

enum Status { CONTINUE, WON, LOST );

объявляет определенный пользователем тип, называемый перечислимым (enumeration). Перечислимый тип, вводимый ключевым словом enum перед именем



типа (в нашем случае Status), является набором целых именованных констант, представленных своими идентификаторами. Значения констант этого списка перечисления начинаются, если не указано иное, с О и увеличиваются последовательно на 1. В предыдущем списке перечисления имя CONTINUE присвоено значению О, WON присвоено значению 1, а LOST - значению 2. Идентификаторы в enum должны быть уникальными, но отдельные константы перечисления могут иметь одинаковые целые значения.

Крепе

#include <iostream.h>

#include <stdlib.h>

tinclude <time.h>

int rollDice(void);

main() {

enum Status { CONTINUE, WON, LOST }; int sum, myPoint; Status gameStatus;

srand(time(NULL)); sum = rollDice 0;

switch(sum) {

case 7: case 11:

gameStatus = WON; break;

case 2: case 3: case 12:

gameStatus = LOST;

break; default:

gameStatus = CONTINUE; myPoint = sum;

cout Очки: myPoint endl; break;

первый бросок костей выигрьш после первого броска проигрыш после первого броска запоминание очков

while (gameStatus == CONTINUE) sum = rollDice О;

if (sum == myPoint) gameStatus = WON;

else

if (sum == 7)

gameStatus = LOST;

[ бросать дальше

выигрыш по очкам проигрыш после суммы 7

if (gameStatus == WON)

cout << Игрок выиграл << endl;

else

cout << Игрок проиграл endl; return 0;

Рис. 3.10. Программа моделирования игры в крепе (часть 1 из 2)



, it

в

int rollDice(void) (

int diel, die2, workSiom;

diel = 1 + randO % 6; die2 = 1 + randO % 6; workSum = diel + die2;

cout Бросок игрока diel + die2 = workSum endl;

return workSum;

Рис. 3.10. Программа моделирования игры в крепе (часть 2 из 2)

Бросок игрока б + 5 = 11 Игрок выиграл

Бросок игрока б + 6 = 12 Игрок проигрёш

Бросок игрока 4 + 6 = 10 Очки: 10

Бросок игрока 2+4=6

Бросок игрока б + 5 = 11 Бросок игрока 3+3=6

Бросок игрока 6 + 4 = 10 Игрок выиграл

Бросок игрока Очки: 4 Бросок игрока Бросок игрока Бросок игрока Бросок игрока Бросок игрока Бросок игрока - Игрок проиграл

Рис. 3.11. Примеры прогонов игры в крепе Хороший стиль программирования 3.8

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

Переменным типа Status, определенного пользователем, может быть присвоено только одно из трех значений, объявленых в перечислении. Если игра выиграна, gameStatus принимает значение WON. Если игра проиграна, gameStatus устанавливается равной LOST. В ином случае gameStatus принимает значение CONTINUE, так что кости могут быть брошены снова.

Типичная ошибка программирования 3.13

Присвоение целого эквивалента константы перечисления переменной перечислимого типа приводит к замечанию (предупреждению) компилятора.



1 ... 65 66 67 [ 68 ] 69 70 71 ... 342

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика