【Python】プレイヤー3人以上のじゃんけんの勝敗判定

プレイヤーが3人以上の場合のじゃんけんの勝敗判定方法解説ページアイキャッチ

このページにはプロモーションが含まれています

このページでは、プレイヤーが3人以上でも適用可能な「じゃんけんの勝敗判定」について解説していきます。

プログラミング入門時にじゃんけんのプログラムを開発してみた経験のある方も多いのではないかと思います。じゃんけんは勝敗を決定するために条件分岐が必要で、じゃんけんの開発により条件分岐の理解度を確認することも出来ますし、ゲームを開発する楽しみを実感することもできる、非常に良いテーマだと思います。

私も本サイトで多くのじゃんけんプログラムに関する記事を公開してきましたのですが、よく考えたらじゃんけんの勝敗を “プレイヤーが2人であることを前提に判定する” ような記事しか公開していなかったので、ここでプレイヤーが3人以上であっても適用可能なじゃんけんの勝敗の判定方法を解説していきたいと思います。

ちなみに、記事のタイトルとしては “3人以上” と明記していますが、この記事で説明する勝敗の判定方法は実はプレイヤーが2人の場合でも適用可能です。ただ、2人限定の場合は、もっと適切な判定方法があると思うので、特に3人以上の時に適用することの多い判定方法になるかなぁと思います。

また、今回は Python のコードで解説を進めていきますが、考え方は他のプログラミング言語でも同じですので、是非他のプログラミング言語を利用されている方もページを読み進めていっていただければと思います!

プレイヤーが3人以上の場合のじゃんけんの勝敗判定

では、プレイヤーが3人以上の場合のじゃんけんの勝敗判定の方法について解説していきたいと思います。

じゃんけんの勝敗判定を行う関数

結論としては、じゃんけんの勝敗判定は下記の judge 関数で行うことができます。

じゃんけんの勝敗判定
def judge(hands):
    # 重複を取り除くためリストを集合に変換
    hand_set = set(hands)

    if len(hand_set) != 2:
        # 手の種類が2つ以外の場合は全プレイヤーが引き分け
        return ['引き分け' for _ in hands]

    if 'グー' not in hand_set:
        # グーがいないならチョキの勝ち
        return ['勝ち' if hand == 'チョキ' else '負け' for hand in hands]
    elif 'チョキ' not in hand_set:
        # チョキがいないならパーの勝ち
        return ['勝ち' if hand == 'パー' else '負け' for hand in hands]
    else:
        # パーがいないならグーの勝ち
        return ['勝ち' if hand == 'グー' else '負け' for hand in hands]

hands = ['パー', 'グー', 'チョキ', 'チョキ']
results = judge(hands)
print(results)

judge 関数の引数

引数には各プレイヤーの手('グー' or 'チョキ' or 'パー')を要素とするリスト hands を指定できるようにしています。

judge関数の引数の説明図

例えば、プレイヤー1がグー、プレイヤー2がパー、プレイヤー3がパーを出した場合は、下記のような hands が引数に指定されることを想定した関数となっています。

引数の指定例
hands = ['グー', 'パー', 'パー']

judge 関数の返却値

さらに、返却値は各プレイヤーのじゃんけんの結果('勝ち' or '負け' or '引き分け')を要素とするリストとしています。

judge関数の返却値の説明図

例えば、プレイヤー1がグー、プレイヤー2がパー、プレイヤー3がパーを出した場合の返却値は下記のようなリストとなります。

返却値の例
['負け', '勝ち', '勝ち']

スポンサーリンク

judge 関数における勝敗を判定する仕組み

関数内のコメントを読んでいただければ理解していただけるのではないかと思うのですが、念のため、なぜ上記の judge 関数でプレイヤーが3人以上のじゃんけんの勝敗が判定できるのか?について解説しておきます。

引き分けの判定を行う

最初に「引き分け」の判定について解説していきます。

まず、プレイヤーが3人以上の場合に引き分け(あいこ)になる条件を考えてみましょう。これは、じゃんけんをしたことのある方であれば簡単に思いつくと思うのですが、この条件の1つは「全てのプレイヤーの手が同じであること」になります。

じゃんけんの結果が引き分けとなる条件を説明する図1

もう1つの条件が、各プレイヤーが出した手に「グー・チョキ・パー全てが存在すること」になります。

じゃんけんの結果が引き分けとなる条件を説明する図2

1つ目の引き分けの条件は、「出された手が 1 種類」と言い換えることができますし、2つ目の引き分けの条件は「出された手が 3 種類」と言い換えることができます。そして、じゃんけんには 3 種類の手しか存在しないので、引き分けである条件は「出された手が 2 種類以外」とも言えます。

したがって、引数 hands に含まれる手の種類をカウントし、カウント結果が 2 以外の場合は全プレイヤーの結果が「引き分け」である判定することができることになります。さらに、Python においては、リストを集合に変換すれば勝手に重複したデータが削除されるようになっています。なので、引数 hands を集合に変換し、集合の要素数をカウントすれば hands に含まれる手の種類をカウントすることが可能です。

リストを集合に変換した結果の長さがプレイヤーの出した手の種類数となることを示す図

