【Python】レッスン4-☆2:ナインゲームを作ろう

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

この記事の練習問題で使用する知識:
1.基礎文法、2.制御構造、3.関数とスコープ、4.データ構造、5.オブジェクト指向

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

<<前のページ Python記事一覧
次のページ>>

練習問題4-☆2:Pythonでナインゲームを作ろう

プレイヤーとコンピュータが交互に牌を選んで得点を競う「ナインゲーム」を作成しましょう。

プレイヤーは1から9までの数字を持ち、毎回選んだ牌の数字で勝敗が決まります。

選ばれた牌は使えなくなり、最後に得点が高い方が勝者となります。

問題の詳細条件

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

  • ゲーム開始時に「ナインゲームを開始します!」と表示すること。
  • プレイヤーとコンピュータは最初に1から9までの数字の牌を持つこと。
  • 各ターンでプレイヤーが出す牌を入力し、コンピュータが出す牌はランダムに選択すること。
  • 牌を出す前に両者の現在の得点を表示すること。
  • プレイヤーが牌を選択する前に、両者の持っている牌を表示すること。持っていない牌は「-」と表示すること。
  • 牌を選択した後、両者が出した牌を比較し、大きい数字を出した方にその数字と同じ得点を加算すること。
  • 勝負の結果を表示すること。
  • 全ての牌を出し終えたら最終的な得点を比較し、勝者を表示すること。

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

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

ナインゲームを開始します!

【第1回戦】
プレイヤーの得点 : 0点
コンピュータの得点: 0点
☆プレイヤーの持ち牌⇒【1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9】
コンピュータの持ち牌⇒【1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9】
持ち牌の中から出す牌を選択してください > 5
プレイヤーの打牌:5 > 3:コンピュータの打牌
プレイヤーは5点獲得

【第2回戦】
プレイヤーの得点 : 5点
コンピュータの得点: 0点
...

【ヒント】難しいと感じる人だけ見よう

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

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

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

1:Randomモジュールのインポート
2:関数display_tilesの定義
  □ f文字列とリスト内包表記でtilesリストの内容をフォーマットして出力
3:関数display_scoresの定義
  □ プレイヤーとコンピュータの得点をf文字列で出力
4:関数get_player_choiceの定義
  □ while文で無効な選択を防ぎ、int型に変換したユーザー入力を返す
5:関数get_computer_choiceの定義
  □ Randomモジュールを使用してtilesリストからランダムな値を選択し返す
6:main関数の定義
  □ リストplayer_tilesとcomputer_tilesに1から9までの数値を格納
  □ 変数player_scoreとcomputer_scoreに0を代入
7:「ナインゲームを開始します!」と出力
8:forループで9回のゲームを行う
  □ 現在の得点をdisplay_scores関数で表示
  □ プレイヤーとコンピュータの持ち牌をdisplay_tiles関数で表示
  □ get_player_choice関数でプレイヤーの選択を受け取り、変数player_choiceに代入
  □ get_computer_choice関数でコンピュータの選択を受け取り、変数computer_choiceに代入
9:if文でプレイヤーの打牌とコンピュータの打牌を比較
  □ プレイヤーの打牌が大きい場合、得点を加算
  □ コンピュータの打牌が大きい場合、得点を加算
  □ 引き分けの場合、得点はなし
10:使用した牌をリストから削除し、値を「-」に変更
11:ゲーム終了後、最終的な得点を表示
12:プレイヤーの得点がコンピュータを上回れば勝利メッセージを表示
  □ コンピュータの勝利なら敗北メッセージを表示
  □ 引き分けなら引き分けメッセージを表示
13:main関数を呼び出してゲームを開始

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

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

import random

def display_tiles(title, tiles):
    print(f"{title}⇒【", end="")
    print(" ,".join([str(tile) if tile != -1 else "-" for tile in tiles]), end="")
    print("】")

def display_scores(player_score, computer_score):
    print(f"プレイヤーの得点 : {player_score}点")
    print(f"コンピュータの得点: {computer_score}点")

def get_player_choice(tiles):
    while True:
        try:
            """【穴埋め問題1】
            ここでプレイヤーが持ち牌の中から選択し、無効な選択を防ぐためのコードを書いてください。
            """
        except ValueError:
            print("数字を入力してください。")

