ルール説明
1.出題者は0〜9の数字を使用した4桁の数字を正解として用意し解答者から隠しておく。
2.解答者は解を予想し質問をする。
3.出題者は質問と正解の数を比較して
Hit数:同じ数字が同じ桁に出現する回数
Blow数:同じ数字が違う桁に出現する回数
をヒントとして回答者に与える。
*本来は4桁の数字がそれぞれ互いに異なる数字であり、Blow数は同じ数字が違う桁に出現する回数であるルールが一般的だが今回は少し複雑化している。
実行環境
PC環境:macOS Monterey
PC環境2:iMac(M1)
PHPを実行するための環境: MAMP(インストール方法はこちら。)
エディター: Visual Studio Code
Github:(コードはこちら)
phpファイル名:Hit&Blow.php
コード
<!-- HTML -->
<html>
<head>
<h2>Hit & Blow ゲームはこちら</h2>
<body bgcolor="#98FB98"></body>
</head>
<body>
<p>ここに4桁の数字を入力して送信ボタンを押してください</p>
<form action="Hit&Blow.php" method="post">
<input type="number" name="input" value="">
<input type="submit">
</form>
</body>
</html>
<!-- PHP -->
<?php
function console_log($data){ //デバグログ出力のためのコード
echo '<script>';
echo 'console.log('.json_encode($data).')';
echo '</script>';
}
session_start(); //セッション開始
if(empty($_SESSION["randomnumber"])) { //sessionが空の場合
$_SESSION["randomnumber"] = sprintf('%04d', mt_rand(0000,9999)); //4桁の乱数生成
}
console_log($_SESSION["randomnumber"]); //consoleで確認できる。
$random_4 = $_SESSION["randomnumber"]; //変数random_4に生成した乱数を格納
$inputnumber = array(); //入力された4桁数字を格納する配列
$randomnumber = array(); //ランダム4桁数字を格納する配列
echo '入力した数字 ',$_POST["input"]; //入力された数字を表示
echo "<br/>\n"; // 改行
$stringinput4 = (string)$_POST["input"]; //入力された4桁の数を文字列に変換させる
$splitinput4 = str_split($stringinput4); //文字列に変換したものを分割
$stringrandom4 = (string)$random_4; //ランダム4桁の数を文字列に変換させる
$splitrandom4 = str_split($stringrandom4); //文字列に変換したものを分割
for($i = 0; $i < count($splitinput4); $i++){ //入力した文字数に応じて繰り返しの回数を変える
array_push($inputnumber, $splitinput4[$i]); //配列に数字(文字型)を格納
}
for ($i = 0; $i < 4; $i++){ //ランダム数字は4文字確定
array_push($randomnumber, $splitrandom4[$i]); //配列に数字(文字型)を格納
}
// echo "<br>\n"; // 改行
// echo 'ランダム4桁 ',$random_4."<br>"; //ランダム4桁数字を出力したい場合はここのコメントアウトを解除
echo "<br>\n"; // 改行
// ここから条件分岐
$hitcount = 0; //Hitした数をカウントする変数
$blowcount = 0; //Blowした数をカウントする変数
$countinput = count($inputnumber); //入力した数字の配列の長さが4ではないとそもそもNG
echo "入力文字列長さ:".$countinput."<br><br>"; //大体は4
if($countinput == 4){ //入力した数字が4桁かどうか
// 初めにHitの個数を数える。
for ($i = 0; $i < 4; $i++){ //ランダム数字は4文字確定
if($randomnumber[$i] == $inputnumber[$i]){ //数字、順番共に一致したかどうか
$hitcount++; //加算
}
}
// Blowの個数を数える。
$r_number_array = array(); //ランダム4桁数字を1文字ずつ格納する配列
foreach($randomnumber as $r_number){ //ランダム4桁数字配列の中で繰り返し処理
$key = in_array($r_number,$inputnumber); //4つのランダム数字それぞれが入力した数字に含まれているかどうか
if($key){ //含まれている場合
if(in_array($r_number,$r_number_array)){ //r_number_arrayに含まれていた場合はもう比較が終了している
// 何もしない
}else{ //r_number_arrayに含まれていない場合
array_push($r_number_array, $r_number); //r_number_arrayに追加
$countrandom = count(array_keys($randomnumber, $r_number)); //ランダム4桁の中にr_numberがいくつ含まれているか
$countinput = count(array_keys($inputnumber, $r_number)); //入力した4桁の中にr_numberがいくつ含まれているか
if($countrandom <= $countinput){ //少ない方の数をblowcountに加算
$blowcount += $countrandom;
}else{
$blowcount += $countinput;
}
}
}else{ //含まれていない場合
// 何もしない
}
}
echo "Hit回数:".$hitcount."<br>";
echo "Blow回数:".$blowcount."<br>";
if($hitcount == 4 && $blowcount == 4){ //HitとBlowが共に4になった場合は新しい乱数を生成させる
$_SESSION["randomnumber"] == array();
session_destroy(); //セッションを破壊させる
}
}else{ //そもそも入力した数字が4桁ではない場合
echo "Retry"."<br>";
}
//PHPの内容
?>
<html>
<head>
</head>
<body>
<hr>
<p> -- 入力履歴 -- </p>
</body>
</html>
<html>
<!-- 入力履歴の結果とそのヒット数の結果を表示 -->
<?php
if($hitcount == 4 && $blowcount == 4){ //HitとBlowが共に4になった場合は新しい乱数を生成させる
$_SESSION["input"] == array();
$_SESSION["hitnumber"] = array();
$_SESSION["blownumber"] = array();
session_destroy(); //セッションを破壊させる
}
session_start(); //セッション開始
if(!isset($_SESSION["input"])){
$_SESSION["input"] = 'Input:'; //最初の文字列
}else{
$_SESSION["input"] .= ' '.$stringinput4; //文字列連結
}
if(!isset($_SESSION["hitnumber"])){
$_SESSION["hitnumber"] = 'Hit:'; //最初の文字列
}else{
$_SESSION["hitnumber"] .= ' '.(string)$hitcount; //文字列連結
}
if(!isset($_SESSION["blownumber"])){
$_SESSION["blownumber"] = 'Blow:'; //最初の文字列
}else{
$_SESSION["blownumber"] .= ' '.(string)$blowcount; //文字列連結
}
echo ($_SESSION["input"]); //入力履歴を表示
echo "<br/>\n";
print $_SESSION["hitnumber"]; //ヒット数を表示
echo "<br/>\n";
print $_SESSION["blownumber"]; //ブロー数を表示
?>
<!-- 参考文献 -->
<!-- PHP 文字列出力と改行の方法について -->
<!-- https://it-kyujin.jp/article/detail/1066/#:~:text=%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%8A%E3%81%A7%E3%81%AE%E6%94%B9%E8%A1%8C%E3%81%AB%E3%81%AF%E3%80%81PHP%E3%82%B3%E3%83%BC%E3%83%89,%E3%81%95%E3%81%9B%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82 -->
<!-- PHP入門 PHPでセッションを使う方法 -->
<!-- https://www.sejuku.net/blog/25276 -->
<!-- やさしいホームページ入門 -->
<!-- http://www.ink.or.jp/~bigblock/html/text.html -->
<!-- 出力に使用するechoとprintの違い -->
<!-- https://www.javadrive.jp/php/string/index3.html -->
<!-- PHPの空白 -->
<!-- https://wepicks.net/phpref-kuhakukaigyo/ -->