MENU

【PHP】Lesson3-☆1:関数を使って石取りゲームを作ろう

tggaa478@yahoo.co.jp

Lesson3で学習した内容を応用して簡単なゲームを作成しましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編

 ・Lesson3-1:ビルトイン関数を理解しよう
 ・Lesson3-2:関数の基本を理解しよう
 ・Lesson3-3:関数の戻り値を理解しよう
 ・Lesson3-4:デフォルト引数とキーワード引数を理解しよう
 ・Lesson3-5:関数の型付けを理解しよう
 ・Lesson3-6:無名関数とアロー関数を理解しよう
 ・Lesson3-7:スコープを理解しよう
 ・確認問題3-1:石取りゲームを作ろう ◁今回はココ
 ・確認問題3-2:丁半賭博ゲームを作ろう
 ・確認問題3-3:モンスターとのバトルゲームを作ろう
Lesson4:データ構造編
Lesson5:クラス

<<前のページ

学習記事一覧

次のページ>>

演習問題|PHPで関数を活用した石取りゲームを作ろう

PHPで石取りゲームを作成しましょう。

このゲームでは20個の石をプレイヤーとコンピュータが交互に取り合います。1回のターンで取れる石の最大数は3個です。

最終的に石を取らなければならないプレイヤーが負けとなります。

プログラムは以下の機能を備えます:

  • 勝敗判定を行う。
  • 現在の石の数を表示する。
  • プレイヤーが取る石の数を入力できる。
  • コンピュータがランダムに石を取る。

この演習の要件

以下の要件に従ってコードを完成させてください。

  1. 初期設定
    • 石の総数を $totalStones = 20 とする。
    • 1度に取れる最大数を $maxPick = 3 とする。
  2. 関数の定義
    • 残りの石の数を表示する関数 displayStones($totalStones) を作成する。
    • プレイヤーの入力を取得し、条件を満たす値のみ受け付ける関数 getPlayerPick($maxPick, $totalStones) を作成する。
    • コンピュータがランダムで石を取る関数 getComputerPick($maxPick, $totalStones) を作成する。
  3. ゲームの進行
    • プレイヤーとコンピュータが交互に石を取る処理を実装する。
    • 取った石の数と残りの石の数を表示する。
    • 石を取った後に勝敗判定を行う。
  4. 終了条件
    • 残りの石が0になった場合、そのターンのプレイヤーが負けと表示する。

ただし、以下のような実行結果となること。

石取りゲームを開始します!
残りの石の数: 20
何個の石を取りますか? (1〜3個): 3
プレイヤーは3個の石を取りました。
残りの石の数: 17
コンピュータは2個の石を取りました。
残りの石の数: 15
何個の石を取りますか? (1〜3個): 3
プレイヤーは3個の石を取りました。
残りの石の数: 12
コンピュータは3個の石を取りました。
残りの石の数: 9
何個の石を取りますか? (1〜3個): 2
プレイヤーは2個の石を取りました。
残りの石の数: 7
コンピュータは3個の石を取りました。
残りの石の数: 4
何個の石を取りますか? (1〜3個): 3
プレイヤーは3個の石を取りました。
残りの石の数: 1
コンピュータは1個の石を取りました。
コンピュータの負けです!
ゲーム終了!

解き方のヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:「石取りゲームを開始します!」を出力
2:変数$totalStonesに20を代入(石の総数)
3:変数$maxPickに3を代入(一度に取れる最大数)
4:関数displayStonesの定義(引数$totalStonesを受け取る)
  □ 「残りの石の数: {$totalStones}」を出力
5:関数getPlayerPickの定義(引数$maxPick, $totalStonesを受け取る)
  □ whileループを開始(無効入力を繰り返しチェック)
  □ □ 「何個の石を取りますか? (1〜{$maxPick}個): 」を出力
  □ □ 標準入力から値を取得し、整数に変換して変数$pickに代入
  □ □ if文で$pickが条件(1〜$maxPickかつ$totalStones以下)を満たすか判定
  □ □ □ 条件を満たした場合、$pickを返す
  □ □ 条件を満たさない場合、「無効な入力です。再入力してください。」を出力
6:関数getComputerPickの定義(引数$maxPick, $totalStonesを受け取る)
  □ 変数$pickにmin($maxPick, $totalStones)の値を代入
  □ 変数$pickを1〜$pickの範囲でランダムに取得し返す
