Сложнее всего было реализовать кодирование слова. В Unix нет удобных утилит для этого, но, оказывается, слово можно закодировать непредсказуемым способом, если выполнить последовательный перебор букв в нем и случайно добавлять каждую следующую букву в начало или в конец закодированной последовательности
.
Обратите внимание на местоположение $scrambled в двух строках: в первой следующая буква добавляется в конец $scrambled, а во второй — в начало.
В остальном логика игры должна быть понятна: внешний цикл until
выполняется, пока пользователь не введет слово quit в качестве ответа, а внутренний цикл while
выполняется, пока пользователь не угадает слово или не введет next, чтобы перейти к следующему слову.
Этот сценарий не имеет аргументов, так что просто введите его имя в командной строке и начните игру!
После запуска сценарий выводит закодированные слова разной длины и подсчитывает количество слов, угаданных пользователем, как показано в листинге 12.2.
Листинг 12.2.Запуск игрового сценария unscramble
$ unscramble
Picked out a word!
You need to unscramble: ninrenoccg
Your guess (quit|next): concerning
*** You got it with tries = 1! Well done!! ***
Picked out a word!
You need to unscramble: esivrmipod
Your guess (quit|next): quit
The unscrambled word was "improvised". Your tries: 0
Done. You correctly figured out 1 out of 2 scrambled words.
Первая же попытка оказалась успешной, и это вдохновляет!
Усовершенствование сценария
Вывод подсказки, хоть в каком-нибудь виде, сделал бы игру более интересной, также пригодился бы флаг, позволяющий ограничивать минимальную длину слова. В первом случае можно было бы за определенные штрафные очки показывать первые n букв из исходного слова и в ответ на каждый запрос подсказки добавлять еще одну букву. Для второго случая необходимо расширить словарь, так как предлагаемый вместе со сценарием содержит слова не короче 10 букв — хитро!
№ 84. Виселица: угадай слово, пока не поздно
Несмотря на жутковатую идею, игра в «виселицу» давно стала классикой. Вы пытаетесь угадать, какие буквы есть в задуманном слове, и каждый раз, когда вы ошибаетесь, у человечка на виселице дорисовывается очередная часть тела. Когда ошибок оказывается слишком много, появляется полное изображение, что означает проигрыш и… как вы понимаете, смерть человечка. Довольно безжалостная игра!
Однако сама по себе игра довольно забавная, а ее реализация в виде сценария командной оболочки оказывается на удивление простой, как демонстрирует листинг 12.3. Вам также потребуется список слов, использовавшийся в сценарии № 83: сохраните файл long-words.txt из ресурсов книги в каталоге /usr/lib/games .
Листинг 12.3.Игровой сценарий hangman
#!/bin/bash
# hangman — простая версия игры "виселица". Вместо постепенного рисования
#·· человечка он просто ведет обратный отсчет ошибочных попыток.
#·· В единственном необязательном аргументе сценарий принимает начальное
#·· расстояние до эшафота.
wordlib="/usr/lib/games/long-words.txt"
empty="\." # Нам нужно что-то для sed [set], когда $guessed="".
games=0
# Сначала проверить наличие библиотеки слов — файла wordlib.
if [! -r "$wordlib"]; then
··echo "$0: Missing word library $wordlib" >&2
··echo "(online: http://www.intuitive.com/wicked/examples/long-words.txt" >&2
··echo "save the file as $wordlib and you're ready to play!)" >&2
··exit 1
fi
# Большой цикл while. Здесь все и происходит.
while ["$guess"!= "quit"]; do
··match="$(randomquote $wordlib)" # Выбрать новое слово из библиотеки.
··if [$games −gt 0]; then
····echo ""
····echo "*** New Game! ***"
··fi
··games="$(($games + 1))"
··guessed=""; guess=""; bad=${1:-6}
··partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"
··# В этом блоке производится:
··#·· ввод буквы > анализ > вывод результатов > переход к началу.
··while ["$guess"!= "$match" −a "$guess"!= "quit"]; do
····echo ""
····if [! -z "$guessed"]; then·· #! —z означает "непустое значение".
······/bin/echo −n "guessed: $guessed, "
····fi
····echo "steps from gallows: $bad, word so far: $partial"
····/bin/echo −n "Guess a letter: "
····read guess
····echo ""
····if ["$guess" = "$match"]; then # Угадано!
······echo "You got it!"
Читать дальше