Pythonでマスターマインドゲームと言う暗号解読ゲームを作る方法

スポンサーリンク

マスターマインド」は2人で遊ぶ暗号解読ゲームで、一方のプレイヤーが色で構成された暗号を隠し、もう一方のプレイヤーが前者のプレイヤーから与えられたヒントをもとに、ターンごとに暗号を推測していくゲームです。

この記事では、Python言語を使って独自のマスターマインドゲームを作成します。

私たちのマスターマインドでは、コンピュータがランダムに秘密のコードを選択し、ユーザーはコンピュータから与えられる決定論的な手がかりに基づいて、それを推測しようとします。

スポンサーリンク

Pythonで作る首謀者ゲーム – デモ

マスターマインドゲームのデモ

さっそくですが、ゲームの設計部分に入りましょう。

マスターマインド・ゲーム・デザイン

マスターマインド・ボードの原型は以下の通りです。

# Function to print the mastermind board
def print_mastermind_board(passcode, guess_codes, guess_flags):
 
    print("-----------------------------------------")
    print("       MASTERMIND")
    print("-----------------------------------------")
 
    print("    |", end="")
    for x in passcode:
        print(" " + x[:3], end="")
    print()
 
    for i in reversed(range(len(guess_codes))):
        print("-----------------------------------------")
        print(guess_flags[i][0], guess_flags[i][1], "|")
         
 
        print(guess_flags[i][2], guess_flags[i][3], end=" |")
        for x in guess_codes[i]:
            print(" " + x[:3], end="")
 
        print()
    print("-----------------------------------------")

ボードの端にあるシールドには秘密のコードが隠されており、ボード全体はコードブレーカーによる推測に基づくものです。

このゲームは、ユーザーが隠された暗号を特定した時点で終了します。

図のボードの右側には、白と赤のペグが並んでおり、それぞれのトライに関連するヒントを示しています。

  • 赤 – 選択された色のいずれかが、秘密のコードのように正しい位置にあります。
  • 白 – 選択された色のいずれかがコードに存在するが、位置が不正確です。

端末でのボードの実装は以下のようになります。

# The Main function
if __name__ == '__main__':
 
    # List of colors
    colors = ["RED", "GREEN", "YELLOW", "BLUE", "BLACK", "ORANGE"]
 
    # Mapping of colors to numbers 
    colors_map = {1:"RED", 2:"GREEN", 3:"YELLOW", 4:"BLUE", 5:"BLACK", 6:"ORANGE"}
 
    # Randomly selecting a passcode
    random.shuffle(colors)
    passcode = colors[:4]
     
    # Number of chances for the player
    chances = 8
 
    # The passcode to be shown to the user
    show_passcode = ['UNK', 'UNK', 'UNK', 'UNK']
 
    # The codes guessed by the player each turn
    guess_codes = [['-', '-', '-', '-'] for x in range(chances)]
 
    # The clues provided to the player each turn
    guess_flags = [['-', '-', '-', '-'] for x in range(chances)]

ボードの上端には秘密のコードが隠されており、プレーヤーがチャンスを失うか、コードを破ったときに明らかにされる。

それまでは “unknown “の “UNK “が表示されている。

ボードの各セクションは、プレイヤーが行うターンを表します。

赤、緑、黄、青、黒、オレンジの6色に対応しています。

一番左のパネルは、各ターンに基づくヒントを示しています。

W」はWHITE、「R」はREDを表し、それぞれ本来の意味を持っています。

上の図では、ユーザーが選んだ4色のうち3色は正しいのですが、どちらも秘密のコードに従った正しい位置ではないので、ヒントには3つの「W」が使われています。

# The current turn
turn = 0
 
# The GAME LOOP
while turn < chances:

上のコードは、黒幕ボードを端末に表示するためのものです。

Data Structures – Game variables

ゲームロジックを便利に開発するために、いくつかのデータ構造が必要です。

  • colors – ゲームに使用される色のリスト。
  • colors_map – 数字と色の対応表。
  • passcode – 秘密のコード
  • show_passcode – ユーザに表示される秘密のコード、Unknowns のリストです。
  • guess_code – プレイヤーによって推測されるリストのリストです。
  • guess_flags – プレイヤーに与えられたヒントのリスト
