Pythonで数当てゲームを作ろう|random・while文を使った初心者向け実践

プログラミング

STEP 3 / 小さな作品をつくる

変数・条件分岐・繰り返しを組み合わせて、コンピューターが選んだ数字を当てるゲームを作りましょう。「もっと大きい」「もっと小さい」というヒントを頼りに、正解を探します。

学習の目安:30〜45分 | 用意するもの:Python 3が動くパソコン

この記事のゴールは、完成したコードを動かし、正解するまで繰り返す仕組みを自分の言葉で説明できることです。

1.まずは完成イメージで遊ぼう

正解は1〜100の整数です。入力のたびにヒントが出ます。正解するまでに何回かかるか挑戦してみましょう。

ひみつの数字を当てよう

ゲームを準備しています。JavaScriptを有効にすると遊べます。

挑戦回数:0回

この体験版はブラウザー用のJavaScriptで動きます。以下では、同じルールのゲームをPythonで作ります。Python版には「qで終了」の機能も付けます。

2.ゲームの手順を考えよう

  1. コンピューターが正解を1つ選ぶ。
  2. プレイヤーが予想した数を入力する。
  3. 整数かどうか、1〜100の範囲かどうかを確かめる。
  4. 正解と比べて、大小のヒントを表示する。
  5. 外れたら入力に戻り、当たったら終了する。

考えてみよう:正解を選ぶ処理を繰り返しの中に置くと、入力するたびに正解が変わってしまいます。正解を選ぶのは、ゲーム開始時の1回だけです。

3.完成コードを動かそう

次のコード全体をコピーし、number_guessing.py という名前でUTF-8で保存します。ファイル名を random.py にするとPythonの標準モジュールと名前が重なるので避けましょう。

import random

answer = random.randint(1, 100)
attempts = 0

print("数当てゲーム! 1〜100の整数を当てよう。")
print("終了したいときは q を入力してください。")

while True:
    text = input("予想した数: ").strip()
    if text.lower() == "q":
        print(f"終了します。正解は {answer} でした。")
        break

    try:
        guess = int(text)
    except ValueError:
        print("整数を入力してください。例: 50")
        continue

    if not 1 <= guess <= 100:
        print("1〜100の範囲で入力してください。")
        continue

    attempts += 1
    if guess < answer:
        print("もっと大きい数です!")
    elif guess > answer:
        print("もっと小さい数です!")
    else:
        print(f"正解! {attempts} 回で当たりました!")
        break

実行するには

保存したフォルダーでターミナル(WindowsではPowerShellなど)を開き、次のコマンドを入力します。Pythonの >>> 画面に入力するコマンドではありません。

Windowsの例

py number_guessing.py

macOS・Linuxの例

python3 number_guessing.py

コマンドが見つからない場合は、Python 3のインストール状態を確認してください。追加のライブラリのインストールは不要です。

実行結果の例

正解が42だった場合の例です。実際の正解はゲームを始めるたびにランダムに選ばれます。

数当てゲーム! 1〜100の整数を当てよう。
終了したいときは q を入力してください。
予想した数: 50
もっと小さい数です!
予想した数: 25
もっと大きい数です!
予想した数: 42
正解! 3 回で当たりました!

4.コードを5つに分けて理解しよう

① randomで正解を選ぶ

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

import random は乱数を扱う標準モジュールを読み込みます。randint(1, 100) は1と100を含む整数を選びます。結果を変数 answer に保存しておきます。

② inputで文字を受け取り、intで整数にする

input() の戻り値は文字列です。数の大小を比べる前に int(text) で整数に変換します。strip() は入力の前後の空白を取り除きます。lower() を使っているので、終了は小文字のqでも大文字のQでもできます。

③ 入力ミスはtry / exceptで受け止める

例えば abc や 1.5 は int() で整数にできず、ValueError になります。except ValueError: で説明を表示し、continue で次の入力へ戻ります。整数でも0や101は範囲外なので、別の条件でやり直します。

④ if / elif / elseで3通りに分ける

guess < answer なら「もっと大きい」、guess > answer なら「もっと小さい」です。どちらでもなければ同じ数なので正解です。比較はプレイヤーの予想を基準に考えましょう。

⑤ while・break・カウンターを組み合わせる

while True: は繰り返しを続けます。正解またはqの入力で break を実行するとループが終わります。attempts += 1 は回数を1増やす書き方です。入力チェックを通過した後に置くことで、入力ミスを回数に含めません。f文字列の {attempts} には、その時点の回数が入ります。

5.動作を確かめよう

  • 小さすぎる数、大きすぎる数を入力すると、対応するヒントが出る。
  • 正解すると、正しい挑戦回数を表示して終了する。
  • abc・空欄・1.5は入力し直しになり、回数が増えない。
  • 0・101は範囲外になり、1と100は予想として受け付ける。
  • qまたはQで終了できる。

テストの間だけ answer = 42 にすると正解・不正解を確実に確認できます。確認後は random.randint(1, 100) に戻しましょう。

6.自分のゲームに改造しよう

課題1:数字の範囲を1〜1000にする

乱数を作る部分だけでなく、入力チェックと案内文も合わせて変更しましょう。

ヒントを見る

random.randint(1, 1000) と 1 <= guess <= 1000 に変更します。画面の「1〜100」という文章も「1〜1000」にします。値を max_number = 1000 にまとめると、次から変更しやすくなります。

課題2:5回までの挑戦にする

5回目に正解した場合は勝ち、5回目に外した場合だけゲームオーバーにしてみましょう。

追加するコードを見る

完成コードの正解判定の if / elif / else 全体の後に、次を追加します。if attempts の前は半角スペース4個です。正解時は先にbreakするため、5回目の正解も成功になります。

    if attempts >= 5:
        print(f"ゲームオーバー。正解は {answer} でした。")
        break

課題3:少ない回数で当てる作戦を考える

最初は50、もっと大きければ75のように、残った範囲の真ん中を選んでみましょう。範囲をほぼ半分に絞る方法なら、1〜100の整数は最大7回で見つけられます。ランダムに予想する方法と比べてみてください。

よくあるつまずき

  • IndentationError:行頭の字下げを確認します。whileの中は半角スペース4個、その中のifなどはさらに4個です。
  • SyntaxError:コロン「:」、引用符、括弧が欠けていないか確認します。全角の記号ではなく、コードをそのままコピーして試しましょう。
  • 正解が毎回変わってしまう:answerを決める行がwhileより前にあるか確認します。
  • 入力ミスでも回数が増える:attemptsを増やす行を、2つの入力チェックの後に置きます。

学びを振り返ろう

「正解を保存する変数」「答えを比べる条件分岐」「入力を続けるループ」がつながると、1つのゲームになります。コードを見ずに手順を説明できたら、範囲や回数制限を変えて自分の作品にしてみましょう。

仕様の参考:Python公式ドキュメント:random.randint / エラーと例外

現役のフリーランスWebエンジニアです。仕事ではWebサイトや業務アプリをつくっています。
学生のころの自分に「これがあれば分かったのに」と思う教材を目指して、LIST LEARNを書いています。じゃんけんゲームなどの小さな作品を一緒につくりながら、情報Ⅰ・Pythonの基礎を身につけましょう。
取得資格: 応用情報技術者試験/第二種情報処理技術者

木下 | 現役Webエンジニアをフォローする
プログラミング