8. Игра «Виселица»
В основе игры «Виселица» лежит принцип угадывания слов. Один игрок загадывает
слово, а второй, в свою очередь, пытается его отгадать. Например, если первый игрок
загадал слово КАПУСТА, он должен изобразить семь «пустых мест», которые
соответствуют буквам в слове:
_______
Второй игрок пытается отгадать это слово, называя различные буквы. Каждый раз, когда
он отгадывает букву, первый игрок заполняет пустые месте. При этом вписывая
названную букву везде, где она встречается. Например, если тот, кто отгадывает, назвал
букву «А», то тот, кто загадал слово, должен вписать все «А», которые есть в слове
КАПУСТА, вот так:
_А____А
Если второй игрок назовет букву, которой нет в слове, у него отнимается очко, а первый
игрок рисует рядом какую-либо часть тела человечка. Если первый игрок закончит
рисовать человечка раньше, чем второй отгадает все буквы, – второй игрок проиграл.
Основываясь на правилах игры «Виселица», JavaScript будет выбирать случайное слово, а
человек – отгадывать буквы. Но рисовать человечка программа пока не будет.
Взаимодействие с игроком
Чтобы играть в данную игру, игроку необходимо каким-то образом вводить в программу
свои ответы. Один из способов реализации этой идеи: сделать/открывать специальное
диалоговое окно (prompt), в котором игрок сможет печатать буквы.
console.log(“Hello, ” + name);
рис. 1
Вызов prompt ("What is your name?") создает окно с запросом "What is your name?" и
строкой для ввода текста. В нижней части этого диалога есть две кнопки — «ОК» и
«Отмена».
Если ввести какой-нибудь текст и нажать «ОК», этот текст станет значением, которое
вернет в программу prompt. Например, если ввести имя и нажать «ОК», JavaScript
напечатает его в консоли.
Поскольку введено имя VLAD и нажато «ОК», строка "VLAD" попадает в переменную
name, а вызов console.log напечатал: "Hello, " + "VLAD", то есть "Hello, VLAD" (рис. 1).
рис. 1
Если нажать кнопку «Отмена», prompt вернет значение null. null используется для
обозначения чего-либо, что намеренно оставлено пустым.
После нажатия «Отмена» в консоли должно появиться:
рис. 2
В данном случае console.log печатает null как строку. Вообще-то null строкой не является.
Вспомним, что в консоль можно выводить только строки. В нашем случае JavaScript
задано напечатать "Hello, " + null. И чтобы напечатать это значение, JavaScript
преобразовал null в строку "null".
Ситуация, когда JavaScript автоматически преобразует значение к другому типу,
называется неявным приведением типа.
Неявное приведение типа – пример того, как JavaScript старается быть универсальной.
Способа объединить строку и null не существует, однако JavaScript знает, что для
успешного выполнения операции нужны две строки. Строковая версия значения null – это
«null», и в результате мы видим в консоли «Hello, null».
Проектирование игры
Прежде чем перейти к непосредственному проектированию игры «Виселица»,
необходимо продумать ее структуру. Программа должна выполнять такие действия:
1.Непроизвольно выбирать слово.
2.Запрашивать вариант ответа у игрока (в нашем случае – букву).
3.Заканчивать игру по желанию игрока.
4.Проверять введенный ответ (является ли он буквой).
5.Подсчитывать угаданные буквы.
6.Демонстрировать, какие буквы отгадал игрок и сколько осталось не
отгаданными.
Завершать игру, если игрок отгадал слово.
Все эти действия, кроме первого и последнего (выбор слова и завершение игры), нужно
выполнять многократно. При этом заранее неизвестно, сколько раз действия должны
повторятся (это зависит от ответов игрока). Таким образом несложно догадаться, что в
программе нужен цикл. Однако в списке действий ничего нет информации что и когда
должно происходить. Чтобы выяснить этот вопрос и лучше представить себе структуру
будущей программы, необходимо составить блок-схему.
Блок-схема – удобный инструмент, который программисты часто используют при
проектировании программ. Пример блок-схемы: (скриншот лучше заменить)
Блок-схема дает представление о структуре программы прежде, чем перейти к написанию
кода и выяснению мелких деталей.
Также понадобится переменная для хранения тех букв, которые ещё нужно угадать. Для
каждого вхождения правильно угаданной буквы эта переменная будет уменьшаться на 1,
и, когда она примет значение 0, программа поймет, что игрок победил.
Программирование игры
Теперь, когда есть представление о структуре игры, можно переходить к написанию кода.
рис. 1
Игра начинается со строки 1, где создается массив со словами (program, monkey, beautiful,
step), из которого затем будет выбираться слово для отгадывания (все слова должны быть
записаны строчными буквами). Cохраните этот массив в переменной words. В строке 7
используется Math.random и Math.floor, чтобы выбрать из массива случайное слово.
рис. 2
В строке 9 в начале цикла for создается переменная цикла i, которая сначала равна 0, а
затем возрастает до word.length (не включая само значение word.length). Во время повтора
цикла в массив добавляется новый элемент — answerArray[i]. Когда цикл завершится,
длина answerArray будет соответствовать длине слова. Например, если было выбрано
слово «monkey» (в котором шесть букв), answerArray примет вид [" _ ", " _ ", " _ ", " _ ", " _
", " _ "] (шесть знаков подчеркивания).
Наконец, создано переменную remainingLetters, которая приравнена к длине загаданного
слова. Эта переменная понадобится, чтобы отслеживать количество букв, которые еще
предстоит угадать. Каждый раз, когда игрок назовет правильную букву, будет
уменьшаться значение этой переменной: на один для каждого вхождения буквы в слово.
рис. 4
В строке 20 prompt запрашивает у игрока ответ и сохраняет его в переменной guess. Далее
возможен один из четырех вариантов развития событий.
Первый вариант. Если игрок нажмет кнопку «Отмена», guess примет значение null. Этот
вариант проверяется в строке 21 командой if (guess === null). Если это условие даст true,
то с помощью break можно выйти из цикла.
Второй и третий варианты. Игрок не ввел ничего либо ввел несколько букв. Если он
просто нажал «ОК», ничего не вводя, в guess окажется пустая строка (""). В таком случае
guess.length вернет 0. Если же игрок ввел больше одной буквы, guess.length вернет число
больше 1. В строке 23 с помощью else if (guess.length !== 1) обрабатываются эти варианты,
то есть происходит проверка, что guess содержит одну букву. В другом случае
отображается диалог alert: «Please enter a single letter.»
Четвертый вариант. Игрок, как и положено, ввел одну букву. Тогда программа должна
обновить состояние игры. Это происходит в строке 26, в секции else.
рис. 5
В строке 27 цикл for представлен переменной j. Именно она будет менять значение от 0 до
word.length, не включая само значение word.length. В этом цикле проверяется каждая
буква переменной word.
В строке 28 с помощью if (word[j] === guess) идет проверка, совпадает ли текущая буква
(word[j]) с ответом игрока. Если это так, обновляется итоговый массив, добавляя туда
букву командой answerArray[j] = guess. Для каждой буквы, совпадающей с ответом,
обновляется соответствующая позиция итогового массива.
Помимо обновления answerArray для каждого совпадения с guess требуется уменьшать
remainingLetters на 1. Делается это в строке 30 командой remainingLetters--;. Каждый раз,
когда guess совпадает с буквой из word, remainingLetters уменьшается на 1, и, когда игрок
угадает все буквы, remainingLetters примет значение 0.
Конец игры
Игровой цикл while выполняется при условии remainingLetters > 0. Поэтому тело данного
цикла будет повторяться до тех пор, пока еще остаются неотгаданные буквы. Когда же
remainingLetters уменьшится до 0, цикл завершится. После цикла остается лишь закончить
игру — это позволяет сделать такие коды:
alert(answerArray.join(“ “));
Код игры
В тексте весь код игры разобран по частям, остается лишь соединить эти строки кода. На
рисунке 6 представлен весь код:
рис. 6