# The GAME MENU
print("-----------------------------------------")
print(" Menu")
print("-----------------------------------------")
print("Enter code using numbers.")
print("1 - RED, 2 - GREEN, 3 - YELLOW, 4 - BLUE, 5 - BLACK, 6 - ORANGE")
print("Example: RED YELLOW ORANGE BLACK ---> 1 3 6 5")
print("-----------------------------------------")
print_mastermind_board(show_passcode, guess_codes, guess_flags)

これらのデータ構造は、マスターマインドゲームの実装において、ゲームロジックを扱う際に便利です。

ゲームループ

ゲーム開発において最も重要な部分の1つがゲームループです。

ゲームループはプレイヤーの動きとゲーム変数の更新を適切に機能させる役割を担っています。

# Accepting the player input
try:   
    code = list(map(int, input("Enter your choice = ").split()))
except ValueError:
    clear()
    print(" Wrong choice!! Try again!!")
    continue

ゲームループは、チャンスの数と現在の手番に依存します。

ゲームループは、プレイヤーのチャンスが尽きたときにいつでもゲームを停止することになっています。

ゲームメニュー

ゲームメニューは、ゲームのシンプルな要素として、プログラマーがプレイヤーに指示やルールを与えるのに役立ちます。

ゲームメニューは次のようなものです。

# Check if the number of colors nunbers are 4
if len(code) != 4:
    clear()
    print(" Wrong choice!! Try again!!")
    continue
 
# Check if each number entered corresponds to a number
flag = 0
for x in code:
    if x > 6 or x < 1:
        flag = 1
 
if flag == 1:          
    clear()
    print(" Wrong choice!! Try again!!")
    continue   
# Storing the player moves
for i in range(4):
    guess_codes[turn][i] = colors_map[code[i]] 

ゲームメニューは、シンプルで適切なものでなければなりません。

プレイヤー入力の処理

プレイヤーの入力を処理するには、3つの基本的なステップがあります。

プレイヤー入力を受け入れ、それに対していくつかのサニティチェックを適用し、すべてが正常であれば、それをデータ構造に格納します。

プレイヤー入力の受付

ゲームメニューで述べたように、プレイヤーは4つの数字を入力する必要があり、それぞれが特定の色に対応し、スペースで区切られている。

私たちの仕事は、このプレイヤーの入力を解析して、適切な色を取り出すための整数のリストにすることです。

# Process to apply clues according to the player input 
dummy_passcode = [x for x in passcode] 
 
pos = 0
 
# Loop to set up clues for the player move
for x in code:
    if colors_map[x] in dummy_passcode:
        if code.index(x) == passcode.index(colors_map[x]):
            guess_flags[turn][pos] = 'R'
        else:
            guess_flags[turn][pos] = 'W'
        pos += 1
        dummy_passcode.remove(colors_map[x])
 
random.shuffle(guess_flags[turn])              

Note: clear() 関数は、直前の出力をフラッシュして、端末をクリーンに保つ役割を担っています。

これは Python の os ライブラリを必要とします。