7:whileループを開始($totalStonesが0より大きい間繰り返す)
  □ displayStones関数を呼び出し、石の状態を表示
  □ プレイヤーのターン開始
  □ □ getPlayerPick関数を呼び出し、プレイヤーの取る石の数を取得
  □ □ $totalStonesから取得した数を減算
  □ □ 「プレイヤーは{$playerPick}個の石を取りました。」を出力
  □ □ if文で$totalStonesが0になったか判定
  □ □ □ 0の場合、「プレイヤーの負けです!」を出力しbreakで終了
  □ displayStones関数を再度呼び出し、石の状態を表示
  □ コンピュータのターン開始
  □ □ getComputerPick関数を呼び出し、コンピュータの取る石の数を取得
  □ □ $totalStonesから取得した数を減算
  □ □ 「コンピュータは{$computerPick}個の石を取りました。」を出力
  □ □ if文で$totalStonesが0になったか判定
  □ □ □ 0の場合、「コンピュータの負けです!」を出力しbreakで終了
8:「ゲーム終了!」を出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

<?php
echo "石取りゲームを開始します!" . PHP_EOL;

// 初期設定
$totalStones = 20; // 石の総数
$maxPick = 3;      // 一度に取れる最大数

// 現在の石の数を表示する関数
function displayStones($totalStones) {
    echo "残りの石の数: {$totalStones}" . PHP_EOL;
}

// プレイヤーの入力を取得する関数
function getPlayerPick($maxPick, $totalStones) {
    while (true) {
        /*
        【穴埋め問題1】ここでプレイヤーから入力を取得し、整数に変換して返すコードを書いてください。
        */
    }
}

// コンピュータの選択を決定する関数
function getComputerPick($maxPick, $totalStones) {
    /*
    【穴埋め問題2】ここでコンピュータがランダムに石を取る数を決定するコードを書いてください。
    */
}

// ゲーム開始
while ($totalStones > 0) {
    // 石の状態を表示
    displayStones($totalStones);

    // プレイヤーのターン
    $playerPick = getPlayerPick($maxPick, $totalStones);
    $totalStones -= $playerPick;
    echo "プレイヤーは{$playerPick}個の石を取りました。" . PHP_EOL;

    // 勝敗判定
    if ($totalStones == 0) {
        /*
        【穴埋め問題3】ここでプレイヤーの負けを表示するコードを書いてください。
        */
        break;
    }

    // 石の状態を表示
    displayStones($totalStones);

    // コンピュータのターン
    $computerPick = getComputerPick($maxPick, $totalStones);
    $totalStones -= $computerPick;
    echo "コンピュータは{$computerPick}個の石を取りました。" . PHP_EOL;

    // 勝敗判定
    if ($totalStones == 0) {
        /*
        【穴埋め問題4】ここでコンピュータの負けを表示するコードを書いてください。
        */
        break;
    }
}

echo "ゲーム終了!" . PHP_EOL;

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

演習問題の答え合わせ

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
<?php
echo "石取りゲームを開始します!" . PHP_EOL;

// 初期設定
$totalStones = 20; // 石の総数
$maxPick = 3;      // 一度に取れる最大数

// 現在の石の数を表示する関数
function displayStones($totalStones) {
    echo "残りの石の数: {$totalStones}" . PHP_EOL;
}

// プレイヤーの入力を取得する関数
function getPlayerPick($maxPick, $totalStones) {
    while (true) {
        echo "何個の石を取りますか? (1〜{$maxPick}個): ";
        $pick = intval(trim(fgets(STDIN)));
        if ($pick >= 1 && $pick <= $maxPick && $pick <= $totalStones) {
            return $pick;
        }
        echo "無効な入力です。再入力してください。" . PHP_EOL;
    }
}

// コンピュータの選択を決定する関数
function getComputerPick($maxPick, $totalStones) {
    $pick = min($maxPick, $totalStones); // 残りの石が少ない場合は調整
    return rand(1, $pick); // ランダムに石を取る
}

// ゲーム開始
while ($totalStones > 0) {
    // 石の状態を表示
    displayStones($totalStones);

    // プレイヤーのターン
    $playerPick = getPlayerPick($maxPick, $totalStones);
    $totalStones -= $playerPick;
    echo "プレイヤーは{$playerPick}個の石を取りました。" . PHP_EOL;

    // 勝敗判定
    if ($totalStones == 0) {
        echo "プレイヤーの負けです!" . PHP_EOL;
        break;
    }

    // 石の状態を表示
    displayStones($totalStones);

    // コンピュータのターン
    $computerPick = getComputerPick($maxPick, $totalStones);
    $totalStones -= $computerPick;
    echo "コンピュータは{$computerPick}個の石を取りました。" . PHP_EOL;

    // 勝敗判定
    if ($totalStones == 0) {
        echo "コンピュータの負けです!" . PHP_EOL;
        break;
    }
}

