【PHP】Lesson2-☆2:数字当てゲームを作って制御構造を総復習しよう

Lesson2で学習した内容を応用して、数字当てゲームを作成しましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
・Lesson2-1:比較演算子と論理演算子
・Lesson2-2:if文による分岐処理を理解しよう
・Lesson2-3:条件演算子を使いこなそう
・Lesson2-4:switch文による分岐処理を理解しよう
・Lesson2-5:for文による繰り返し処理を理解しよう
・Lesson2-6:while文による繰り返し処理を理解しよう
・Lesson2-7:繰り返しを制御しよう
・Lesson2-8:エラーメッセージを読めるようになろう
・Lesson2-9:例外処理を理解しよう
・確認問題2-1:ハイアンドロー ゲームを作ろう
・確認問題2-2:数字当てゲームを作ろう ◁今回はココ
・確認問題2-3:シンプルなじゃんけんゲームを作ろう
Lesson3:関数編
Lesson4:データ構造編
Lesson5:クラス編
演習問題|PHPで数字当てゲームを作成しよう【is_numeric・ループ・分岐の実践】

ランダムな数字を当てるゲームを作成しましょう。
このプログラムでは1から100までのランダムな数字が選ばれ、それをユーザーが当てるまで繰り返し入力を求めます。
プログラムではユーザーが数字以外を入力した場合にエラーメッセージを表示し、正しい入力がされるまでゲームを続行できるようにする必要があります。
この問題の要件
以下の要件に従ってコードを完成させてください。
- ランダムな1から100までの整数を生成し、その値をゲームの「正解」として使用すること。
- ユーザーに「数字を入力してください:」と表示し、数値を入力させること。
- ユーザーが入力した値が数値かどうかを is_numeric で判定し、数値でない場合は「数字を入力してください!」とエラーメッセージを表示して再入力を求めること。
- ユーザーが入力した数値が正解より小さい場合は「もっと大きい数字です!」、正解より大きい場合は「もっと小さい数字です!」と表示すること。
- ユーザーが正解を当てた場合は「おめでとうございます!正解は〇〇でした。」と表示し、ゲームを終了すること。
- ゲーム終了時に、何回目の入力で正解したかを表示すること。
ただし、以下のような実行結果となること。
数字当てゲームを始めます! 1から100までの数字を当ててください。 数字を入力してください: 50 もっと大きい数字です! 数字を入力してください: 75 もっと小さい数字です! 数字を入力してください: 63 おめでとうございます!正解は 63 でした。 あなたは 3 回目で正解しました。
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)1:「数字当てゲームを始めます!」を出力
2:「1から100までの数字を当ててください。」を出力
3:変数$targetに1から100までの範囲のランダムな数字を代入
4:変数$attemptsに0を代入
5:while文による無限ループ開始
□ 「数字を入力してください: 」を出力
□ 標準入力から文字列を読み取り、trim関数で余分な空白を除去して変数$inputに代入
□ if文で$inputが数値でない場合を判定
□ □ 「数字を入力してください!」を出力
□ □ continueで次のループに進む
□ 変数$guessに$inputを整数にキャストして代入
□ 変数$attemptsに1を加算
□ if文で$guessが$targetより小さいかを判定
□ □ 「もっと大きい数字です!」を出力
□ elseif文で$guessが$targetより大きいかを判定
□ □ 「もっと小さい数字です!」を出力
□ else文
□ □ 「おめでとうございます!正解は {$target} でした。」を出力
□ □ 「あなたは {$attempts} 回目で正解しました。」を出力
□ □ breakでループを終了
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
<?php // 数字当てゲーム echo "数字当てゲームを始めます!" . PHP_EOL; echo "1から100までの数字を当ててください。" . PHP_EOL; // ランダムな数字を生成 /* 【穴埋め問題1】ここで1から100までの範囲のランダムな数字を生成して$targetに代入するコードを書いてください。 */ $attempts = 0; while (true) { echo "数字を入力してください: "; $input = trim(fgets(STDIN)); // ユーザー入力 // 入力が数字か確認 if (!is_numeric($input)) { echo "数字を入力してください!" . PHP_EOL; continue; } /* 【穴埋め問題2】ここで$inputを整数にキャストして$guessに代入し、試行回数をカウントするコードを書いてください。 */ /* 【穴埋め問題3】ここで$guessと$targetを比較して判定処理を行い、結果を出力するコードを書いてください。 */ }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
この問題の答え合わせ
この問題の正解コードとその解説は以下の通りです。
クリックして開いて確認してください。
- 正解コード
-
<?php // 数字当てゲーム echo "数字当てゲームを始めます!" . PHP_EOL; echo "1から100までの数字を当ててください。" . PHP_EOL; // ランダムな数字を生成 $target = rand(1, 100); $attempts = 0; while (true) { echo "数字を入力してください: "; $input = trim(fgets(STDIN)); // ユーザー入力 // 入力が数字か確認 if (!is_numeric($input)) { echo "数字を入力してください!" . PHP_EOL; continue; } $guess = (int)$input; $attempts++; // 判定 if ($guess < $target) { echo "もっと大きい数字です!" . PHP_EOL; } elseif ($guess > $target) { echo "もっと小さい数字です!" . PHP_EOL; } else { echo "おめでとうございます!正解は {$target} でした。" . PHP_EOL; echo "あなたは {$attempts} 回目で正解しました。" . PHP_EOL; break; } }
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
ゲームの開始メッセージ
echo "数字当てゲームを始めます!" . PHP_EOL; echo "1から100までの数字を当ててください。" . PHP_EOL;
echo
: 画面に文字列を表示する命令です。PHP_EOL
: 改行を意味する定数で、環境に応じた適切な改行コードを使います。- ここではゲームの開始をユーザーに知らせるメッセージを表示しています。
ランダムな数字を生成
$target = rand(1, 100); $attempts = 0;
rand(1, 100)
: 1から100の間でランダムな整数を生成する関数です。$target
: ゲームの「正解」となるランダムな数字を格納します。$attempts
: ユーザーが入力を行った回数を記録する変数です。初期値は0に設定します。
ユーザーの入力を取得するループ
while (true) { echo "数字を入力してください: "; $input = trim(fgets(STDIN));
while (true)
: 無限ループを作成します。ユーザーが正解を当てるまで繰り返します。fgets(STDIN)
: ユーザーからの入力を取得する関数です。trim()
: ユーザーの入力から不要な空白や改行を取り除く関数です。
入力が数字かどうかをチェック
if (!is_numeric($input)) { echo "数字を入力してください!" . PHP_EOL; continue; }
is_numeric($input)
: 入力が数値かどうかを判定する関数です。- 数字や数字として扱える文字列(例:
"123"
,"45.67"
)の場合はtrue
を返します。 - それ以外(例:
"abc"
,"123abc"
)の場合はfalse
を返します。
- 数字や数字として扱える文字列(例:
!is_numeric($input)
: 入力が数値でない場合の処理を表します。continue
: 現在のループを中断し、次の繰り返しに進みます。
数値に変換し、判定を行う
$guess = (int)$input; $attempts++;
(int)$input
: 入力された値を整数型に変換します。$attempts++
: ユーザーが入力を行った回数を1増やします。
ユーザーの入力と正解を比較
if ($guess < $target) { echo "もっと大きい数字です!" . PHP_EOL; } elseif ($guess > $target) { echo "もっと小さい数字です!" . PHP_EOL; } else { echo "おめでとうございます!正解は {$target} でした。" . PHP_EOL; echo "あなたは {$attempts} 回目で正解しました。" . PHP_EOL; break; }
if-elseif-else
: 条件分岐を行います。- 入力が正解より小さい場合は「もっと大きい数字です!」と表示。
- 入力が正解より大きい場合は「もっと小さい数字です!」と表示。
- 正解した場合はメッセージを表示し、
break
でループを終了します。
{$target}
: 変数の値を文字列内に埋め込んで表示します。
まとめ
このコードでは、ランダムな数字を当てるというシンプルなゲームを通じて、以下の内容を学べます:
- PHPでのユーザー入力の取得方法(
fgets
,trim
)。 - 条件分岐(
if-elseif-else
)の使い方。 - 入力が有効かどうかを確認する方法(
is_numeric
)。 - 無限ループ(
while (true)
)の使用例。
このプログラムを理解することで、PHPの基本的な制御構造やユーザー入力の扱い方に慣れることができます。
ぜひこの知識を活用して、他のゲームやツールを作ってみてください!