def get_computer_choice(tiles):
    """【穴埋め問題2】
    ここでランダムにコンピュータの持ち牌を選択するコードを書いてください。
    """

def main():
    player_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    computer_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]

    player_score = 0
    computer_score = 0

    print("ナインゲームを開始します!")

    for round_num in range(1, 10):
        print(f"\n【第{round_num}回戦】")
        display_scores(player_score, computer_score)
        display_tiles("☆プレイヤーの持ち牌", player_tiles)
        display_tiles("コンピュータの持ち牌", computer_tiles)

        """【穴埋め問題3】
        ここでプレイヤーの持ち牌から選択を受け取り、選択済みの牌を無効にするコードを書いてください。
        """
        """【穴埋め問題4】
        ここでコンピュータの持ち牌からランダムに選択を行い、選択済みの牌を無効にするコードを書いてください。
        """

        """【穴埋め問題5】
        プレイヤーとコンピュータの選んだ牌を比較し、得点計算を行うコードを書いてください。
        """

    print("\nゲーム終了!")
    display_scores(player_score, computer_score)

    if player_score > computer_score:
        print("プレイヤーの勝利です!")
    elif player_score < computer_score:
        print("コンピュータの勝利です!")
    else:
        print("引き分けです!")

if __name__ == "__main__":
    main()

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

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

問題の答え合わせと解説

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

一つの正解例

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

import random

def display_tiles(title, tiles):
    print(f"{title}⇒【", end="")
    print(" ,".join([str(tile) if tile != -1 else "-" for tile in tiles]), end="")
    print("】")

def display_scores(player_score, computer_score):
    print(f"プレイヤーの得点 : {player_score}点")
    print(f"コンピュータの得点: {computer_score}点")

def get_player_choice(tiles):
    while True:
        try:
            choice = int(input("持ち牌の中から出す牌を選択してください > "))
            if choice in tiles:
                return choice
            else:
                print("無効な選択です。再度選択してください。")
        except ValueError:
            print("数字を入力してください。")

def get_computer_choice(tiles):
    return random.choice(tiles)

def main():
    # プレイヤーとコンピュータの持ち牌(1〜9)
    player_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    computer_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]

    # プレイヤーとコンピュータの得点
    player_score = 0
    computer_score = 0

    print("ナインゲームを開始します!")

    for round_num in range(1, 10):
        # 現在の回戦を表示
        print(f"\n【第{round_num}回戦】")

        # 現在の得点を表示
        display_scores(player_score, computer_score)

        # 現在の持ち牌を表示
        display_tiles("☆プレイヤーの持ち牌", player_tiles)
        display_tiles("コンピュータの持ち牌", computer_tiles)

        # プレイヤーが牌を選択
        player_choice = get_player_choice([tile for tile in player_tiles if tile != -1])

        # コンピュータが牌を選択
        computer_choice = get_computer_choice([tile for tile in computer_tiles if tile != -1])

        # 両者の牌を比較し、結果を表示
        print(f"プレイヤーの打牌:{player_choice}", end="")
        if player_choice > computer_choice:
            print(f" > {computer_choice}:コンピュータの打牌")
            player_score += player_choice
            print(f"プレイヤーは{player_choice}点獲得")
        elif player_choice < computer_choice:
            print(f" < {computer_choice}:コンピュータの打牌")
            computer_score += computer_choice
            print(f"コンピュータは{computer_choice}点獲得")
        else:
            print(f" = {computer_choice}:コンピュータの打牌")
            print("引き分けです。得点はなし")

        # 使用した牌を無効にする
        player_tiles[player_tiles.index(player_choice)] = -1
        computer_tiles[computer_tiles.index(computer_choice)] = -1

    # 最終結果を表示
    print("\nゲーム終了!")
    display_scores(player_score, computer_score)

    if player_score > computer_score:
        print("プレイヤーの勝利です!")
    elif player_score < computer_score:
        print("コンピュータの勝利です!")
    else:
        print("引き分けです!")

if __name__ == "__main__":
    main()

正解例の詳細解説

このコードは「ナインゲーム」というゲームを実装しています。