>
clear()`の関数宣言については、以下の完全なコードを確認してください。

サニティチェックの適用

次は、プレイヤー入力のサニティチェックを行います。

# Check for win condition
if guess_codes[turn] == passcode:
    clear()
    print_mastermind_board(passcode, guess_codes, guess_flags)
    print("Congratulations!! YOU WIN!!!!")
    break

プレイヤーの動きを記憶する

プレイヤーが有効な手を打ったことが分かったら、その手をゲームコンテナに格納することができます。

# Update turn  
turn += 1          
clear()

各手順のヒントを設定する

暗号の通り正しい位置にある色には「R」、正しい位置にあるが間違った位置にある色には「W」のフラグを設定することで、2つのセットとなります。

# Check for loss condiiton 
if turn == chances:
    clear()
    print_mastermind_board(passcode, guess_codes, guess_flags)
    print("YOU LOSE!!! Better luck next time!!!")  

旗を並べ替えると、色の位置に関連するヒントが得られることがあるので、覚えておくとよいでしょう。

勝利条件を確認する

あとは、隠されたコードで最新の入力をチェックするだけです。

import random
import os
 
def clear():
    os.system("clear")
 
# Function to print the mastermind board
def print_mastermind_board(passcode, guess_codes, guess_flags):
 
 
    print("-----------------------------------------")
    print("       MASTERMIND")
    print("-----------------------------------------")
 
    print("    |", end="")
    for x in passcode:
        print(" " + x[:3], end="")
    print()
 
    for i in reversed(range(len(guess_codes))):
        print("-----------------------------------------")
        print(guess_flags[i][0], guess_flags[i][1], "|")
         
 
        print(guess_flags[i][2], guess_flags[i][3], end=" |")
        for x in guess_codes[i]:
            print(" " + x[:3], end="")
 
        print()
    print("-----------------------------------------")
 
# The Main function
if __name__ == '__main__':
 
    # List of colors
    colors = ["RED", "GREEN", "YELLOW", "BLUE", "BLACK", "ORANGE"]
 
    # Mapping of colors to numbers 
    colors_map = {1:"RED", 2:"GREEN", 3:"YELLOW", 4:"BLUE", 5:"BLACK", 6:"ORANGE"}
 
    # Randomly selecting a passcode
    random.shuffle(colors)
    passcode = colors[:4]
     
    # Number of chances for the player
    chances = 8
 
    # The passcode to be shown to the user
    show_passcode = ['UNK', 'UNK', 'UNK', 'UNK']
 
    # The codes guessed by the player each turn
    guess_codes = [['-', '-', '-', '-'] for x in range(chances)]
 
    # The clues provided to the player each turn
    guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
     
    clear()
 
    # The current turn
    turn = 0
 
    # The GAME LOOP
    while turn < chances:
         
        print("-----------------------------------------")
        print(" Menu")
        print("-----------------------------------------")
        print("Enter code using numbers.")
        print("1 - RED, 2 - GREEN, 3 - YELLOW, 4 - BLUE, 5 - BLACK, 6 - ORANGE")
        print("Example: RED YELLOW ORANGE BLACK ---> 1 3 6 5")
        print("-----------------------------------------")
        print_mastermind_board(show_passcode, guess_codes, guess_flags)
 
        # Accepting the player input
        try:   
            code = list(map(int, input("Enter your choice = ").split()))
        except ValueError:
            clear()
            print(" Wrong choice!! Try again!!")
            continue   
 
        # Check if the number of colors nunbers are 4
        if len(code) != 4:
            clear()
            print(" Wrong choice!! Try again!!")
            continue
 
        # Check if each number entered corresponds to a number
        flag = 0
        for x in code:
            if x > 6 or x < 1:
                flag = 1
 
        if flag == 1:          
            clear()
            print(" Wrong choice!! Try again!!")
            continue   
 
        # Storing the player input
        for i in range(4):
            guess_codes[turn][i] = colors_map[code[i]] 
 
        # Process to apply clues according to the player input 
        dummy_passcode = [x for x in passcode] 
 
        pos = 0
 
        # Loop to set up clues for the player move
        for x in code:
            if colors_map[x] in dummy_passcode:
                if code.index(x) == passcode.index(colors_map[x]):
                    guess_flags[turn][pos] = 'R'
                else:
                    guess_flags[turn][pos] = 'W'
                pos += 1
                dummy_passcode.remove(colors_map[x])
 
        random.shuffle(guess_flags[turn])              
 
 
        # Check for win condition
        if guess_codes[turn] == passcode:
            clear()
            print_mastermind_board(passcode, guess_codes, guess_flags)
            print("Congratulations!! YOU WIN!!!!")
            break
 
        # Update turn  
        turn += 1          
        clear()
 
# Check for loss condiiton 
if turn == chances:
    clear()
    print_mastermind_board(passcode, guess_codes, guess_flags)
    print("YOU LOSE!!! Better luck next time!!!")  

プレイヤーが正しいコードを入力したら、すぐに勝利のメッセージを表示し、ゲームを終了させる。

ターン番号を更新する

小さな、しかし非常に重要なタスクは、プレイヤーの移動が成功するたびにターンナンバーを更新することです。

Mastermind
Mastermind Board

最後に、損失条件を処理することです。

ロス状態を確認する

チャンス数を使い切ったとき、プレイヤーは負けになります。

このとき、適切なメッセージを表示する必要があります。

Mastermind Game Design
Game Design on Terminal

以上で、Python言語による首謀者の作成方法の説明を終わります。

完全なるコード

Mastermind Game Menu
Game Menu

まとめ

自作のゲームを作るという作業は、初心者のPythonプログラマーにとって最初は難しく感じるかもしれません。

この記事で特定のPythonの概念を簡略化し、読者がこのタスクを達成できるように見えることを望みます。

何か提案や疑問があれば、下のコメント欄からお気軽にどうぞ。

お読みいただきありがとうございました。

タイトルとURLをコピーしました