Выбрать главу

Суть игры проста. Раздаются две карты, и игрок пытается угадать: окажется ли числовое значение третьей в промежутке значений этих двух. Затем вскрывается третья карта. Масть не важна; важны достоинства карт и их комбинации. То есть если выпали шестерка червей и девятка треф, а третья выпавшая карта — шестерка бубен, комбинация проигрышная. Четверка пик тоже даст проигрышную комбинацию, а семерка треф — выигрышную.

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

Сценарий обещает быть интересным. Готовы? Тогда переходите к листингу 12.14.

Код

Листинг 12.14. Игровой сценарий aceydeucey

··#!/bin/bash

··# aceyduecey: Дилер выкладывает две карты, и вы должны угадать, попадает ли

··#·· числовое значение следующей карты в колоде между значениями этих двух

··#·· карт. Например, выпали 6 и 8, если следующая карта окажется 7, вы выиграли

··#·· если 9 — проиграли.

··function initializeDeck

··{

····# Создать колоду карт.

····card=1

····while [$card −le 52] # 52 карты в колоде. Вы это знаете, правда?

····do

······deck[$card]=$card

······card=$(($card + 1))

····done

··}

··function shuffleDeck

··{

····# Это не настоящее перемешивание. Это случайное извлечение значений карт

····#·· из массива 'deck' и создание массива newdeck[], представляющего

····#·· "перемешанную" колоду.

····count=1

····while [$count!= 53]

····do

······pickCard

······newdeck[$count]=$picked

······count=$(($count + 1))

····done

··}

··function pickCard

··{

····# Это самая интересная функция: выбор случайной карты из колоды.

····#·· Поиск карты осуществляется в массиве deck[].

····local errcount randomcard

····threshold=10 # Максимальное число попыток, прежде чем признать неудачу

····errcount=0

····# Выбирает из колоды случайную карту, которая еще не была выбрана,

····#·· выполняя не более $threshold попыток. В случае неудачи (чтобы

····#·· избежать зацикливания, когда раз за разом выполняется попытка

····#·· извлечь уже извлеченную карту) выполняется переход к запасному

····#·· варианту.

····while [$errcount −lt $threshold]

····do

······randomcard=$((($RANDOM % 52) + 1))

······errcount=$(($errcount + 1))

······if [${deck[$randomcard]} −ne 0]; then

········picked=${deck[$randomcard]}

········deck[$picked]=0 # Выбрали — удалить ее.

········return $picked

······fi

····done

····# Если сценарий оказался здесь, значит, он не смог выбрать случайную карту,

····#·· поэтому дальше просто продолжается последовательный обход массива

····#·· до обнаружения первой доступной карты.

····randomcard=1

····while [${newdeck[$randomcard]} −eq 0]

····do

······randomcard=$(($randomcard + 1))

····done

····picked=$randomcard

····deck[$picked]=0 # Выбрали — удалить ее.

····return $picked

··}

··function showCard

··{

····# Функция использует операции деления и взятия остатка для определения

····#·· масти и достоинства, хотя в этой игре значение имеет только достоинство.

····#·· Однако для представления важно иметь полную информацию.

····card=$1

····if [$card −lt 1 −o $card −gt 52]; then

······echo "Bad card value: $card"

······exit 1

····fi

····# деление и взятие остатка — школьные годы не были потрачены впустую!

····suit="$(((($card — 1) / 13) + 1))"

····rank="$(($card % 13))"

····case $suit in

······1) suit="Hearts"··;;

······2) suit="Clubs"····;;