プレイヤーとコンピュータが交互に牌を出し合い、大きい方が得点を得るというシンプルなルールです。このゲームを通して、基本的なリストの操作や条件分岐、ループなど、Pythonの基本文法を学ぶことができます。

display_tiles 関数

def display_tiles(title, tiles):
    print(f"{title}⇒【", end="")
    print(" ,".join([str(tile) if tile != -1 else "-" for tile in tiles]), end="")
    print("】")

この関数はプレイヤーとコンピュータの持ち牌を見やすく表示するためのものです。

リストに含まれる数字(1〜9)を表示し、すでに使用済みの牌は - と表示します。

  • join メソッド:リストの各要素をカンマで区切って1つの文字列にします。
  • リスト内包表記:[str(tile) if tile != -1 else "-"] という部分で、-1 となっている使用済みの牌は "-" として表示されます。

display_scores 関数

def display_scores(player_score, computer_score):
    print(f"プレイヤーの得点 : {player_score}点")
    print(f"コンピュータの得点: {computer_score}点")

この関数は現在の得点を表示します。

プレイヤーとコンピュータそれぞれの得点を表示するため、f 文字列を使って得点をフォーマットしています。

get_player_choice 関数

def get_player_choice(tiles):
    while True:
        try:
            choice = int(input("持ち牌の中から出す牌を選択してください > "))
            if choice in tiles:
                return choice
            else:
                print("無効な選択です。再度選択してください。")
        except ValueError:
            print("数字を入力してください。")

プレイヤーが持ち牌から選んで打牌するための関数です。

入力が有効であるかチェックし、無効な入力がされた場合は再度入力を促します。

  • try-except:プレイヤーが数字以外を入力した場合、エラーを防ぎ、再入力を促すための構造です。
  • input 関数:コンソールからユーザーの入力を取得します。

get_computer_choice 関数

def get_computer_choice(tiles):
    return random.choice(tiles)

コンピュータがランダムに牌を選ぶための関数です。

random.choice() を使用して、与えられたリストからランダムに1つの牌を選びます。

メインの処理 (main 関数)

def main():
    player_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    computer_tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    player_score = 0
    computer_score = 0

ゲームの主な流れを処理する関数です。

プレイヤーとコンピュータの持ち牌をリストで定義し、得点は初期値として 0 に設定されます。

ゲームのメインループ

for round_num in range(1, 10):
    print(f"\n【第{round_num}回戦】")
    display_scores(player_score, computer_score)
    display_tiles("☆プレイヤーの持ち牌", player_tiles)
    display_tiles("コンピュータの持ち牌", computer_tiles)

ここでは9回戦をループで繰り返します。各ラウンドの開始時に現在の持ち牌と得点を表示します。

  • range(1, 10):1から9までの範囲でループを実行します。

プレイヤーとコンピュータの牌の選択

player_choice = get_player_choice([tile for tile in player_tiles if tile != -1])
computer_choice = get_computer_choice([tile for tile in computer_tiles if tile != -1])

プレイヤーは有効な牌から1つを選び、コンピュータもランダムに1つ選択します。

選んだ牌は -1 に置き換えられ、次のラウンドでは使用できなくなります。

結果の判定と得点の計算

if player_choice > computer_choice:
    player_score += player_choice
    print(f"プレイヤーは{player_choice}点獲得")
elif player_choice < computer_choice:
    computer_score += computer_choice
    print(f"コンピュータは{computer_choice}点獲得")
else:
    print("引き分けです。得点はなし")

プレイヤーとコンピュータの出した牌を比較し、大きい方が得点を得ます。

同じ牌が選ばれた場合は引き分けとなります。

最終結果の表示

if player_score > computer_score:
    print("プレイヤーの勝利です!")
elif player_score < computer_score:
    print("コンピュータの勝利です!")
else:
    print("引き分けです!")

全てのラウンドが終了した後、最終的な得点を比較して勝者を決定します。

まとめ

このプログラムはシンプルなゲームを通してPythonの基本的な文法を学ぶ良い練習になります。

リスト操作、条件分岐、ループ、関数の使い方など、実践的なスキルを身に付けることができます。

次は、さらに複雑なゲームや処理に挑戦してみましょう!

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

<<前のページ Python記事一覧
次のページ>>

質問用コンタクトフォーム

この記事はAIを用いて書いた記事です。

人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。






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