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

····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!"

····elif ["$guess" = "quit"]; then # Запрошен выход? Хорошо.

······exit 0

····# Теперь нужно проверить присутствие введенной буквы в слове.

····elif [$(echo $guess | wc −c | sed 's/[^[: digit: ]]//g') −ne 2]; then

······echo "Uh oh: You can only guess a single letter at a time"

····elif [! -z "$(echo $guess | sed 's/[[: lower: ]]//g')"]; then

······echo "Uh oh: Please only use lowercase letters for your guesses"

····elif [-z "$(echo $guess | sed "s/[$empty$guessed]//g")"]; then

······echo "Uh oh: You have already tried $guess"

····# Теперь можно проверить присутствие буквы в слове.

····elif ["$(echo $match | sed "s/$guess/-/g")"!= "$match"]; then

······guessed="$guessed$guess"

······partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"

······if ["$partial" = "$match"]; then

········echo "** You've been pardoned!! Well done! The word was \"$match\"."

········guess="$match"

······else

········echo "* Great! The letter \"$guess\" appears in the word!"

······fi

····elif [$bad −eq 1]; then

······echo "** Uh oh: you've run out of steps. You're on the platform…"

······echo "** The word you were trying to guess was \"$match\""

······guess="$match"

····else

······echo "* Nope, \"$guess\" does not appear in the word."

······guessed="$guessed$guess"

······bad=$(($bad — 1))

····fi

··done

done

exit 0

Как это работает

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

Почему в сравнении используется число 2, а не 1? Потому что к предложенной пользователем букве в результате нажатия клавиши Enter добавляется символ перевода строки (\n). То есть правильно, когда строка содержит два символа, а не один. Команда sed в этой инструкции отбрасывает все нецифровые символы, чтобы исключить любые проблемы с начальными символами табуляции, которые так любит добавлять команда wc.

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

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

Кроме всех этих проверок в сценарии hangman используется еще одна хитрость: в исходном слове все буквы, совпадающие с введенной, заменяются дефисами. Затем результат сравнивается с исходным словом . Если они различаются (то есть если одна или несколько букв заменены дефисами), значит, предложенная пользователем буква есть в слове. Например, если для загаданного слова cat пользователь ввел букву a, она будет записана в переменную guessed, которая получит значение '-a-'.

Одна из ключевых идей, лежащих в основе сценария hangman, — вывод частично угаданного слова из переменной partial, значение которой повторно собирается с каждой угаданной буквой. Поскольку в переменной guessed накапливаются буквы, угаданные игроком, команда sed преобразует в дефисы все буквы в исходном слове, которые отсутствуют в строке guessed .

Запуск сценария

Игра «виселица» принимает один необязательный аргумент: переданное ей число используется как максимально допустимое число ошибочных попыток, в противном случае их будет шесть (значение по умолчанию). В листинге 12.4 демонстрируется пример запуска сценария hangman без аргументов.

Результаты

Листинг 12.4. Сеанс игры «виселица»

$ hangman

steps from gallows: 6, word so far: —-

Guess a letter: e

* Great! The letter "e" appears in the word!