JavaScriptを学んだので、じゃんけんゲームを作成してみました。
もし、初学者の方がいましたら、参考にして頂けますと幸いです。
#参考サイト
- 変数名が困ったときにおすすめ
https://codic.jp/engine - ボタンデザイン
https://saruwakakun.com/html-css/reference/buttons - textContentとinnerHTMLの違い
https://itsakura.com/js-textcontent-innerhtml
#特徴
- 10回行い、勝ち数、負け数、勝率を計算
- ボタンを押下する度に、相手の手がランダムに決定される
- 結果によって表示されるコメントが変わる
- 勝ちの場合:『あなたの勝ちです』と表示、勝ちカウント+1
- 負けの場合:『あなたの負けです』と表示、負けカウント+1
- 引き分け:『あいこです』と表示
- 結果によって表示されるコメントが変わる
- 10回に到達後
-
グー
,チョキ
,パー
ボタンが非活性になる - アラート表示させ、勝ち越し、負け越し、引き分けか表示
-
更新
ボタン表示させる
-
#関数について
- gameCountReplace()
- 試合数を計算する関数
- alert()
- 最終的な結果をアラートで表示させるための関数
- resetClick()
- ボタン作成、reload()関数呼び出し関数
- inactive()
- ボタンを非活性にする関数
- winRateCalc()
- 勝率を計算する関数
- onClick()
- グー、チョキ、パーのどれかを押下したときに処理される関数
HTML
index.html
(省略)
<body>
<div id="main">
<div id="container">
<h1>じゃんけん</h1>
<p class="text">試合数:
<span id="gameCount">0</span>
</p>
<div class="btn">
<button id="rock" value="0">グー</button>
<button id="scissors" value="1">チョキ</button>
<button id="paper" value="2">パー</button>
</div>
<div id="battle">
<p id="myHand">自分の出した手:まだ出していません</p>
<p id="enemyHand">相手の出した手:まだ出していません</p>
<h2 id="result"></h2>
</div>
<div id="resultTable">
<dl>
<dt class="text">勝ち数</dt>
<dt class="text">負け数</dt>
<dt class="text">勝率</dt>
</dl>
<dl>
<dd id="winCount">ー</dd>
<dd id="loseCount">ー</dd>
<dd id="winRate">ー</dd>
</dl>
</div>
<div id="reset"></div>
</div>
</div>
<script src="./main.js"></script>
</body>
#JavaScript
main.js
'use strict';
(() => {
const hands = ['グー', 'チョキ', 'パー'];
const resultText = ['『あなたの勝ちです』', '『あなたの負けです』', '『あいこです』'];
// 値を取得する
const count = document.getElementById('gameCount');
let countResult = count.innerHTML;
const rock = document.getElementById('rock');
const scissors = document.getElementById('scissors');
const paper = document.getElementById('paper');
const myHandType = document.getElementById('myHand');
const enemyHandType = document.getElementById('enemyHand');
const result = document.getElementById('result');
const reset = document.getElementById('reset');
const winCount = document.getElementById('winCount')
const loseCount = document.getElementById('loseCount')
const winRate = document.getElementById('winRate');
//試合数、勝ち数、負け数
let gameCount = 0;
let winResult = 0;
let loseResult = 0;
//試合数書き換え
const gameCountReplace = (gameCount) => {
countResult = countResult.replace(countResult, gameCount);
count.textContent = countResult;
}
const alert = (winResult, loseResult) => {
if (winResult > loseResult) {
window.alert('勝ち越しました!');
} else if (winResult < loseResult) {
window.alert('負け越しました!');
} else {
window.alert('引き分けでした!');
}
}
//リセットボタン表示とreload()関数呼び出し
const resetClick = () => {
//ボタン要素作成
const resetBtn = document.createElement('input');
resetBtn.type = 'button';
resetBtn.value = '更新';
reset.appendChild(resetBtn); //親要素(reset)の子要素にボタンを配置する
resetBtn.addEventListener('click', () => { //更新ボタンを押下後、画面リロードする
location.reload();
})
}
//10回到達したらボタンを非活性にする
const inactive = () => {
rock.disabled = true;
scissors.disabled = true;
paper.disabled = true;
}
//勝率計算
const winRateCalc = (gameCount, winCount) => {
const winRateResult = (winCount / gameCount) * 100;
winRate.textContent = `${winRateResult}%`;
}
//ボタン押下関数
const onClick = (event) => {
const myHand = Number(event.target.value); //取得するvalue値はstring型のため、Number型に変換
const enemyHand = Math.floor(Math.random() * hands.length);
myHandType.textContent = `自分の出した手:${hands[myHand]}`;
enemyHandType.textContent = `相手の出した手:${hands[enemyHand]}`;
//勝敗判定
const handResult = (myHand - enemyHand + 3) % hands.length;
if (handResult === 2) {
result.textContent = resultText[0];
gameCount++;
winResult++;
gameCountReplace(gameCount);
} else if (handResult === 1) {
result.textContent = resultText[1];
gameCount++;
loseResult++;
gameCountReplace(gameCount);
} else {
result.textContent = resultText[2];
}
if (gameCount === 10) { //試合数が10回に到達したら実行される処理
winCount.textContent = `${winResult}回`;
loseCount.textContent = `${loseResult}回`;
winRateCalc(gameCount, winResult);
alert(winResult,loseResult)
inactive();
resetClick();
}
}
// クリックした時の挙動はどのボタンも同じなので、関数を共通化
rock.addEventListener('click', onClick);
scissors.addEventListener('click', onClick);
paper.addEventListener('click', onClick);
})();
#CSS
style.css
#main {
width: 500px;
margin: 0 auto;
}
#container {
text-align: center;
}
.btn {
margin: 20px;
padding: 10px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
button,
input[type="button"] {
width: 30%;
border: none;
border-radius: 5px;
color: #fff;
padding: 8px 16px;
font-size: 16px;
}
button#rock {
background-color: #dc143c;
border-bottom: solid 4px #8b0000;
}
button#scissors {
background-color: #ffd700;
border-bottom: solid 4px #b8860b;
}
button#paper {
background-color: #4676d7;
border-bottom: solid 4px #191970;
}
#rock:disabled,
#scissors:disabled,
#paper:disabled {
background-color: #808080;
border-bottom: none;
}
input[type="button"] {
background-color: #b0c4de;
border-bottom: solid 4px #708090;
width: 40%;
padding: 10px;
font-size: 30px;
}
button:active,
input[type="button"]:active {
-webkit-transform: translateY(4px);
transform: translateY(4px); /*下に動く*/
border-bottom: none; /*線を消す*/
}
#battle {
border: 1px solid #ccc;
padding: 10px;
}
#myHand,
#enemyHand {
font-size: 20px;
}
#resultTable {
border: 1px solid #ccc;
margin: 15px 0;
}
dl {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
border-bottom: 1px solid #ccc;
font-size: 20px;
}
dl:last-child {
border-bottom: none;
}
dd {
text-align: center;
font-size: 20px;
}
学んだこと
-
○.disabled = true
とすることで、非活性状態にできること -
event.target.value
で押下したボタンのvalue
値を取得することが可能 -
replace()
関数の使い方(文字の書き換え) - JavaScriptで処理した値を画面上に表示させるために、
textContent
やinnerHTML
を活用できること- textContent:htmlのタグを文字としてそのまま出力
- innerHTML:htmlのタグを解釈して出力
- 関数の呼び出すタイミングとか、なんとなく掴めた気がする。
- じゃんけんの勝敗処理で、下記のように書くことで、判定処理が簡潔に済むことを知れた
const handResult = (myHand - enemyHand + 3) % hands.length;
メモ(適当)
- 初期状態として、JS上で
まだ出していません
の箇所だけ変えるというようにしたかった。しかし今回は、再描画という形をとっている。- 1回目は、一部だけ変更はできたのだが、2回目以降は値が変更しなかった。
- 原因
- 最初は、replace('まだ出していません', xxx)としていた。
- 1回目は画面に「まだ出していません」が表示されているため、
replace()
関数が実行される。 - 2回目以降は「まだ出していません」が書き換わっているため、
replace()
関数が実行されなかった
- 1回目は画面に「まだ出していません」が表示されているため、
- 最初は、replace('まだ出していません', xxx)としていた。
- 原因
- 1回目は、一部だけ変更はできたのだが、2回目以降は値が変更しなかった。
※ちょっと頑張ればこの処理できそうじゃんとか思いますが、面倒だったので、辞めました。また、機会があればこの辺の処理を修正したいと思います。
まとめ
- 自分でコードを考えて、作成したので、ロジック的な部分の向上に繋がった。また、何より作成したものが、すぐに画面に反映されるのは、楽しかったし、フロント言語の醍醐味だなと感じた。
- 今回のアプリは、基礎文法でしか使っていないので、オブジェクト指向や非同期通信あたりも今後学んでいきたい。
- 徐々に慣れてきたら、Vue.js,Node.jsなどのFWにも挑戦していきたいと考えている。
- 今後のステップアップのために、これ作ると良いよ、これ作ったよ的なものがあれば教えて欲しいです。