【Python】レッスン2-☆2:数字当てゲームを作ろう

記事内に商品プロモーションを含む場合があります

この記事の練習問題で使用する知識:
レッスン1の知識比較演算子と論理演算子条件分岐(if-else文)条件分岐(elif文)条件分岐(match文)繰り返し処理(for文)繰り返し処理(while文)繰り返しの制御エラーメッセージ例外処理の基礎

Pythonのゲームコード一覧はこちら

<<前の問題 問題集Top 次の問題>>

練習問題2-☆2:数字当てゲームを作ろう

1から100までのランダムな数値を生成し、プレイヤーにその数を予測させる数値当てゲームを作成しましょう。

プレイヤーには10回の予測チャンスが与えられます。プレイヤーが予測するたびに、予測が正解かどうか、または正解よりも大きいか小さいかを表示します。

プレイヤーが正解の数値を当てることができたらゲームは終了しますが、10回の予測が終わった後も正解を当てられなければ、正解の数値が表示されてゲーム終了です。

この問題の要件

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

  • 1から100までのランダムな数値を生成し、それを correct_number に格納すること。
  • 予測できる回数を max_attempts に10として設定すること。
  • プレイヤーの予測をループで繰り返し、入力が数値でない場合はエラーメッセージを表示すること。
  • プレイヤーの予測が正解の数値と比較し、正解よりも小さいか大きいかを表示すること。
  • 正解が当たった場合、その回数を表示してゲームを終了すること。
  • 10回予測しても当てられなかった場合、正解の数値を表示すること。

ただし、以下のような実行結果となるコードを書くこと。

*****↓↓正解コードの実行結果の例↓↓*****

1から100までの数字を当ててください!
あなたには 10 回のチャンスがあります。
あなたの予測: 50
もっと大きい数字です。
残りのチャンスは 9 回です。
あなたの予測: 75
もっと小さい数字です。
残りのチャンスは 8 回です。
あなたの予測: 60
もっと大きい数字です。
残りのチャンスは 7 回です。
あなたの予測: 70
もっと小さい数字です。
残りのチャンスは 6 回です。
あなたの予測: 65
おめでとうございます!正解です!5 回目で当てました。

この問題を解くヒント

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

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

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

1:Randomモジュールのインポート
2:1から100までのランダムな数字を生成し、変数correct_numberに代入
3:変数max_attemptsに10を代入
4:「1から100までの数字を当ててください!」と出力
5:f文字列を使って「あなたには {max_attempts} 回のチャンスがあります。」と出力
6:変数attemptsに0を代入
7:while文によるループ開始
  □ユーザーに数値を入力させ、int型に変換して変数guessに代入
  □変数attemptsに1を加算する
  □if文にてguessの値がcorrect_numberの値と等しいか判定
  □□真の場合、f文字列を使って「おめでとうございます!正解です!{attempts} 回目で当てました。」と出力し、breakにてループを終了
  □elif文にてguessの値がcorrect_numberの値より小さいか判定
  □□真の場合、「もっと大きい数字です。」と出力
  □else文
  □□「もっと小さい数字です。」と出力
  □f文字列を使って「残りのチャンスは {remaining_attempts} 回です。」と出力
8:except文でValueErrorをキャッチし、「無効な入力です。数字を入力してください。」と出力
9:if文にてattemptsの値がmax_attemptsと等しいか判定
  □真の場合、f文字列を使って「残念!正解は {correct_number} でした。」と出力

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

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

import random

# 1から100までのランダムな数字を生成
"""【穴埋め問題1】
ここにrandomを使って、1から100までのランダムな数値を生成し、correct_numberに代入するコードを書いてください。
"""

# 予測できる回数を設定
"""【穴埋め問題2】
ここにmax_attemptsに10を代入するコードを書いてください。
"""

# ゲーム開始メッセージ
print("1から100までの数字を当ててください!")
"""【穴埋め問題3】
ここにf文字列を使って、max_attemptsを表示するコードを書いてください。
"""

# 現在の試行回数をカウント
"""【穴埋め問題4】
ここにattempts変数を0に初期化するコードを書いてください。
"""

