【Python】レッスン3-☆1:丁半賭博ゲームを作ろう

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

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

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

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

練習問題3-☆1:丁半賭博ゲームを作ろう

サイコロを使った丁半賭博ゲームを作成しましょう。

このゲームでは、プレイヤーが掛け金を決めてサイコロの結果が「丁(偶数)」か「半(奇数)」かを予測し、勝敗を決めます。

プレイヤーが勝てば掛け金を得て、負ければ掛け金を失います。また、所持金が無くなった時点でゲームが終了します。

所持金が残っていれば、プレイヤーが続行するかどうかを選択することができます。

この問題の要件

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

  • 初期の所持金は1000円とする。
  • プレイヤーは掛け金を入力し、サイコロの目が「丁(偶数)」か「半(奇数)」かを予測する。
  • サイコロは2個振り、出た目の合計が「丁(偶数)」か「半(奇数)」かで勝敗を決定する。
  • 勝てば掛け金分だけ所持金が増え、負ければ掛け金分だけ所持金が減る。
  • ゲームを続けるかどうかを確認し、続ける場合は再びサイコロを振る。所持金が0円になった場合、ゲームは終了する。

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

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

丁半賭博ゲームを始めます!
プレイヤーの所持金: 1000円
いくらかけますか? ⇒ 500
丁か半か?(丁:0,半:1) ⇒ 1
サイコロの目: 3, 4 ⇒ 半
あなたの勝ち!賞金は500円
プレイヤーの所持金: 1500円
続けますか?(はい:0,いいえ:1) ⇒ 1
最終所持金は1500円でした。
丁半賭博ゲームを終わります。

この問題を解くヒント

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

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

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

1:Randomモジュールのインポート
2:get_bet関数の定義
  □ 無限ループを開始
  □ □ try-exceptブロック内でユーザーからの入力を整数に変換して変数betに代入
  □ □ if文でbetが1以上で所持金以下であるか判定
  □ □ □ 真の場合はbetを返す
  □ □ else文でエラーメッセージを出力
  □ □ exceptブロックでValueErrorをキャッチし、エラーメッセージを出力
3:get_choice関数の定義
  □ 無限ループを開始
  □ □ try-exceptブロック内でユーザーからの入力を整数に変換して変数choiceに代入
  □ □ if文でchoiceが0または1であるか判定
  □ □ □ 真の場合はchoiceを返す
  □ □ else文でエラーメッセージを出力
  □ □ exceptブロックでValueErrorをキャッチし、エラーメッセージを出力
4:roll_dice関数の定義
  □ randomモジュールを使い、2つのサイコロの値をランダムに生成
  □ それぞれ変数dice1とdice2に代入して返す
5:ask_continue関数の定義
  □ 無限ループを開始
  □ □ try-exceptブロック内でユーザーからの入力を整数に変換して変数continue_gameに代入
  □ □ if文でcontinue_gameが0または1であるか判定
  □ □ □ 真の場合はcontinue_gameを返す
  □ □ else文でエラーメッセージを出力
  □ □ exceptブロックでValueErrorをキャッチし、エラーメッセージを出力
6:cho_han_game関数の定義
  □ print文で「丁半賭博ゲームを始めます!」と出力
  □ 変数moneyに1000を代入して初期所持金を設定
  □ while文で所持金が0より大きい間ループ
  □ □ print文でプレイヤーの所持金を表示
  □ □ get_bet関数を呼び出し、掛け金を取得
  □ □ get_choice関数を呼び出し、丁か半かを選択
  □ □ roll_dice関数を呼び出し、2つのサイコロを振る
  □ □ サイコロの目を足して合計を変数dice_sumに代入
  □ □ print文でサイコロの目と結果(丁か半か)を表示
  □ □ if文で勝敗を判定
  □ □ □ 勝った場合、賞金を表示し、所持金を増やす
  □ □ □ 負けた場合、没収金を表示し、所持金を減らす
  □ □ if文で所持金が0より大きいか判定
  □ □ □ ask_continue関数で続行するか確認し、ゲームを続けるか判定
  □ □ □ if文でゲームを終了する場合は「最終所持金」を表示してループを抜ける
  □ □ 所持金が0以下になった場合、「所持金がなくなりました」と表示してループを抜ける
7:cho_han_game関数を呼び出してゲームを開始

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

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

import random

# 掛け金を入力する関数
def get_bet(money):
    while True:
        try:
            bet = int(input("いくらかけますか? ⇒ "))
            if bet > 0 and bet <= money:
                return bet
            else:
                print("無効な入力です!所持金以内の正しい金額を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

# 丁か半かを選択する関数
def get_choice():
    while True:
        try:
            choice = int(input("丁か半か?(丁:0,半:1) ⇒ "))
            if choice == 0 or choice == 1:
                return choice
            else:
                print("無効な入力です!0か1を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

# サイコロを振る関数
def roll_dice():
    """【穴埋め問題1】
    ここにrandomモジュールを使ってサイコロを2つ振るコードを書いてください。
    """
    return dice1, dice2

# 続けるかどうかを確認する関数
def ask_continue():
    """【穴埋め問題2】
    ここにプレイヤーがゲームを続けるかどうか確認するコードを書いてください。
    """
    return continue_game

# メインのゲーム関数
def cho_han_game():
    print("丁半賭博ゲームを始めます!")
    
    money = 1000  # プレイヤーの初期所持金
    
    while money > 0:
        print(f"プレイヤーの所持金: {money}円")
        
        # 掛け金を取得
        bet = get_bet(money)
        
        # 丁か半かの選択
        choice = get_choice()
        
        # サイコロを振る
        """【穴埋め問題3】
        ここでサイコロを振る関数を呼び出して、その結果を使って丁か半かを判断するコードを書いてください。
        """
        
        # 勝敗判定
        if (dice_sum % 2 == 0 and choice == 0) or (dice_sum % 2 != 0 and choice == 1):
            print(f"あなたの勝ち!賞金は{bet}円")
            money += bet
        else:
            print(f"あなたの負け!{bet}円没収!")
            money -= bet
        
        # 続けるかどうかを確認
        if money > 0:
            """【穴埋め問題4】
            ここでゲームを続けるかどうかを確認し、プレイヤーが終了を選んだ場合にはゲームを終了するコードを書いてください。
            """
        else:
            print("所持金がなくなりました。ゲームを終了します。")
            break

    print(f"最終所持金は{money}円でした。丁半賭博ゲームを終わります。")

# ゲームを実行
cho_han_game()

 

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

解答例と解説

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

正解コードの例

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

import random

# 掛け金を入力する関数
def get_bet(money):
    while True:
        try:
            bet = int(input("いくらかけますか? ⇒ "))
            if bet > 0 and bet <= money:
                return bet
            else:
                print("無効な入力です!所持金以内の正しい金額を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

# 丁か半かを選択する関数
def get_choice():
    while True:
        try:
            choice = int(input("丁か半か?(丁:0,半:1) ⇒ "))
            if choice == 0 or choice == 1:
                return choice
            else:
                print("無効な入力です!0か1を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

# サイコロを振る関数(リストも使わない)
def roll_dice():
    dice1 = random.randint(1, 6)
    dice2 = random.randint(1, 6)
    return dice1, dice2

# 続けるかどうかを確認する関数
def ask_continue():
    while True:
        try:
            continue_game = int(input("続けますか?(はい:0,いいえ:1) ⇒ "))
            if continue_game == 0 or continue_game == 1:
                return continue_game
            else:
                print("無効な入力です!0か1を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

# メインのゲーム関数
def cho_han_game():
    print("丁半賭博ゲームを始めます!")
    
    money = 1000  # プレイヤーの初期所持金
    
    while money > 0:
        print(f"プレイヤーの所持金: {money}円")
        
        # 掛け金を取得
        bet = get_bet(money)
        
        # 丁か半かの選択
        choice = get_choice()
        
        # サイコロを振る
        dice1, dice2 = roll_dice()
        dice_sum = dice1 + dice2
        print(f"サイコロの目: {dice1}, {dice2} ⇒ {'丁' if dice_sum % 2 == 0 else '半'}")
        
        # 勝敗判定
        if (dice_sum % 2 == 0 and choice == 0) or (dice_sum % 2 != 0 and choice == 1):
            print(f"あなたの勝ち!賞金は{bet}円")
            money += bet
        else:
            print(f"あなたの負け!{bet}円没収!")
            money -= bet
        
        # 続けるかどうかを確認
        if money > 0:
            if ask_continue() == 1:
                print(f"最終所持金は{money}円でした。")
                break
        else:
            print("所持金がなくなりました。ゲームを終了します。")
            break

    print(f"最終所持金は{money}円でした。丁半賭博ゲームを終わります。")

# ゲームを実行
cho_han_game()

正解コードの解説

このコードはサイコロを使った「丁半賭博ゲーム」をシミュレーションするものです。

プレイヤーは「丁」か「半」かを選び、サイコロの出た目の合計が偶数(丁)か奇数(半)かで勝敗が決まります。掛け金をかけ、所持金が尽きるか、プレイヤーがゲームを終了するまで繰り返します。

掛け金を入力する関数

def get_bet(money):
    while True:
        try:
            bet = int(input("いくらかけますか? ⇒ "))
            if bet > 0 and bet <= money:
                return bet
            else:
                print("無効な入力です!所持金以内の正しい金額を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

この関数はプレイヤーから掛け金を入力させます。

int()関数で文字列を整数に変換します。入力が正しい範囲内(1円以上、所持金以下)であれば掛け金を返し、不正な入力があればエラーメッセージを表示します。

tryexceptは例外処理を行うもので、不正な入力(例えば文字列が入力された場合)でもプログラムが止まらないようにしています。

丁か半かを選択する関数

def get_choice():
    while True:
        try:
            choice = int(input("丁か半か?(丁:0,半:1) ⇒ "))
            if choice == 0 or choice == 1:
                return choice
            else:
                print("無効な入力です!0か1を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

この関数はプレイヤーに「丁」(偶数)か「半」(奇数)を選ばせます。

0か1以外の入力を防ぎ、同様に例外処理で不正な入力が発生してもエラーメッセージを表示して再入力させます。

サイコロを振る関数

def roll_dice():
    dice1 = random.randint(1, 6)
    dice2 = random.randint(1, 6)
    return dice1, dice2

random.randint(1, 6)を使ってサイコロの目をランダムに決定します。

2つのサイコロの目をそれぞれdice1dice2という個別の変数に保存しています。そしてこの2つの変数を個別に返すことで、サイコロの結果を扱っています。

ゲームを続けるか確認する関数

def ask_continue():
    while True:
        try:
            continue_game = int(input("続けますか?(はい:0,いいえ:1) ⇒ "))
            if continue_game == 0 or continue_game == 1:
                return continue_game
            else:
                print("無効な入力です!0か1を入力してください。")
        except ValueError:
            print("無効な入力です!数字を入力してください。")

プレイヤーにゲームを続けるかどうか確認します。

0を入力すればゲーム続行、1を入力すれば終了します。例外処理で不正な入力に対応しています。

メインゲーム関数

def cho_han_game():
    print("丁半賭博ゲームを始めます!")
    
    money = 1000  # プレイヤーの初期所持金
    
    while money > 0:
        print(f"プレイヤーの所持金: {money}円")
        
        # 掛け金を取得
        bet = get_bet(money)
        
        # 丁か半かの選択
        choice = get_choice()
        
        # サイコロを振る
        dice1, dice2 = roll_dice()
        dice_sum = dice1 + dice2
        print(f"サイコロの目: {dice1}, {dice2} ⇒ {'丁' if dice_sum % 2 == 0 else '半'}")
        
        # 勝敗判定
        if (dice_sum % 2 == 0 and choice == 0) or (dice_sum % 2 != 0 and choice == 1):
            print(f"あなたの勝ち!賞金は{bet}円")
            money += bet
        else:
            print(f"あなたの負け!{bet}円没収!")
            money -= bet
        
        # 続けるかどうかを確認
        if money > 0:
            if ask_continue() == 1:
                print(f"最終所持金は{money}円でした。")
                break
        else:
            print("所持金がなくなりました。ゲームを終了します。")
            break

    print(f"最終所持金は{money}円でした。丁半賭博ゲームを終わります。")

メインゲーム関数はゲーム全体の流れを制御します。

所持金が無くなるまでループし、以下のステップを繰り返します。

  1. 所持金を表示。
  2. プレイヤーから掛け金と「丁」か「半」の選択を受け取る。
  3. サイコロを2つ振り、その合計値で結果を判定。勝てば掛け金を増やし、負ければ掛け金を減らします。
  4. プレイヤーが続けるかどうかを確認し、続ける場合は再度ゲームを行います。所持金が0になるか、プレイヤーが終了を選ぶまでゲームは続きます。

まとめ

この「丁半賭博ゲーム」を通じて、Pythonの基本的な構文や関数の作り方、ループ、例外処理、そしてランダムな数値生成について学ぶことができました。

プログラミングではこのように、シンプルなゲームを作ることで楽しみながら文法を身につけることができます。

次に進むときは、ぜひ新しい要素を加えて自分のゲームを拡張してみましょう!

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

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

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

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

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






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