そのため、下記の条件分岐によって引き分けかどうかを判定することが可能となります。この場合は全プレイヤーの結果が引き分けとなるため、hands と同じ長さかつ、全要素を引き分けとするリストを返却してやれば良いことになります。

引き分けの判定
# 重複を取り除くためリストを集合に変換
hand_set = set(hands)

if len(hand_set) != 2:
    # 手の種類が2つ以外の場合は全プレイヤーが引き分け
    return ['引き分け' for _ in hands]

上記では出された手の種類数のカウントを行うために hands の集合への変換を行なっていますが、別にリストの各要素を調べ、'グー' の数、'チョキ' の数、'パー' の数をカウントし、カウントした結果が 0 でない個数を「出された手の種類数」としても良いです。

重要なのは、出された手の種類数を使って引き分けかどうかを判定することなので、種類数のカウント方法はなんでも良いです。

引き分けの判定方法の解説は以上です。

勝ち負けの判定を行う

次は「勝ち負け」の判定方法を解説していきます。

judge 関数では、最初に引き分けかどうかの判定を行い、引き分けでない場合のみ「勝ち or 負け」の判定を行うようになっています。具体的には、引き分けの場合は return によって関数を終了するようになっています。そして、前述の通り、全プレイヤーが出した手の種類数が 2 以外の場合に引き分けと判定されます。

つまり、「勝ち or 負け」の判定が行われるのは全プレイヤーが出した手の種類数が 2 の場合のみとなります。言い換えれば、全プレイヤーが出さなかった手が 1 種類のみ存在することになります。

で、じゃんけんの手は 3 種類のみであるため、この時の各プレイヤーの手は3パターンのみに絞られます。

1つ目が誰もグーを出さなかったパターンになります。この場合は必ずチョキを出したプレイヤーが勝ちということになります。

グーがいない場合にチョキを出したプレイヤーが勝ちとなることを示す図

2つ目が誰もチョキを出さなかったパターンで、この場合は必ずパーを出したプレイヤーが勝ちということになります。

チョキがいない場合にパーを出したプレイヤーが勝ちとなることを示す図

3つ目が誰もパーを出さなかったパターンで、この場合は必ずグーを出したプレイヤーが勝ちということになります。

パーがいない場合にグーを出したプレイヤーが勝ちとなることを示す図

つまり、引き分けでない場合、各プレイヤーが出した手のパターンとしては上記の3つのみしか存在せず、上記の3つのパターンのうち、どれに当てはまるかどうかを調べてやれば、各プレイヤーの「勝ち負け」が判定できることになります。

したがって、次のように3つの条件分岐を設けて上記の3パターンのうちのどれに当てはまるかを調べ、そのパターンにおける勝ちの手を出したプレイヤーに対応する要素を '勝ち'、負けの手を出したプレイヤーに対応する要素を '負け' にセットしたリストを返却してやれば、各プレイヤーの勝敗の判定結果を返却することができることになります。

勝ち負けの判定
if 'グー' not in hand_set:
    # グーがいないならチョキの勝ち
    return ['勝ち' if hand == 'チョキ' else '負け' for hand in hands]
elif 'チョキ' not in hand_set:
    # チョキがいないならパーの勝ち
    return ['勝ち' if hand == 'パー' else '負け' for hand in hands]
else:
    # パーがいないならグーの勝ち
    return ['勝ち' if hand == 'グー' else '負け' for hand in hands]

ちょっと3項演算子を利用した内包表記の部分が分かりにくいので補足しておくと、例えば下記では、hands'チョキ'  の要素が '勝ち' に、それ以外の要素が '負け' に置き換えられたリストが新規に生成されることになります。

返却値のリストの生成の例
['勝ち' if hand == 'チョキ' else '負け' for hand in hands]

上記を違う書き方に変更すれば次の通りになり、結果としては同じリストが生成されることになります。3項演算子と内包表記を組み合わせれば、下記のような複数行にわたる処理も1行で記述することができますので、これらについても覚えておくと良いと思います。

返却値のリストの生成の違うやり方
results = []
for hand in hands:
    if hand == 'チョキ':
        results.append('勝ち')
    else:
        results.append('負け')

こんな感じで、全プレイヤーが出した手の種類数から引き分けかどうかを判定し、全プレイヤーが出さなかった手から勝ち負けを判定することで、プレイヤーが3人以上の場合でも適切にじゃんけんの結果を判定することができるようになります。

まとめ

このページでは、プレイヤーが3人以上でも適用可能な「じゃんけんの勝敗判定」について解説しました!

全プレイヤーが出した手の種類数から引き分けかどうかを判定し、全プレイヤーが出さなかった手から勝ち負けを判定することで、プレイヤーが3人以上の場合でも適切にじゃんけんの結果を判定することが可能です。

こういった、日頃何気なくプレイしているゲームをプログラムとして開発してみることで、ロジック等を考える力が身につくと思いますし、ゲームが題材であれば楽しくプログラミングを学ぶこともできると思います。是非、他のゲームのプログラム開発にも挑戦してみてください!

同じカテゴリのページ一覧を表示