«Камень, ножницы, бумага» — простая, но очень популярная жестовая игра, которой вот уже не первый век развлекаются люди во всём мире. Поскольку правила игры просты, а жесты общепонятны, ею широко пользуются для улаживания споров, принятия решений или просто чтобы провести время. В этой статье мы исследуем богатую историю игры «Камень, ножницы, бумага», поговорим о том, как в неё играть, напишем саму игру и разберём структуру её кода, а также узнаем, как на материале этой игры можно прокачать навыки программирования.
История игры «Камень, ножницы, бумага»
Игра «Камень, ножницы, бумага» зародилась в Древнем Китае – там существовала аналогичная игра под названием «шушилинь», известная уже примерно во II веке до н.э. В ранней версии этой игры использовались три жеста, обозначавшие животных: тигр, курица и червь. В данном случае курица боится тигра, червь боится курицы, а тигр боится, что у него заведутся черви. Возникает кольцевое взаимоотношение, подобное тому, что известно нам из игры «Камень, ножницы, бумага».
Постепенно игра проникла в Японию, где закрепилась под названием «ян-кен-пон» и приобрела особую популярность в период Эдо (1603–1868). В японской версии исходную китайскую троицу животных заменили на всем знакомые камень, ножницы и бумагу, а также изобрели жесты, известные нам сегодня. Со временем игра распространилась и в европейские страны, где остаётся популярным развлечением по сей день.
Разработка игры «Камень, ножницы, бумага»
Разработка компьютерной версии «Камень, ножницы, бумага» — отличное упражнение для программистов, желающих попрактироваться и отточить свои навыки. Такую игру можно написать на HTML, CSS и JavaScript, этого хватит, чтобы предоставить пользовательский интерфейс и запрограммировать игровую логику.
Структурно код для игры «Камень, ножницы, бумага» можно разбить на несколько ключевых компонентов:
- Структура HTML: в файле HTML определяется структура и содержимое игры, в том числе, кнопки, которыми пользователь может выбирать ход. Также в HTML отображаются области для вывода результатов и очков.
- Стили CSS: в файле CSS обеспечивается стилевое оформление игры, в том числе, макет страницы, цвета, шрифты и другие визуальные элементы (правда, в этом примере мы не будем серьёзно останавливаться на стилях и сосредоточимся на функциональной составляющей)
- Логика JavaScript: в файле JavaScript содержится игровая логика, в том числе, функции для обработки пользовательского ввода, определения того, какой ход сделал компьютер, сравнения ходов для определения победителя, ведения счёта и отображения результатов.
Теперь давайте подробнее разберём структуру кода и исследуем, как все компоненты работают вместе. Наша цель – создать полнофункциональную игру «Камень, ножницы, бумага».
Структура HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rock, Paper, Scissors</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Rock, Paper, Scissors</h1>
<p>Choose your move:</p>
<button id="rock" onclick="handleClick('rock')">Rock</button>
<button id="paper" onclick="handleClick('paper')">Paper</button>
<button id="scissors" onclick="handleClick('scissors')">Scissors</button>
<div id="result"></div>
<div>
<span>User Score:</span>
<span id="user-score">0</span>
</div>
<div>
<span>Computer Score:</span>
<span id="computer-score">0</span>
</div>
<script src="script.js"></script>
</body>
</html>
Структура HTML служит основой игры. В разметке определяется, какие элементы будут видны пользователю. Вот основные HTML-элементы, входящие в эту структуру:
[…]
<body>
В этом элементе заключено всё содержимое, которое будет отображаться на странице, в частности, заголовки, абзацы, кнопки и другие элементы пользовательского интерфейса.
<h1>
<В этом элементе содержится заголовок, то есть, название игры: “Rock, Paper, Scissors”.
<p>
Это элемент, в котором заключается абзац (параграф). В нём содержатся инструкции, то есть, подсказки для пользователя, как выбирать ход.
<button>
В этих элементах представлены варианты хода, которые может выбрать пользователь («камень», «ножницы» или «бумага»). У каждой кнопки есть атрибут id, по которому его легко выбирать в файле JavaScript, а также атрибут onclick, по которому срабатывает функция handleClick(). В качестве аргумента эта функция принимает тот или иной ход.
<div id=”result”>
Данный div-элемент – это контейнер, в котором отображается результат каждого раунда. По атрибуту id можно выбирать и обновлять этот элемент на JavaScript.
Очки пользователя и компьютера
В этих div-элементах содержатся очки, заработанные пользователем и компьютером. Каждое значение очков заключено в элемент span, обладающий уникальным атрибутом id. Поэтому данные элементы легко выбирать и обновлять при помощи JavaScript.
<script src=”script.js”></script>
В этом элементе заключён скрипт, который связывает файл JavaScript с HTML-документом. Он размещается в самом конце элемента body и таким образом гарантирует, что сначала полностью загрузится содержимое HTML-документа, и только потом будет выполняться код JavaScript.
Структура файла JavaScript:
let userScore = 0;
let computerScore = 0;
let roundsPlayed = 0;
const getUserChoice = userInput => {
return userInput.toLowerCase();
};
const getComputerChoice = () => {
const number = Math.floor(Math.random() * 3);
return ["rock", "paper", "scissors"][number];
};
const determineWinner = (userChoice, computerChoice) => {
if (userChoice === computerChoice) {
return "It's a tie!";
}
const winConditions = {
rock: "scissors",
paper: "rock",
scissors: "paper",
};
return winConditions[userChoice] === computerChoice
? "User wins!"
: "Computer wins!";
};
const checkGameOver = () => {
if (userScore >= 3) {
alert("User wins the game!");
resetGame();
} else if (computerScore >= 3) {
alert("Computer wins the game!");
resetGame();
}
};
const resetGame = () => {
userScore = 0;
computerScore = 0;
roundsPlayed = 0;
document.getElementById("user-score").textContent = userScore;
document.getElementById("computer-score").textContent = computerScore;
document.getElementById("result").innerHTML = "";
};
const handleClick = choice => {
if (roundsPlayed >= 5) {
alert("Game over! Please start a new game.");
resetGame();
return;
}
const userChoice = getUserChoice(choice);
const computerChoice = getComputerChoice();
const result = determineWinner(userChoice, computerChoice);
const resultDiv = document.getElementById("result");
resultDiv.innerHTML = `User: ${userChoice} vs. Computer: ${computerChoice} - ${result}`;
if (result === "User wins!") {
userScore++;
} else if (result === "Computer wins!") {
computerScore++;
}
document.getElementById("user-score").textContent = userScore;
document.getElementById("computer-score").textContent = computerScore;
roundsPlayed++;
checkGameOver();
};
В файле JavaScript содержится игровая логика. В частности, здесь находятся функции для обработки пользовательского ввода, определения хода компьютера, сравнения ходов с целью определения победителя, а также для обновления счёта и выводимых результатов.
Разрабатывая на JavaScript логику игры «Камень, ножницы, бумага», можно освоить различные аспекты программирования, в частности, работу с функциями, условными операторами, а также обработку событий.
- Объявление и инициализация глобальных переменных:
userScor, computerScore, roundsPlayed
. В них хранятся очки пользователя, очки компьютера и общее количество отыгранных раундов.
- Функция
getUserChoice()
: она принимает пользовательский ввод (строку) и возвращает её же в нижнем регистре. Это делается для того, чтобы все записи в игре не отличались по регистру.
- Функция
getComputerChoice()
: она создаёт случайный вариант, который станет ходом компьютера. Эта функция генерирует случайное число от 0 до 2 и сопоставляет его с соответствующим вариантом (камень, ножницы или бумага).
- Функция
determineWinner()
: она принимает выбор, сделанный компьютером и выбор, сделанный пользователем, сравнивает их и определяет победителя раунда. Проверяет, равны ли варианты (в таком случае фиксируется ничья) или находит победителя в зависимости от условий того, какой объект берёт верх. Эти условия определяются в объекте winConditions
.
- Функция
checkGameOver()
: проверяет, завершена ли игра, в зависимости от того, какая из сторон победила по итогам 5 раундов. Если пользователь или компьютер победили в 3 или более раундах, то игра считается завершённой и выводится окно-уведомление с указанием победителя. После вывода такого уведомления вызывается функция resetGame()
, сбрасывающая состояние игры в исходное.
- Функция
resetGame()
: эта функция сбрасывает состояние игры, устанавливая в 0 очки пользователя, очки компьютера и количество сыгранных раундов. Также она обновляет таблицу лидеров и стирает текст с описанием результата.
- Функция
handleClick()
: Функция `handleClick()
` вызывается, как только пользователь щёлкнет по одной из кнопок – камню, ножницам или бумаге. Сначала функция проверяет, не завершена ли ещё игра (прошло ли 5 раундов) и, если требуется, выводит уведомление о начале новой игры. После этого функция извлекает значение, выбранное пользователем (передаётся в качестве аргумента) и получает значение, выбранное компьютером (оно генерируется случайным образом). Далее она определяет победителя при помощи функции determineWinner()
и обновляет текст с результатами. В зависимости от того, кто выиграл раунд – пользователь или компьютер – счёт этого игрока увеличивается, что соответствующим образом отражается на экране. Также увеличивается значение переменной roundsPlayed
и вызывается функция checkGameOver()
, проверяющая, закончена ли игра.
Какими продвинутыми навыками программирования можно овладеть, работая над игрой «Камень, ножницы, бумага»
- Понять объектную модель документа (DOM) и научиться манипулировать ею. Программируя «Камень, ножницы, бумага», можно научиться выбирать, создавать и модифицировать HTML-элементы при помощи JavaScript.
- Обработка событий: в игре требуются слушатели событий, которые будут обнаруживать пользовательский ввод и реагировать на него. Так приобретается ценный опыт по работе с событиями в JavaScript.
- Реализация игровой логики: при разработке игровой логики программист всегда практикуется в написании функций, использовании условных операторов и работе с переменными.
- Работа с CSS-стилями: разрабатывая внешний вид игры, разработчик учится обращаться со свойствами и селекторами CSS. В ходе этой работы можно лучше понять принципы веб-дизайна.
- Организация кода и наилучшие практики: при разработке игры «камень, ножницы, бумага» мы учимся писать чистый и организованный код, следовать наилучшим практикам, задумываться о масштабируемости и поддержке кода в разных проектах.
В дальнейшем этот проект может послужить основой для дальнейших исследований и творчества. Разработчик вполне может реализовать в этой игре и дополнительные возможности – например, звуковые эффекты, анимацию, таблицы рекордов и альтернативные игровые режимы.
Поиграть в «Камень, ножницы, бумага» можно
здесь.