数字を使用する推理ゲーム「ヌメロン」をJSで作成しました。
まだ改善点がいくつかありますので、また修正しましたら再度コードを変更しようと思います。
「ヌメロン」とは
ヌメロンのルールをご説明します。ご存じの方は読み飛ばしていただければと思います。
1~9の数字から異なる3桁の数字を選びます。
1ターンごとにお互いが相手の選んだと思われる3桁の数字を推理して宣言します。
例えばAさんは「358」を選んだとします。
Bさんが「381」と宣言しました。
Aさんの数字は「358」で数字としては3と8があっています。
位置があっている場合はヒット、位置はあっていないけど、数字があっている場合はブローで表現します。 ※イート、バイトという呼び方もあります。
今回の場合は1ヒット1ブローとなります。
このヒットとブローがターンごとに変わっていくのでそこから推測して、相手の3桁の数字を当てれば勝利になります。
ヌメロンをコーディング
それではヌメロンをコーディングしていきます。
今回は、対戦というより一方的に解いていくような仕様になっています。
まずランダムに3桁の数字を決め、スタートします。three_random_number()メソッド
入力欄に数字を入れていただき、送信ボタンを押せば数字が送信されます。
この時、数字が重なっているかどうか、3桁の数字で送信されているかをチェックし、3桁の数字でない場合はバリデーションエラーにするようにしました。
10回までに成功すれば、アラートを表示してゲームが終了します。
コード
numeron.html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Sample</title>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="numeron.js"></script>
</head>
<body>
<h1>ヌメロン</h1>
<input type="text" id="form">
<div class="frame">入力内容:<span id="output"></span></div>
<div id="alert"></div>
<input type="button" value="回答" onclick="inputCheck()">
<div id="judge1"></div>
<div id="judge2"></div>
<div id="judge3"></div>
<div id="judge4"></div>
<div id="judge5"></div>
<div id="judge6"></div>
<div id="judge7"></div>
<div id="judge8"></div>
<div id="judge9"></div>
<div id="judge10"></div>
<div id="finish"></div>
<input type="hidden" name="playnum" id="playnum" value=1></input>
</body>
</html>
numeron.js
//ランダムの3桁の数字を生成
three_random_number()
//入力チェック
function inputCheck () {
let num = $('input:hidden[name="playnum"]').val();
var form = document.getElementById("form");
var form_value = form.value;
const checkNum = form_value.split("");
if (form_value.match(/[0-9]+/g) != form_value || form_value.length != 3) {
document.getElementById('alert').innerHTML = '3桁の数値で入力してください!';
document.getElementById('output').innerHTML = form_value;
} else {
if(existsSameValue(checkNum)){
document.getElementById('alert').innerHTML = '3桁の数字は異なるものをいれてください!';
form.value = '';
document.getElementById('output').innerHTML = form_value;
return;
}
//成功判定してヒットかブローの判定
document.getElementById('output').innerHTML = form_value;
var idName = "judge" + num;
var hitNum = hitJudge(answer_number, checkNum);
var blowNum = blowJudge(answer_number, checkNum);
document.getElementById(idName).innerHTML = num + '回目の回答: ' + form_value + ' H:' + hitNum + ' B:' + blowNum;
$('input:hidden[name="playnum"]').val(parseInt(num) + 1);
}
//入力フォームのリセット
form.value = '';
if(hitNum == 3){
document.getElementById('finish').innerHTML = "正解です!";
alert("正解です!");
}
if(num == 10){
document.getElementById('finish').innerHTML = "挑戦失敗です";
}
}
function hitJudge(answer_number, checkNum){
var num = 0;
for (let i = 0; i < 3; i++) {
if(checkNum[i] == answer_number[i]){
num++;
}
}
return num;
}
function blowJudge(answer_number, checkNum){
var num = 0;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if(i == j) continue;
if(checkNum[i] == answer_number[j]){
num++;
}
}
}
return num;
}
function existsSameValue(num){
var check = new Set(num);
return check.size != num.length;
}
// ランダムな三桁の数字
function three_random_number() {
answer_number = [];
for (let i = 0; answer_number.length < 3; i++) {
const number = Math.floor(Math.random() * 10)
if(!answer_number.includes(number)){
answer_number.push(number);
}
}
}
今後追加・修正したいところ
関数の修正
まず、判定している関数はひとつにまとめることができますが、あえてそのままにしました。
この関数をどのように一つにまとめるか考えていただければ学習になるかと思います。
ヒントアイテム機能
HIGH LOW など数字の位置を1~4 5~9に分けて表示してくれる機能や、一番上と一番下の値の差を知ることができるお助けアイテムを追加してみようと思います。
CPU対戦機能
CPUと対戦する機能ができたらと思います。