# プレイヤーの予測をループで繰り返す
while attempts < max_attempts:
    try:
        """【穴埋め問題5】
        ここにプレイヤーからの入力を数値として取得し、guessに代入するコードを書いてください。
        """

        # 試行回数を1増やす
        attempts += 1

        # 予測が正解の場合
        if guess == correct_number:
            """【穴埋め問題6】
            ここにf文字列を使って正解メッセージを表示するコードを書いてください。試行回数も表示してください。
            """
            break
        # 予測が正解より小さい場合
        elif guess < correct_number:
            print("もっと大きい数字です。")
        # 予測が正解より大きい場合
        else:
            print("もっと小さい数字です。")

        """【穴埋め問題7】
        ここに残りのチャンスを表示するために、remaining_attemptsを計算してf文字列で表示するコードを書いてください。
        """

    except ValueError:
        # 入力が数値でない場合のエラーメッセージ
        print("無効な入力です。数字を入力してください。")

# 回数制限に達した場合のメッセージ
if attempts == max_attempts:
    """【穴埋め問題8】
    ここにf文字列を使って正解の数字を表示するコードを書いてください。
    """

この問題の穴埋めコードは以上です。

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

解答例と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

import random

# 1から100までのランダムな数字を生成
correct_number = random.randint(1, 100)

# 予測できる回数を設定
max_attempts = 10

# ゲーム開始メッセージ
print("1から100までの数字を当ててください!")
print(f"あなたには {max_attempts} 回のチャンスがあります。")

# 現在の試行回数をカウント
attempts = 0

# プレイヤーの予測をループで繰り返す
while attempts < max_attempts:
    try:
        # プレイヤーの入力を数値として取得
        guess = int(input("あなたの予測: "))
        
        # 試行回数を1増やす
        attempts += 1
        
        # 予測が正解の場合
        if guess == correct_number:
            print(f"おめでとうございます!正解です!{attempts} 回目で当てました。")
            break
        # 予測が正解より小さい場合
        elif guess < correct_number:
            print("もっと大きい数字です。")
        # 予測が正解より大きい場合
        else:
            print("もっと小さい数字です。")
        
        # 残りの試行回数を表示
        remaining_attempts = max_attempts - attempts
        print(f"残りのチャンスは {remaining_attempts} 回です。")
    
    except ValueError:
        # 入力が数値でない場合のエラーメッセージ
        print("無効な入力です。数字を入力してください。")
    
# 回数制限に達した場合のメッセージ
if attempts == max_attempts:
    print(f"残念!正解は {correct_number} でした。次回はもっと頑張りましょう!")
◇◆◇ちょうど10回目で正解すると、このコードはどうなる???◇◆◇

上記の正解コードには一つ問題があり、ちょうど10回目で正解したときには「正解のメッセージ」と「回数制限到達のメッセージ」が両方表示されてしまいます。

ご指摘して下さった読者の方、ありがとうございます^^。
気付いていなかった方は、まずなぜそうなるのかを考えてみましょう。

そして、これを回避するにはどうすれば良いでしょうか?

色々なやり方がありますが、ここでは「正解したかどうかをフラグで管理する」方法を紹介します。

以下のように is_correct というフラグを追加し、その値に応じてメッセージを表示することで、どちらか一方のみのメッセージを表示できるようになります。

import random

# 1から100までのランダムな数字を生成
correct_number = random.randint(1, 100)

# 予測できる回数を設定
max_attempts = 10

# ゲーム開始メッセージ
print("1から100までの数字を当ててください!")
print(f"あなたには {max_attempts} 回のチャンスがあります。")

# 現在の試行回数をカウント
attempts = 0

# 正解したかどうかのフラグ
is_correct = False