echo "ゲーム終了!" . PHP_EOL;
Q
正解コードの解説

コードをブロックごとに分割して解説します。

初期設定

echo "石取りゲームを開始します!" . PHP_EOL;
$totalStones = 20; // 石の総数
$maxPick = 3;      // 一度に取れる最大数
  • echo:文字列を表示する命令です。この場合「石取りゲームを開始します!」と画面に表示されます。
  • PHP_EOL:改行コードです。環境に応じた改行を追加します。
  • 変数 $totalStones:ゲームで使用する石の総数を設定します。
  • 変数 $maxPick:1回のターンで取れる最大の石の数を設定します。

残りの石を表示する関数

function displayStones($totalStones) {
    echo "残りの石の数: {$totalStones}" . PHP_EOL;
}
  • 関数 displayStones:引数 $totalStones を受け取り、残りの石の数を表示します。
  • {$totalStones}:波括弧 {} を使うことで文字列の中に変数を埋め込むことができます。

プレイヤーの入力処理

function getPlayerPick($maxPick, $totalStones) {
    while (true) {
        echo "何個の石を取りますか? (1〜{$maxPick}個): ";
        $pick = intval(trim(fgets(STDIN)));
        if ($pick >= 1 && $pick <= $maxPick && $pick <= $totalStones) {
            return $pick;
        }
        echo "無効な入力です。再入力してください。" . PHP_EOL;
    }
}
  • while (true):無限ループを作ります。正しい入力があるまで繰り返します。
  • fgets(STDIN):ユーザーからの入力を受け取ります。
  • trim:余分な空白や改行を削除します。
  • intval:文字列を整数に変換します。
  • 条件判定:入力が1〜3の範囲内かつ残りの石以下であるかをチェックします。

コンピュータの選択処理

function getComputerPick($maxPick, $totalStones) {
    $pick = min($maxPick, $totalStones); 
    return rand(1, $pick);
}
  • min:指定した値のうち最小値を返します。ここでは残りの石が最大で取れる数より少ない場合に対応します。
  • rand(1, $pick):1から $pick の間でランダムな数を生成します。

ゲームの進行処理

プレイヤーのターン
$playerPick = getPlayerPick($maxPick, $totalStones);
$totalStones -= $playerPick;
echo "プレイヤーは{$playerPick}個の石を取りました。" . PHP_EOL;
  • getPlayerPick:プレイヤーの入力を受け取ります。
  • $totalStones -= $playerPick:取った石の数だけ残りの石を減らします。
  • 結果の表示:プレイヤーが何個の石を取ったのか表示します。

勝敗判定

if ($totalStones == 0) {
    echo "プレイヤーの負けです!" . PHP_EOL;
    break;
}

if:残りの石が0ならばプレイヤーの負けと表示してループを終了します。

コンピュータのターン

$computerPick = getComputerPick($maxPick, $totalStones);
$totalStones -= $computerPick;
echo "コンピュータは{$computerPick}個の石を取りました。" . PHP_EOL;
  • getComputerPick:コンピュータがランダムに石を取ります。
  • $totalStones -= $computerPick:取った石の分だけ減らします。
  • 結果の表示:コンピュータが取った石の数を表示します。

ゲーム終了条件

if ($totalStones == 0) {
    echo "コンピュータの負けです!" . PHP_EOL;
    break;
}

コンピュータが最後の石を取った場合は負けと判定されます。

ゲーム終了メッセージ

echo "ゲーム終了!" . PHP_EOL;

最後にゲーム終了メッセージを表示します。

まとめ

このプログラムではPHPでの関数、ループ、条件分岐の使い方を学ぶことができます。
ポイントは以下の通りです:

  1. 関数の活用:繰り返し使う処理は関数化することでコードを整理できる。
  2. ユーザー入力の検証:不正な入力を防ぐチェックを入れる。
  3. ランダム処理:コンピュータの動作をランダム化してリアリティを増す。

このコードを通して、プログラムの流れやデータ処理の基礎を学べます。

ぜひ、他のゲームや機能追加に挑戦して理解を深めてください!

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいPHP学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました