Pythonでサイコロ転がしゲームを作ってみた

### 前置き
今日は、6月21日だ。そこで、サイコロのことをぱっと思い浮かんだ。
サイコロの目は、6つあり、目の総和が21である。
そのような理由で、パソコンとサイコロを転がすゲームが作りたくなった。

### プログラムコード
```python
import random

def get_user_choice():
    while True:
        try:
            user_choice = int(input("1から6の数字を選んで、入力してください: "))
            if user_choice not in range(1, 7):
                print("無効な入力です。サイコロの目（1から6）を入力してください。")
            else:
                return user_choice
        except ValueError:
            print("無効な入力です。数字を入力してください。")
```
### 出力結果
```

```
これでは、get_user_choiceという関数を定義しているだけで、何も出力されない。

### ゲームの説明
パソコンとユーザーがサイコロを転がして戦います。
ユーザが入力したサイコロの目 > パソコンが入力したサイコロの目：ユーザーに1点
ユーザが入力したサイコロの目 ＝ パソコンが入力したサイコロの目：加算なし
ユーザが入力したサイコロの目 ＝ パソコンが入力したサイコロの目：パソコンに1点
6点取った方が勝つゲームにします。（デュースなし）

### 6点先取のプログラムコード
``` python
import random

def get_user_choice():
    while True:
        try:
            user_choice = int(input("1から6の数字を選んで、入力してください: "))
            if user_choice not in range(1, 7):
                print("無効な入力です。サイコロの目（1から6）を入力してください。")
            else:
                return user_choice
        except ValueError:
            print("無効な入力です。数字を入力してください。")

def main():
    print("サイコロ転がしゲームにようこそ！")
    print("コンピュータとのサイコロゲームに挑戦しましょう！最初に6点取った方が勝者です。")

    computer_wins = 0
    player_wins = 0

    while computer_wins < 6 and player_wins < 6:
        print("\n--- 新しいラウンド ---")
        print(f"現在のスコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")

        user_choice = get_user_choice()
        computer_choice = random.randint(1, 6)
        print(f"コンピュータが選んだ数字は {computer_choice} です。")

        if user_choice == computer_choice:
            print("引き分けです。得点は加算されません。")
        elif user_choice > computer_choice:
            print("あなたの勝ちです！")
            player_wins += 1
        else:
            print("コンピュータの勝ちです。")
            computer_wins += 1

    if player_wins >= 6:
        print(f"おめでとうございます！あなたの勝ちです！最終スコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")
    else:
        print(f"残念！コンピュータの勝ちです。最終スコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")

if __name__ == "__main__":
    main()
```
### プログラムコードの説明
ここでは、"main"という関数を定義している。
はじめに、サイコロ転がしゲームにようこそ。コンピューターとのサイコロゲームに挑戦しよう。最初に6点取った方が勝者ですと出力される。
user_choiceがcomputer_choiceより大きい場合、ユーザの勝利で1点加算
computer_choiceがuser_choiceより大きい場合、コンピュータの勝利で1点加算
user_choice = computer_choiceの場合は、引き分けで両者に得点が加算されない。
randintを使い、computer_choiceがランダムになっている。

### 実際のゲームプレイ
```python
サイコロ転がしゲームにようこそ！
コンピュータとのサイコロゲームに挑戦しましょう！最初に6点取った方が勝者です。

--- 新しいラウンド ---
現在のスコア： プレイヤー 0 - 0 コンピュータ
1から6の数字を選んで、入力してください: ５
コンピュータが選んだ数字は 4 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 1 - 0 コンピュータ
1から6の数字を選んで、入力してください: 5
コンピュータが選んだ数字は 5 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 1 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 3 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 2 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 6 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 2 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 2 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 3 - 0 コンピュータ
1から6の数字を選んで、入力してください: 4
コンピュータが選んだ数字は 4 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 3 - 0 コンピュータ
1から6の数字を選んで、入力してください: 2
コンピュータが選んだ数字は 1 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 0 コンピュータ
1から6の数字を選んで、入力してください: 5
コンピュータが選んだ数字は 2 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 5 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 5 です。
あなたの勝ちです！
おめでとうございます！あなたの勝ちです！最終スコア： プレイヤー 6 - 0 コンピュータ
```
### ちなみに
今回はたまたま6-0で完勝してしまった。精度を上げるために、同じルールを使い、デュースを含めたゲームに変更してみた。デュースは、スコアが5-5になった場合、2点差がつくまで永遠にゲームは続行される。