# プレイヤーの予測をループで繰り返す
while attempts < max_attempts:
    try:
        # プレイヤーの入力を数値として取得
        guess = int(input("あなたの予測: "))
        
        # 試行回数を1増やす
        attempts += 1
        
        # 予測が正解の場合
        if guess == correct_number:
            print(f"おめでとうございます!正解です!{attempts} 回目で当てました。")
            is_correct = True  # 正解したのでフラグをTrueに
            break
        # 予測が正解より小さい場合
        elif guess < correct_number:
            print("もっと大きい数字です。")
        # 予測が正解より大きい場合
        else:
            print("もっと小さい数字です。")
        
        # 残りの試行回数を表示
        remaining_attempts = max_attempts - attempts
        print(f"残りのチャンスは {remaining_attempts} 回です。")
    
    except ValueError:
        # 入力が数値でない場合のエラーメッセージ
        print("無効な入力です。数字を入力してください。")
    
# 回数制限に達した場合のメッセージ
if is_correct == True:
    print("ゲームクリア!おめでとうございます!") # 何も表示しなければ、最初の正解コードと同じになる。
else:
    print(f"残念!正解は {correct_number} でした。次回はもっと頑張りましょう!")

このように修正することで、今回の問題は解決できます。

是非両方のコードを実行し、違いを見比べてみて下さい。

正解コードの解説

このプログラムは1から100までのランダムな数をプレイヤーに予測させるゲームを実装しています。

以下でコードをブロックごとに分解し、使われている文法や処理について説明します。

ランダムな数値を生成

import random
correct_number = random.randint(1, 100)

random モジュールをインポートし、その中の randint 関数を使って1から100までのランダムな整数を生成しています。

生成された数値は correct_number という変数に保存されます。これはゲームの正解の数になります。

予測回数を設定

max_attempts = 10

この行ではプレイヤーが予測できる最大の回数を max_attempts という変数に10として設定しています。

プレイヤーは10回まで予測できます。

ゲーム開始メッセージの表示

print("1から100までの数字を当ててください!")
print(f"あなたには {max_attempts} 回のチャンスがあります。")

print 関数を使ってゲームの開始メッセージとプレイヤーの予測できる回数を表示しています。

ここで f"..." の形式を使って、変数 max_attempts の値を文字列に埋め込んでいます。

試行回数の初期化

attempts = 0

attempts という変数に0を代入して試行回数を初期化しています。

この変数はプレイヤーが何回予測を行ったかをカウントするために使います。

プレイヤーの予測とゲームのループ

while attempts < max_attempts:
    try:
        guess = int(input("あなたの予測: "))
        attempts += 1

while ループはプレイヤーが最大回数(max_attempts)に達するまで繰り返されます。

input 関数を使ってプレイヤーの予測を入力として受け取ります。この入力は int で数値に変換され、guess に保存されます。

また、プレイヤーが予測をするたびに試行回数 attempts が1増加します。

予測が正しいかどうかの判定

if guess == correct_number:
    print(f"おめでとうございます!正解です!{attempts} 回目で当てました。")
    break
elif guess < correct_number:
    print("もっと大きい数字です。")
else:
    print("もっと小さい数字です。")

if-elif-else 文で、プレイヤーの予測が正解かどうかを判定しています。

正解だった場合はプレイヤーに「おめでとうございます!」というメッセージが表示され、ループを break で終了します。

もし予測が正解の数より小さければ「もっと大きい数字です。」と表示し、逆に大きければ「もっと小さい数字です。」と表示します。

残りの試行回数の表示

remaining_attempts = max_attempts - attempts
print(f"残りのチャンスは {remaining_attempts} 回です。")

プレイヤーが予測を行うたびに残りの試行回数が計算され、それが print 関数を使って表示されます。

無効な入力の処理

except ValueError:
    print("無効な入力です。数字を入力してください。")

もしプレイヤーが数値以外の入力をした場合、ValueError というエラーが発生します。

これを except ブロックで捕捉し、「無効な入力です。数字を入力してください。」というメッセージを表示します。

ゲーム終了時の処理

if attempts == max_attempts:
    print(f"残念!正解は {correct_number} でした。次回はもっと頑張りましょう!")

プレイヤーが予測できる最大回数に達した場合はゲームは終了し、正解の数を表示します。

このメッセージでゲームが終了します。

Pythonのゲームコード一覧はこちら

<<前の問題 問題集Top 次の問題>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Python記事トップへ戻る
    トップページへ戻る