### デュースを含めたプログラムコード
```python
import random

def get_user_choice():
    while True:
        try:
            user_choice = int(input("1から6の数字を選んで、入力してください: "))
            if user_choice not in range(1, 7):
                print("無効な入力です。サイコロの目（1から6）を入力してください。")
            else:
                return user_choice
        except ValueError:
            print("無効な入力です。数字を入力してください。")

def main():
    print("サイコロ転がしゲームにようこそ！")
    print("コンピュータとのサイコロゲームに挑戦しましょう！最初に6点取った方が勝者です。デュース（同点）が発生した場合、相手に2点差がつくまで続きます。")

    computer_wins = 0
    player_wins = 0

    while computer_wins < 6 and player_wins < 6:
        print("\n--- 新しいラウンド ---")
        print(f"現在のスコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")

        user_choice = get_user_choice()
        computer_choice = random.randint(1, 6)
        print(f"コンピュータが選んだ数字は {computer_choice} です。")

        if user_choice == computer_choice:
            print("引き分けです。得点は加算されません。")
        elif user_choice > computer_choice:
            print("あなたの勝ちです！")
            player_wins += 1
        else:
            print("コンピュータの勝ちです。")
            computer_wins += 1

        # デュース（同点）の処理
        if player_wins == computer_wins and player_wins >= 5:
            print("\nデュースです！相手に2点差がつくまで続けます。\n")

            while abs(player_wins - computer_wins) < 2:
                print("\n--- デュースラウンド ---")
                print(f"現在のスコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")
                
                user_choice = get_user_choice()
                computer_choice = random.randint(1, 6)
                print(f"コンピュータが選んだ数字は {computer_choice} です。")

                if user_choice == computer_choice:
                    print("引き分けです。得点は加算されません。")
                elif user_choice > computer_choice:
                    print("あなたの勝ちです！")
                    player_wins += 1
                else:
                    print("コンピュータの勝ちです。")
                    computer_wins += 1

    if player_wins >= 6:
        print(f"おめでとうございます！あなたの勝ちです！最終スコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")
    else:
        print(f"残念！コンピュータの勝ちです。最終スコア： プレイヤー {player_wins} - {computer_wins} コンピュータ")

if __name__ == "__main__":
    main()
```
### 改良したプログラムコードの説明
ここでも、mainという関数を定義している。
はじめに、サイコロ転がしゲームにようこそ。コンピューターとのサイコロゲームに挑戦しよう。最初に6点取った方が勝者ですと出力される。
user_choiceがcomputer_choiceより大きい場合、ユーザの勝利で1点加算
computer_choiceがuser_choiceより大きい場合、コンピュータの勝利で1点加算
user_choice = computer_choiceの場合は、引き分けで両者に得点が加算されない。
randintを使い、computer_choiceがランダムになっている。

以前のコードとの変更点は、デュース（両者が勝利できる点数から1点引いた点で並んだ場合、相手に2点差がつくまでゲームが続く）機能を含めたため、abs関数を使用した。具体的には、スコアが5-5になった場合、6-5で勝利するのではなく、7-5でゲームに勝利することができる。

### デュースを含めた実際のゲームプレイ
```python
サイコロ転がしゲームにようこそ！
コンピュータとのサイコロゲームに挑戦しましょう！最初に6点取った方が勝者です。デュース（同点）が発生した場合、相手に2点差がつくまで続きます。

--- 新しいラウンド ---
現在のスコア： プレイヤー 0 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 6 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 0 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 3 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 1 - 0 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 4 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 2 - 0 コンピュータ
1から6の数字を選んで、入力してください: 4
コンピュータが選んだ数字は 3 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 3 - 0 コンピュータ
1から6の数字を選んで、入力してください: 2
コンピュータが選んだ数字は 1 です。
あなたの勝ちです！

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 0 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 4 です。
コンピュータの勝ちです。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 1 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 3 です。
コンピュータの勝ちです。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 2 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 1 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 2 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 1 です。
引き分けです。得点は加算されません。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 2 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 4 です。
コンピュータの勝ちです。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 3 コンピュータ
1から6の数字を選んで、入力してください: 1
コンピュータが選んだ数字は 4 です。
コンピュータの勝ちです。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 4 コンピュータ
1から6の数字を選んで、入力してください: 3
コンピュータが選んだ数字は 5 です。
コンピュータの勝ちです。

--- 新しいラウンド ---
現在のスコア： プレイヤー 4 - 5 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 2 です。
あなたの勝ちです！

デュースです！相手に2点差がつくまで続けます。


--- デュースラウンド ---
現在のスコア： プレイヤー 5 - 5 コンピュータ
1から6の数字を選んで、入力してください: 6
コンピュータが選んだ数字は 4 です。
あなたの勝ちです！

--- デュースラウンド ---
現在のスコア： プレイヤー 6 - 5 コンピュータ
1から6の数字を選んで、入力してください: 3
コンピュータが選んだ数字は 1 です。
あなたの勝ちです！
おめでとうございます！あなたの勝ちです！最終スコア： プレイヤー 7 - 5 コンピュータ
```
### ちなみに
具体的には、コンピューターと私が選んだサイコロの目が一緒だった場合、"引き分けです。得点は加算されません”と出力された。そして、ちゃんとスコアが5-5になった時、6-5で勝利せず、7-5で勝利することができた。

皆さんも時間がある時に、このプログラムコードを参考にしながら、サイコロ転がしゲームを遊んでみてはいかがでしょうか。