LoginSignup
0
1

More than 1 year has passed since last update.

【Python3】0から作るPython初心者プログラミング【04】-あっち向いてほいプログラム-

Last updated at Posted at 2021-11-29

【ご挨拶】こんにちは! ぬかさんエンジニアリングです。(4回目‼)

今回は、大人数であっち向いてほいトーナメントバトルが出来るプログラムをつくりたいと思います!
基本的には土台として前回の大人数じゃんけんプログラムのコードを転用して作ることになります。作り方だけ見たいという方は前回の記事も一緒に見てもらった方が理解度は高まるかと思います。己の力のみで0からお題に挑戦したいという方ものために「機能要件」を用意していますので、それだけ見て作ってみるのもいいかもしれません。
今回のプログラムからいよいよゲームらしくなっていきます。それに伴って初心者の中には少し難易度が高いと感じる方もいるかもしれません。どうしても行き詰った場合はまず寝てください。もしくは〔作り方〕をサラッと見てください。いずれにせよ最後まで作りきることを目標にして下さい。私もこの記事を作るためにクラスについて勉強し直して結構時間をが掛かりましたが、完成した時の達成感と脱力感はいい物でした。質問等も受け付けておりますので一緒に頑張りましょう!
LGTMも是非よろしくお願いします‼

本シリーズ初めての方へ

【趣旨】
Python初心者プログラマーが入門書で学んだ知識を実践的なコーディングを通じて身に着けていくためのお題を提供します。
お題を基に各自コーディングに挑戦していただいた後、この記事でコーディングの過程を答え合わせします。

【対象】
Pythonの入門書を読んで理解はしたけど何か目的をもって実践的にコーディングをしたい方。
ProgateでPythonコースをLv5まで勉強したけど応用力が身に着いていないと感じている方。

【初心者とは】
この記事シリーズでの初心者は下記の項目を理解済みであることが目安となっています。
[演算子, 標準ライブラリ, 条件分岐, 繰り返し処理, 例外処理, リスト, タプル, セット, 辞書, オブジェクト指向]

【利用ライブラリ & Python3 --version】

・Google Colaboratory
以下のリンクからアクセスして使い方を確認した後、左上のファイルタブから「ノートブックを新規作成」を選択して自分のプログラムを作りましょう。ファイルはGoogleDriveに保存されるため、自分のGoogleアカウントと連携させるのを忘れないようにしましょう。

Colaboratory へようこそ ←ここからリンクへ飛ぶ

・Python 3.7.12

$$$$

それではさっそく本題に入っていきましょう:muscle:

第【04】回 -あっち向いてほいプログラム-

このシリーズ第四回目の今回は、前回の大人数じゃんけんプログラムから更にゲーム性をアップしてあっち向いてほいトーナメントバトルが出来るプログラムを実装します!
ゲーム性がアップしただけありゲームの進み方も複雑になっていきます。どんな可能性でもプログラムがエラーを起こさず最後まで処理できるように何度もチェックしながら決められた「要件」を満たすプログラムを一緒に作っていきましょう!

【お題】あっち向てほいでトーナメントバトルが出来るプログラムをつくろう!

hoi_battle_ground()

#出力

==============================

あっち向いてほいBATTLEGROUNDS


       >>GAMESTART<<

          Press A

==============================
A





============================================================

        あっち向いてほいBATTLEGROUNDSへようこそ


    このゲームでは最大64人でトーナメント戦を行います
                    ルールは単純です
  あっち向いてほいで決められた点数を先に獲得したら勝利です


   トーナメントを勝ち抜いて優勝を目指して頑張りましょう

 ============================================================





============================================================

あっち向いてほいBATTLEGROUNDSの設定を決めてください


参加人数を4,8,16,32,64人から選択してください >8


プレイヤーの人数を選択してください(最大人数は8人です) >3


プレイヤー名を記入してください>nu
<nu>さんですねエントリー完了しました


プレイヤー名を記入してください>ka
<ka>さんですねエントリー完了しました


プレイヤー名を記入してください>san
<san>さんですねエントリー完了しました


試合のマッチポイントを入力してください >3

============================================================








3ポイントマッチ制 8人トーナメントスタート!!


-----------------------------------
第1回戦対戦表

コンピュータ5 vs ka
コンピュータ3 vs コンピュータ4
コンピュータ1 vs nu
コンピュータ2 vs san
-----------------------------------
-----------------------------------
第1回戦 第1試合

コンピュータ5 vs ka
-----------------------------------

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手パー
kaの手グー


◎◎コンピュータ5の勝ち!◎◎


>>>あっち向いてほい<<<
あなたの顔の向きを選択してください(整数1,2,3,4) 1
コンピュータ5の手:
kaの手:
××じゃんけんに戻る××

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手グー
kaの手グー

△△あいこでしょ!!△△
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手チョキ
kaの手グー


◎◎kaの勝ち!◎◎


>>>あっち向いてほい<<<
{1: '↑', 2: '→', 3: '↓', 4: '←'}
あなたの指の向きを選択してください(整数1,2,3,4) 1
kaの手:
コンピュータ5の手:


◎◎◎kaの勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ5:0ポイント               
ka:1ポイント

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手チョキ
kaの手グー


◎◎kaの勝ち!◎◎


>>>あっち向いてほい<<<
{1: '↑', 2: '→', 3: '↓', 4: '←'}
あなたの指の向きを選択してください(整数1,2,3,4) 1
kaの手:
コンピュータ5の手:


◎◎◎kaの勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ5:0ポイント               
ka:2ポイント

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手グー
kaの手グー

△△あいこでしょ!!△△
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 1
コンピュータ5の手チョキ
kaの手グー


◎◎kaの勝ち!◎◎


>>>あっち向いてほい<<<
{1: '↑', 2: '→', 3: '↓', 4: '←'}
あなたの指の向きを選択してください(整数1,2,3,4) 1
kaの手:
コンピュータ5の手:


◎◎◎kaの勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりkaの勝利<><><><


-----------------------------------
第1回戦 第2試合

コンピュータ3 vs コンピュータ4
-----------------------------------

>>>じゃんけんぽん<<<
コンピュータ3の手パー
コンピュータ4の手パー

△△あいこでしょ!!△△
コンピュータ3の手グー
コンピュータ4の手チョキ


◎◎コンピュータ3の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ3の手:
コンピュータ4の手:
××じゃんけんに戻る××

>>>じゃんけんぽん<<<
コンピュータ3の手チョキ
コンピュータ4の手チョキ

△△あいこでしょ!!△△
コンピュータ3の手グー
コンピュータ4の手チョキ


◎◎コンピュータ3の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ3の手:
コンピュータ4の手:


◎◎◎コンピュータ3の勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ3:1ポイント               
コンピュータ4:0ポイント

>>>じゃんけんぽん<<<
コンピュータ3の手パー
コンピュータ4の手パー

△△あいこでしょ!!△△
コンピュータ3の手チョキ
コンピュータ4の手グー


◎◎コンピュータ4の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ4の手:
コンピュータ3の手:


◎◎◎コンピュータ4の勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ3:1ポイント               
コンピュータ4:1ポイント

>>>じゃんけんぽん<<<
コンピュータ3の手チョキ
コンピュータ4の手パー


◎◎コンピュータ3の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ3の手:
コンピュータ4の手:


◎◎◎コンピュータ3の勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ3:2ポイント               
コンピュータ4:1ポイント

>>>じゃんけんぽん<<<
コンピュータ3の手パー
コンピュータ4の手チョキ


◎◎コンピュータ4の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ4の手:
コンピュータ3の手:


◎◎◎コンピュータ4の勝利1ポイント獲得!◎◎◎


現在のポイント               
コンピュータ3:2ポイント               
コンピュータ4:2ポイント

>>>じゃんけんぽん<<<
コンピュータ3の手チョキ
コンピュータ4の手グー


◎◎コンピュータ4の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ4の手:
コンピュータ3の手:


◎◎◎コンピュータ4の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ4の勝利<><><><


-----------------------------------
第1回戦 第3試合

コンピュータ1 vs nu
-----------------------------------

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
nuの出す手を入力してください(整数1, 2, 3) 2
コンピュータ1の手グー
nuの手チョキ

                    
                    
                    
                    
                                

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
nuの出す手を入力してください(整数1, 2, 3) 2
コンピュータ1の手グー
nuの手チョキ


◎◎コンピュータ1の勝ち!◎◎


>>>あっち向いてほい<<<
あなたの顔の向きを選択してください(整数1,2,3,4) 2
コンピュータ1の手:
nuの手:


◎◎◎コンピュータ1の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ1の勝利<><><><


-----------------------------------
第1回戦 第4試合

コンピュータ2 vs san
-----------------------------------

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
sanの出す手を入力してください(整数1, 2, 3) 3
コンピュータ2の手チョキ
sanの手パー

                    
                    
                    
                    
                    

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
sanの出す手を入力してください(整数1, 2, 3) 3
コンピュータ2の手パー
sanの手パー

△△あいこでしょ!!△△
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
sanの出す手を入力してください(整数1, 2, 3) 3
コンピュータ2の手チョキ
sanの手パー


◎◎コンピュータ2の勝ち!◎◎


>>>あっち向いてほい<<<
あなたの顔の向きを選択してください(整数1,2,3,4) 3
コンピュータ2の手:
sanの手:


◎◎◎コンピュータ2の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ2の勝利<><><><


-----------------------------------
準決勝対戦表
ka vs コンピュータ4
コンピュータ1 vs コンピュータ2
-----------------------------------
-----------------------------------
準決勝戦 第1試合

ka vs コンピュータ4
-----------------------------------

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 2
kaの手チョキ
コンピュータ4の手パー

                    
                    
                    
                    
                    

>>>じゃんけんぽん<<<
選択肢: {1: 'グー', 2: 'チョキ', 3: 'パー'}
kaの出す手を入力してください(整数1, 2, 3) 2
kaの手チョキ
コンピュータ4の手グー


◎◎コンピュータ4の勝ち!◎◎


>>>あっち向いてほい<<<
あなたの顔の向きを選択してください(整数1,2,3,4) 2
コンピュータ4の手:
kaの手:


◎◎◎コンピュータ4の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ4の勝利<><><><


-----------------------------------
準決勝戦 第2試合

コンピュータ1 vs コンピュータ2
-----------------------------------

>>>じゃんけんぽん<<<
コンピュータ1の手パー
コンピュータ2の手グー

           
           
           
           
           

>>>じゃんけんぽん<<<
コンピュータ1の手パー
コンピュータ2の手グー


◎◎コンピュータ1の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ1の手:
コンピュータ2の手:


◎◎◎コンピュータ1の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ1の勝利<><><><


-----------------------------------
決勝対戦表
コンピュータ4 vs コンピュータ1
-----------------------------------
-----------------------------------
決勝戦

コンピュータ4 vs コンピュータ1
-----------------------------------

>>>じゃんけんぽん<<<
コンピュータ4の手チョキ
コンピュータ1の手グー

           
           
           
           
           

>>>じゃんけんぽん<<<
コンピュータ4の手チョキ
コンピュータ1の手パー


◎◎コンピュータ4の勝ち!◎◎


>>>あっち向いてほい<<<
コンピュータ4の手:
コンピュータ1の手:


◎◎◎コンピュータ4の勝利1ポイント獲得!◎◎◎


><><><>3ポイント先取によりコンピュータ4の勝利<><><><


 +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
     栄えある優勝者はコンピュータ4!!おめでとうございます!!!
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
 +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*


もう一度プレイしますか(Yes:y/No:n)n

【要件定義】
1.最大64人対戦が出来るようにしてください。

2.人間のプレイヤーの数は一人~プレイヤー全員まで自由に選択できるようにしてください。

3.プレイヤー全員のうち人間のプレイヤー以外は自動的にコンピュータを割り当ててください。

4.人間のプレイヤーに名前を付けて試合中もその名前で表示されるようにしてください。

5.試合のマッチポイントは自由に選択できるようにしてください。

6.トーナメントの各回戦の初めに全試合の対戦表を表示して分かりやすくしてください。

7.各試合の初めにその試合が「第○回戦第○試合」で「誰と誰」の対戦か表示して分かりやすくしてください。

8.試合で得点が入るたびに両者の現在のポイントを表示して進行具合を分かりやすくしてください。

9.各試合の勝者の名前を表示してください。

10.優勝者を表示してください。

11.ゲーム終了後に再度プレイするか選択できるようにしてください。


【機能要件】
(0.このゲームの概要とルール説明を表示する)←有無は問わない

1.4人、8人、16人、32人、64人からトーナメントバトルの参加人数を選択(入力)できる機構を作成してゲームに反映できるようにしてください。

2.人間が操作するプレイヤーの人数を入力できる機構を作成してゲームに反映できるようにしてください。

3.各人間プレイヤーの名前を入力できる機構を作成してゲームに反映できるようにしてください。

4.試合のマッチポイント数を入力できる機構を作成してゲームに反出来るようにしてください。

5.トーナメントにおけるプレイヤーの組み合わせがランダムになるように設計してください。

6.トーナメントの初めに「○ポイントマッチ制 ○人トーナメントスタート」表示してください。

7.トーナメントの各回戦の最初に「第○回戦対戦表」と全試合分の「プレイヤー名 vs プレイヤー名」を出力してください。

8.各試合の最初に「第○回戦 第○試合」とその試合の「プレイヤー名 vs プレイヤー名」を出力してください。

9.最後とそのひとつ前の回戦は「第○回戦」を「決勝」「準決勝」に変換して表示してください。

10.試合のルールは、じゃんけんに勝った人が指の向きを、じゃんけんに負けた人が顔の向きを選択し、同じ向きであった場合じゃんけんの勝者に勝利ポイントが入ります。
あっち向いてほいでお互いが選択した向きが異なる場合は再びじゃんけんからやり直すように設計してください。ポイントのマイナスはありません。

11.試合中どちらかがポイントを獲得したタイミングで両者の現在のポイントを表示するようにしてください。

12.決勝で勝ち残ったプレイヤーの名前を表示して表彰してください。

13.再度プレイするか選択できる機構を作成してください。


〔お助けヒント〕

ヒント1
プレイヤーのインスタンスは一つ一つ変数に代入せずに配列にまとめて格納し、取り出す場合はfor文を使うようにすると便利です。

ヒント2
新たにクラスを作成し初期化メソッドでプレイヤーのインスタンスの配列をインスタンス変数に代入します。そして、試合の一連の流れを実行できるインスタンスメソッドたちを作成してクラスにまとめるとあっち向いてほいプログラムが作りやすくなります。

ヒント3
このプログラムを要約すると「for文で1回戦~決勝まで回す中で更にfor文で第一試合~最終試合まで回し、その中で更にwhile文でどちらかがマッチポイントを獲るまでじゃんけんとあっち向いてほいを繰り返すプログラム」です。こんがらがったらまずは図示!

ヒント4
インスタンスメソッド内でインスタンスメソッドを実行するネスト構造を使って処理を連鎖させて、返り値はネストを遡ってくる方法を使うと便利です。

【解答】

解答は以下の通りです。
※この解答はあくまで私の回答です。各々の方法でお題が解けていればそれで全然かまいません。むしろ、もっと簡潔な方法があればご教示頂けると助かります:bow_tone1:

import random

#スコアシートクラス(プレイヤーの名前を保持、プレイヤーの得点を保持)
class Scoresheet:

  def __init__(self, names, score=0):
    self.names = names
    self.score = score


#ヒューマンクラス(じゃんけんの手の選択、あっち向いてほいの手の選択)
class Human(Scoresheet):

  ##人間プレイヤーの手を選択
  def pon(self):
    print('選択肢:', HANDS)
    while True:
      try:
        hand = input(f"{self.names}の出す手を入力してください(整数:1, 2, 3) 〉")
        if hand in ("1", "2", "3"):
            self.hand = HANDS[int(hand)]
            return
      except:
         print("整数:1, 2, 3を入力してください。")

  ##人間プレイヤーの指か顔の向きを選択
  def hoi(self, j_result):
    if j_result == "w":
      print(FINGER)
      while True:
        try:
          finger = input("あなたの指の向きを選択してください(整数:1,2,3,4) 〉")
          if finger in ("1","2","3","4"):
            self.finger = FINGER[int(finger)]
            return
        except:
          print("整数1,2,3,4を入力してください")  
    else:
      while True:
        try:
          face = input("あなたの顔の向きを選択してください(整数:1,2,3,4) 〉")
          if face in ("1","2","3","4"):
            self.face = FACE[int(face)]
            return
        except:
          print("整数1,2,3,4を入力して下さい")


#コンピュータクラス(じゃんけんの手の選択、あっち向いてほいの手の選択)
class Computer(Scoresheet):

  ##コンピュータの手を選択
  def pon(self):
    self.hand = random.choice(list(HANDS.values()))

  ##コンピュータの指か顔の向きを選択
  def hoi(self, j_result):
    if j_result == "w":
        self.finger = random.choice(list(FINGER.values()))
    else:
        self.face = random.choice(list(FACE.values()))


#トーナメントクラス(試合のマッチング、各回戦の一連の試合を実行し敗者を選出、各回戦のスコアリセット)
class Tournament:

  def __init__(self, players, tournament_num=None):
    self.players = players
    self.tournament_num = tournament_num

  ##プレイヤーの順番をランダムにシャッフル
  def shuffle(self):  
      random_list = [player for player in self.players]
      random.shuffle(random_list)
      return random_list

  ##2人ずつのグループに分けて対戦表を作成&出力
  def match(self):
    game_num = int(len(self.players) / 2)

    print("-"*35)
    if game_num == 1:
      print("決勝対戦表")
    elif game_num == 2:
      print("準決勝対戦表")
    else:
      print(f"第{self.tournament_num}回戦対戦表\n")

    for n in range(0, game_num):
      group_n = self.players[n*2:n*2+2] 
      print(f"{group_n[0].names} vs {group_n[1].names}")
    print("-"*35)
    return game_num

  ##第〇回戦の全試合を実施して負けた参加者を配列(リスト型)に格納
  def battle(self, game_num, match_point):
    losers_list = []
    for n in range(0, game_num):
      group_n = self.players[n*2:n*2+2] 
      print("-"*35)
      if game_num == 1:
        print("決勝戦")
      elif game_num == 2:
        print(f"準決勝戦 第{n+1}試合")
      else:
        print(f"第{self.tournament_num}回戦 第{n+1}試合")
      print(f"\n{group_n[0].names} vs {group_n[1].names}")
      print("-"*35)
      while True:
        loser = Janken(group_n).play(match_point)
        if loser:
          losers_list.append(loser)
          break
    return losers_list

  ##スコアリセット
  def score_reset(self):
    for player in self.players:
      player.score = 0


#じゃんけんクラス(じゃんけんをする際の手の選択と出力、判定、ポイントの加算と出力)
class Janken:

  def __init__(self, group_n):
    self.group_n = group_n

  ##じゃんけんの一連の流れを実行
  def play(self, match_point):
    print("\n>>>じゃんけんぽん!<<<")
    self.pon()
    while True:
      j_winner, j_loser = self.judge()           
      if j_winner:
        print(f"\n\n◎◎{j_winner.names}の勝ち!◎◎")
        break
      else:  
        print("\n△△あいこでしょ!!△△")
        self.pon()
    return Hoi(j_winner, j_loser).play(self.group_n, match_point)

  ##ヒューマンクラスとコンピュータクラスのponインスタンスメソッドを実行して各参加者のじゃんけんの手を出力 
  def pon(self):
    for player in self.group_n:
      player.pon()
    for player in self.group_n:
      print(f"{player.names}の手:{player.hand}")

  ##プレイヤーのじゃんけんの手があいこか否かを判定、あいこでなければ勝者を決定
  def judge(self):
    hands = set(player.hand for player in self.group_n)
    if len(hands) != 2:
      return None, None
    hand1, hand2 = hands
    win = hand1 if hand1.stronger_than(hand2) else hand2
    for player in self.group_n:
      if player.hand == win:
        winner = player 
      else:
        loser = player
    return winner, loser


#あっち向いてほいクラス(あっち向いてほいをする際の手と指の選択&出力、勝敗判定)
class Hoi:

  def __init__(self, j_winner, j_loser):
    self.j_winner = j_winner
    self.j_loser = j_loser


  ##あっち向いてほいをプレイして勝者を出力し敗者を返り値で返す
  def play(self, group_n, match_point):
    print("\n\n>>>あっち向いてほい!<<<")
    self.hoi()
    if self.j_winner.finger == self.j_loser.face:
      print(f"\n\n◎◎◎{self.j_winner.names}の勝利!1ポイント獲得!◎◎◎")
      self.j_winner.score += 1
      if self.j_winner.score < match_point:
        print(f"\n\n現在のポイント \
              \n{group_n[0].names}:{group_n[0].score}ポイント \
              \n{group_n[1].names}:{group_n[1].score}ポイント")
        return
      else:
        print(f"\n\n><><><>{match_point}ポイント先取により{self.j_winner.names}の勝利!<><><><\n\n")
        return self.j_loser        
    else:
      print("××じゃんけんに戻る××")
      return

  ##プレイヤー同士の出した指と顔の向きを出力
  def hoi(self):
    self.j_winner.hoi("w")
    self.j_loser.hoi("l")
    print(f"{self.j_winner.names}の手:{self.j_winner.finger}")
    print(f"{self.j_loser.names}の手:{self.j_loser.face}")

#ハンドクラス(判定で2つの手の勝敗を決定) 
class Hand:

  def __init__(self, shape, stronger_than):
      self.shape = shape
      self._stronger_than = stronger_than

  ##デバッグ時にインスタンスを指定の形で出力する用
  def __repr__(self):
      return repr(self.shape)

  ##インスタンスをstr型で出力する際にself.shapeを出力
  def __str__(self):
      return self.shape

  ##2つの手のうち、一方の手が勝つ時の相手の手と実際の相手の手が同じだという返り値を返す
  def stronger_than(self, enemy):
      return self._stronger_than == enemy.shape


#じゃんけんの手、あっち向いてほいの顔、あっち向いてほいの指の辞書
HANDS = {1: Hand("グー", "チョキ"),
         2: Hand("チョキ", "パー"),
         3: Hand("パー", "グー")}
FACE = {1:"↑",2:"→",3:"↓",4:"←"}
FINGER = {1:"↑",2:"→",3:"↓",4:"←"}


#あっち向いてほいバトルグラウンドをスタート
def hoi_battle_ground():

  print("="*30 + "\n\nあっち向いてほいBATTLEGROUNDS\n\n\n       >>GAMESTART<<\n\n          Press A\n\n" + "="*30)
  while True:
    Button = input()
    if Button == "A":
      break

  print("\n\n\n\n\n" + "="*60 + "\n\n        あっち向いてほいBATTLEGROUNDSへようこそ!" \
  + "\n\n\n    このゲームでは最大64人でトーナメント戦を行います。" \
  + "\n                    ルールは単純です。" \
  + "\n  あっち向いてほいで決められた点数を先に獲得したら勝利です。" \
  + "\n\n\n   トーナメントを勝ち抜いて優勝を目指して頑張りましょう!\n\n " + "="*60
  )

  print("\n\n\n\n\n" + "="*60 + "\n\nあっち向いてほいBATTLEGROUNDSの設定を決めてください")

  ##トーナメントプレイ人数を選択
  while True:
    try :
      all_player_num = int(input("\n\nプレイ人数を4,8,16,32,64人から選択してください >"))
      if all_player_num in [4, 8, 16, 32, 64]:
        break
    except:
      print("4,8,16,32,64を入力してください。")

  ##人間プレイヤーの人数を選択  
  while True:
    try:
      player_num = int(input(f"\n\n人間プレイヤーの人数を選択してください(最大人数は{all_player_num}人です) >"))
      if 1 <= player_num & player_num <= all_player_num:
        break
    except:
      print("数字以外を入力しないでください。")

  ##各人間プレイヤーの名前の入力
  player_name_list =[]
  for _ in range(0, player_num):
    player_name = input("\n\n人間プレイヤーの名前を記入してください。>")   
    player_name_list.append(player_name)
    print(f"<{player_name}>さんですね。エントリー完了しました。")

  ##試合のマッチポイントの入力
  while True:
    try:
      match_point = int(input(f"\n\n試合のマッチポイントを入力してください。 >"))
      if match_point >= 1:
        break
    except:
      print("1以上の整数を入力してください。")

  print("\n" + "="*60 + "\n\n\n\n\n")

  ##プレイヤーのインスタンスを配列(タプル型)に格納
  com_num = all_player_num - player_num
  players = *[Human(i) for i in player_name_list], *[Computer(f"コンピュータ{i}") for i in range(1, com_num + 1)]

  ##プレイヤーのインスタンスをシャッフルして配列(リスト型)に格納
  random_list = Tournament(players).shuffle()

  ##トーナメントが何回戦まであるか算出
  tournament_num = [i for i in range(1, all_player_num + 1) if all_player_num % i == 0]

  ##試合開始
  print(f"\n\n\n{match_point}ポイントマッチ制 {all_player_num}人トーナメントスタート!!\n\n")
  for n in range(1, len(tournament_num)):
      ###各2人組に分けた際の試合数
      game_num = Tournament(random_list, n).match()
      ###プレイヤーのリストから試合の敗者を除外
      losers_list = Tournament(random_list, n).battle(game_num, match_point)
      for loser in losers_list:
        random_list.remove(loser)
        if len(random_list) == 1:
          print(" " + "+*"*33) 
          print("*+"*34)
          print(f"     栄えある優勝者は{random_list[0].names}!!おめでとうございます!!!")
          print("*+"*34)
          print(" " + "+*"*33)
      ###勝ち残った参加者の勝利ポイントをリセット
      Tournament(random_list).score_reset()

  ##もう一度プレイするか選択
  while True:
    try:
      restart = input("\n\nもう一度プレイしますか?(Yes:y/No:n)")
      if restart == "y":
        hoi_battle_ground()
        break
      elif restart == "n":
        break
    except:
      print("yかnを入力してください")

#あっち向いてほいグラウンドメソッドを実行します。
  hoi_battle_ground()

【解説】

〔作り方〕

①各種ゲーム設定を入力できる機構を作成

⑴プレイヤー人数入力機構

  ##トーナメントプレイ人数を選択
  while True:
    try :
      all_player_num = int(input("\n\nプレイ人数を4,8,16,32,64人から選択してください >"))
      if all_player_num in [4, 8, 16, 32, 64]:
        break
    except:
      print("4,8,16,32,64を入力してください。")

⑵人間プレイヤー人数入力機構

  ##人間プレイヤーの人数を選択  
  while True:
    try:
      player_num = int(input(f"\n\n人間プレイヤーの人数を選択してください(最大人数は{all_player_num}人です) >"))
      if 1 <= player_num & player_num <= all_player_num:
        break
    except:
      print("数字以外を入力しないでください。")

⑶各人間プレイヤーの名前入力機構

  ##各人間プレイヤーの名前の入力
  player_name_list =[]
  for _ in range(0, player_num):
    player_name = input("\n\n人間プレイヤーの名前を記入してください。>")   
    player_name_list.append(player_name)
    print(f"<{player_name}>さんですね。エントリー完了しました。")

⑷試合のマッチポイント入力機構

  ##試合のマッチポイントの入力
  while True:
    try:
      match_point = int(input(f"\n\n試合のマッチポイントを入力してください。 >"))
      if match_point >= 1:
        break
    except:
      print("1以上の整数を入力してください。")

②プレイヤーのインスタンスを配列(タプル)に格納

⑴プレイヤーのインスタンスを配列に格納してまとめて扱いやすくする

  ##プレイヤーとコンピュータのインスタンスを配列(タプル型)に格納
  com_num = all_player_num - player_num
  players = *[Human(i) for i in player_name_list], *[Computer(f"コンピュータ{i}") for i in range(1, com_num + 1)]

"""
playersの中身(player:3, computer:5)
(<__main__.Human object at 0x7fd29607cad0>, <__main__.Human object at 0x7fd29607cc90>,
 <__main__.Human object at 0x7fd29607c2d0>, <__main__.Computer object at 0x7fd2960cd050>,
 <__main__.Computer object at 0x7fd29607cc50>, <__main__.Computer object at 0x7fd29607cb10>,
 <__main__.Computer object at 0x7fd29607c8d0>, <__main__.Computer object at 0x7fd29607ce90>)
"""

詳しい解説は前回の「③参加者のインスタンス配列を受け取りじゃんけんを実行するJankenクラスを作成」をご覧ください。

③各回戦の結果から優勝者を出力する機構を作成

⑴各回戦の敗者をプレイヤーリストから除き、最後の一人を優勝者として出力する機構

  ##トーナメントが何回戦まであるか算出(総プレイヤー数の約数-1)
  tournament_num = [i for i in range(1, all_player_num + 1) if all_player_num % i == 0]

  ##試合開始
  print(f"\n\n\n{match_point}ポイントマッチ制 {all_player_num}人トーナメントスタート!!\n\n")
  for n in range(1, len(tournament_num)):
      ###各2人組に分けた際の試合数
      game_num = Tournament(random_list, n).match()
      ###プレイヤーのリストから試合の敗者を除外
      losers_list = Tournament(random_list, n).battle(game_num, match_point)
      for loser in losers_list:
        random_list.remove(loser)
        if len(random_list) == 1:
          print(" " + "+*"*33) 
          print("*+"*34)
          print(f"     栄えある優勝者は{random_list[0].names}!!おめでとうございます!!!")
          print("*+"*34)
          print(" " + "+*"*33)
      ###勝ち残った参加者の勝利ポイントをリセット
      Tournament(random_list).score_reset()

この機構では、総プレイヤー人数からトーナメントが何回戦まであるか算出しその回数分for文を回します。各回戦ごとにlosers_listに敗者のインスタンスを格納してrandom_listからremoveメソッドを使って除いていきます。
敗者を取り除いたrandom_listにプレイヤーのインスタンスが複数残っている場合はfor文で次回戦に移ります。その際、前回戦で獲得したスコアを0ポイントにリセットします。
インスタンスが1つしか残っていない場合はそのインスタンスを優勝者として名前を出力します。

Tournamentクラスインスタンスメソッドが何をしているかについては③で詳しく解説します。

トーナメントが何回戦まであるか算出する方法
総プレイヤー数を1~総プレイヤー数で割って整数で割り切れる回数-1 == 約数-1
16人の場合
16/1,16/2,16/4,16/8,16/16 →4回戦まで
32人の場合
32/1,32/2,32/4,32/8,32/16,32/32 →5回戦まで

あっち向いてほいプログラムトーナメント表.png

④プレイヤーのインスタンス配列を受け取りトーナメントの各試合を実行するTournamentクラスを作成

⑴初期化メソッドを作成

#トーナメントクラス(試合のマッチング、各回戦の一連の試合を実行し敗者を選出、各回戦のスコアリセット)
class Tournament:

  def __init__(self, players, tournament_num=None):
    self.players = players
    self.tournament_num = tournament_num

このTournamentクラスは初期化メソッドインスタンス変数self.playersに全プレイヤーのインスタンスをまとめて代入します。
前回はJankenクラスがこの役割を果たしていましたが、今回はこのTournamentクラスが担っています。全プレイヤーを扱うインスタンスメソッドを作成して有効的にインスタンス変数self.playersを使っていきます。

⑵プレイヤーのインスタンス配列の順序をランダムに変更するshuffleインスタンスメソッドを作成

  ##プレイヤーの順番をランダムにシャッフル
  def shuffle(self):  
      random_list = [player for player in self.players]
      random.shuffle(random_list)
      return random_list

  ##プレイヤーのインスタンスをシャッフルして配列(リスト型)に格納
  random_list = Tournament(players).shuffle()

Tournamentクラスインスタンス作成とshuffle インスタンスメソッドの実行を同時に行うと、playersの中身のインスタンスがランダムにシャッフルされrandom_listとして戻ってきます。
一回トーナメントバトルが終わるまではずっとここで決まったインスタンスの組み合わせで試合が行われます。

⑶各回戦ごとにトーナメントの対戦表を出力するmatchインスタンスメソッドを作成

  ##2人ずつのグループに分けて対戦表を作成&出力
  def match(self):
    game_num = int(len(self.players) / 2)

    print("-"*35)
    if game_num == 1:
      print("決勝対戦表")
    elif game_num == 2:
      print("準決勝対戦表")
    else:
      print(f"第{self.tournament_num}回戦対戦表\n")

    for n in range(0, game_num):
      group_n = self.players[n*2:n*2+2] 
      print(f"{group_n[0].names} vs {group_n[1].names}")
    print("-"*35)
    return game_num

##試合開始
  print(f"\n\n\n{match_point}ポイントマッチ制 {all_player_num}人トーナメントスタート!!\n\n")
  for n in range(1, len(tournament_num)):
      ###各2人組に分けた際の試合数
      game_num = Tournament(random_list, n).match() #<<<<<<<<<<

試合開始して各回戦が始まる前にTournamentクラスmatchインスタンスメソッドを実行します。
このインスタンスメソッドは各回戦の試合数を計算しgame_numに代入して返り値として返します。また、各回戦のトーナメント対戦表を出力してくれます。

⑷各試合の一連の流れを実行するbattleインスタンスメソッドを作成

  ##第〇回戦の全試合を実施して負けた参加者を配列(リスト型)に格納
  def battle(self, game_num, match_point):
    losers_list = []
    for n in range(0, game_num):
      group_n = self.players[n*2:n*2+2] 
      print("-"*35)
      if game_num == 1:
        print("決勝戦")
      elif game_num == 2:
        print(f"準決勝戦 第{n+1}試合")
      else:
        print(f"第{self.tournament_num}回戦 第{n+1}試合")
      print(f"\n{group_n[0].names} vs {group_n[1].names}")
      print("-"*35)
      while True:
        loser = Janken(group_n).play(match_point)
        if loser:
          losers_list.append(loser)
          break
    return losers_list

##試合開始
  print(f"\n\n\n{match_point}ポイントマッチ制 {all_player_num}人トーナメントスタート!!\n\n")
  for n in range(1, len(tournament_num)):
      ###各2人組に分けた際の試合数
      game_num = Tournament(random_list, n).match()
      ###プレイヤーのリストから試合の敗者を除外
      losers_list = Tournament(random_list, n).battle(game_num, match_point) #<<<<<<<<<<

試合開始して各回戦が始まるとTournamentクラスbattleインスタンスメソッドを実行します。このインスタンスメソッドを実行すると、各回戦ごとの全試合から敗者をリストにして返してくれます。
battleインスタンスメソッドの引数にgame_num(試合数)とmatch_pointを渡すことで、一試合match_point分先取制で受け取った試合数game_num分をfor文で繰り返します。
一試合の流れを説明すると、まずその試合が何回戦で第何試合で誰と誰が対戦しているのか出力します。
次に、Jankenクラスplayインスタンスメソッドを実行して返り値として敗者のインスタンスが帰ってきたらwhile文を終了してlosers_listに敗者のインスタンスを追加します。
for文を全試合数分回したらloser_listbattleインスタンスメソッドの返り値として返します。

⑸各回戦ごとに勝ち残ったプレイヤーの勝利ポイントを0にリセットするscore_resetインスタンスメソッドを作成

  ##スコアリセット
  def score_reset(self):
    for player in self.players:
      player.score = 0

  ##試合開始
  print(f"\n\n\n{match_point}ポイントマッチ制 {all_player_num}人トーナメントスタート!!\n\n")
  for n in range(1, len(tournament_num)):
      ###各2人組に分けた際の試合数
      game_num = Tournament(random_list, n).match()
      ###プレイヤーのリストから試合の敗者を除外
      losers_list = Tournament(random_list, n).battle(game_num, match_point)
      for loser in losers_list:
        random_list.remove(loser)
        if len(random_list) == 1:
          print(" " + "+*"*33) 
          print("*+"*34)
          print(f"     栄えある優勝者は{random_list[0].names}!!おめでとうございます!!!")
          print("*+"*34)
          print(" " + "+*"*33)
      ###勝ち残った参加者の勝利ポイントをリセット
      Tournament(random_list).score_reset() #<<<<<<<<<<

各回戦が終了した時点で勝ち残っているプレイヤーの勝利ポイントは全員3ポイントあります。このまま次回戦を始めてしまうと最初から3ポイント獲得した状態になってしまいます。
この問題を解決するのがこのscore_resetインスタンスメソッドです。
このインスタンスメソッドを実行すると各プレイヤーの勝利ポイントに0を代入してくれます。これで問題なく次回戦に進ませることが出来ます。

⑤Jankenクラスを一部変更

⑴勝敗判定部分を一部変更

  ##じゃんけんの一連の流れを実行
  def play(self, match_point):
    print("\n>>>じゃんけんぽん!<<<")
    self.pon()
    while True:
      ###judgeインスタンスメソッドの返り値の第一項をj_winnerに、第二項をj_loserに代入
      j_winner, j_loser = self.judge()           
      if j_winner:
        ###j_winnerがTrue、つまり勝者がいる場合
        print(f"\n\n◎◎{j_winner.names}の勝ち!◎◎")
        break
      else:
        ###いない場合はもう一度じゃんけん  
        print("\n△△あいこでしょ!!△△")
        self.pon()
    ##勝者が決まったら返り値であっち向いてほいを実行する
    return Hoi(j_winner, j_loser).play(self.group_n, match_point)


  ##プレイヤーのじゃんけんの手があいこか否かを判定、あいこでなければ勝者を決定
  def judge(self):
    hands = set(player.hand for player in self.group_n)
    if len(hands) != 2:
      return None, None
    hand1, hand2 = hands
    win = hand1 if hand1.stronger_than(hand2) else hand2
    ###二人のうち勝者はインスタンスをwinnerに代入、敗者はloserに代入する形に変更
    for player in self.group_n:
      if player.hand == win:
        winner = player 
      else:
        loser = player
    ###複数返り値
    return winner, loser

前回の大人数じゃんけんプログラムで使用したコードを基本的には転用していますが、今回は勝者に加え敗者も明確にする必要があるのでjudgeインスタンスメソッドを変更しました。
詳しくは上記のコードのメモをご覧ください。

⑵返り値でHoiクラスplayインスタンスメソッドを実行

  ##じゃんけんの一連の流れを実行
  def play(self, match_point):
    print("\n>>>じゃんけんぽん!<<<")
    self.pon()
    while True:
      ###judgeインスタンスメソッドの返り値の第一項をj_winnerに、第二項をj_loserに代入
      j_winner, j_loser = self.judge()           
      if j_winner:
        ###j_winnerがTrue、つまり勝者がいる場合
        print(f"\n\n◎◎{j_winner.names}の勝ち!◎◎")
        break
      else:
        ###いない場合はもう一度じゃんけん  
        print("\n△△あいこでしょ!!△△")
        self.pon()
    ##勝者が決まったら返り値であっち向いてほいを実行する
    return Hoi(j_winner, j_loser).play(self.group_n, match_point) #<<<<<<<<<<

Hoiクラスインスタンスj_winner, j_loser(勝者と敗者)を渡します。
同時にHoiクラスplayインスタンスメソッドに引数としてself.group_n(その試合の二人のプレイヤー)を第一項に、match_pointを第二項に渡しています。
これであっち向いてほいを実行することができます。
詳しい意味は⑥で説明します。

⑥Hoiクラスを作成

⑴初期化メソッドを作成

#あっち向いてほいクラス(あっち向いてほいをする際の手と指の選択&出力、勝敗判定)
class Hoi:

  def __init__(self, j_winner, j_loser):
    self.j_winner = j_winner
    self.j_loser = j_loser

Jankenクラスの返り値としてHoiクラスインスタンスを作成しました。その際に受け取った勝者と敗者のインスタンスを初期化メソッドself.j_winnerself.j_loserに保持します。

⑵あっち向いてほいの一連の流れを実行するplayインスタンスメソッドを作成

  ##あっち向いてほいをプレイして勝者を出力し敗者を返り値で返す
  def play(self, group_n, match_point):
    print("\n\n>>>あっち向いてほい!<<<")
    self.hoi()
    if self.j_winner.finger == self.j_loser.face:
      print(f"\n\n◎◎◎{self.j_winner.names}の勝利!1ポイント獲得!◎◎◎")
      self.j_winner.score += 1
      if self.j_winner.score < match_point:
        print(f"\n\n現在のポイント \
              \n{group_n[0].names}:{group_n[0].score}ポイント \
              \n{group_n[1].names}:{group_n[1].score}ポイント")
        return
      else:
        print(f"\n\n><><><>{match_point}ポイント先取により{self.j_winner.names}の勝利!<><><><\n\n")
        return self.j_loser        
    else:
      print("××じゃんけんに戻る××")
      return

このインスタンスメソッドではあっち向いてほいの一連の流れを実行します。
まずはself.hoiを実行してプレイヤーに顔か指を選択させ出力します。
詳しい内容は⑥の⑶で解説します。
次に、じゃんけん勝者の指とじゃんけん敗者の顔の向きが同じか判定します。
向きが同じ場合はじゃんけん勝者の勝利となり、勝者の名前を出力した後にポイントを追加します。
勝利ポイントがマッチポイント未満である場合は両者の現在のポイントを出力した後に空の返り値を返します。ここで空の返り値を返すとJankenクラスplayインスタンスメソッドの返り値も空になり、Tournamentクラスbattleインスタンスメソッドのwhile文から抜け出せずもう一度じゃんけんからやり直しになります。
勝利ポイントがマッチポイントまで達した場合は勝者の名前を出力した上で敗者のインスタンスを返り値として返します。敗者を受け取ることでTournamentクラスbattleインスタンスメソッドwhile文から抜け出せて次の試合に移ることができます。 向きが異なる場合は空の返り値を返して、勝利ポイントがマッチポイント未満であった場合と同じくじゃんけんをやり直します。

あっち向いてほいプログラムフローチャート.drawio.png

⑶プレイヤーに顔か指を選択させ出力するhoiインスタンスメソッドを作成

  ##プレイヤー同士の出した指と顔の向きを出力
  def hoi(self):
    self.j_winner.hoi("w")
    self.j_loser.hoi("l")
    print(f"{self.j_winner.names}の手:{self.j_winner.finger}")
    print(f"{self.j_loser.names}の手:{self.j_loser.face}")

このインスタンスメソッドではプレイヤーにあっち向いてほいの顔か指を選択させます。
Humanクラスインスタンスメソッドself.j_winner.hoi()Computerクラスインスタンスメソッドself.j_loser.hoi()を実行することで選択してもらいます。引数で"w"と"l"を渡しているのは、HumanクラスComputerクラス側で顔の選択か指の選択か場合分けを行う為です。詳しくは⑦の⑴と⑵でコードを確認してみてください。

⑦HumanクラスとComputerクラスを一部変更

⑴ヒューマンクラスhoiインスタンスメソッドを作成

#ヒューマンクラス(じゃんけんの手の選択、あっち向いてほいの手の選択)
class Human(Scoresheet):

  ##人間プレイヤーの手を選択
  def pon(self):
    print('選択肢:', HANDS)
    while True:
      try:
        hand = input(f"{self.names}の出す手を入力してください(整数:1, 2, 3) 〉")
        if hand in ("1", "2", "3"):
            self.hand = HANDS[int(hand)]
            return
      except:
         print("整数:1, 2, 3を入力してください。")

  ##人間プレイヤーの指か顔の向きを選択
  def hoi(self, j_result):
    if j_result == "w":
      print(FINGER)
      while True:
        try:
          finger = input("あなたの指の向きを選択してください(整数:1,2,3,4) 〉")
          if finger in ("1","2","3","4"):
            self.finger = FINGER[int(finger)]
            return
        except:
          print("整数1,2,3,4を入力してください")  
    else:
      while True:
        try:
          face = input("あなたの顔の向きを選択してください(整数:1,2,3,4) 〉")
          if face in ("1","2","3","4"):
            self.face = FACE[int(face)]
            return
        except:
          print("整数1,2,3,4を入力して下さい")

FACE = {1:"↑",2:"→",3:"↓",4:"←"}
FINGER = {1:"↑",2:"→",3:"↓",4:"←"}

Humanクラスhoiインスタンスメソッドを追加します。
Hoiクラスhoiインスタンスメソッドで渡された引数"w"か"l"によって顔の選択か指の選択か場合分けを行います。指はself.fingerに、顔はself.faceに代入します。

⑵コンピュータクラスhoiインスタンスメソッドを作成

#コンピュータクラス(じゃんけんの手の選択、あっち向いてほいの手の選択)
class Computer(Scoresheet):

  ##コンピュータの手を選択
  def pon(self):
    self.hand = random.choice(list(HANDS.values()))

  ##コンピュータの指か顔の向きを選択
  def hoi(self, j_result):
    if j_result == "w":
        self.finger = random.choice(list(FINGER.values()))
    else:
        self.face = random.choice(list(FACE.values()))

FACE = {1:"↑",2:"→",3:"↓",4:"←"}
FINGER = {1:"↑",2:"→",3:"↓",4:"←"}

Computerクラスhoiインスタンスメソッドを追加します。
Hoiクラスhoiインスタンスメソッドで渡された引数"w"か"l"によって顔の選択か指の選択か場合分けを行います。指はself.fingerに、顔はself.faceに代入します。

⑧スーパークラスScoresheetを作成

HumanクラスComputerクラスに共通する「属性」である"名前"と"勝利ポイント"をスーパークラスインスタンス変数に保持させる

#スコアシートクラス(プレイヤーの名前を保持、プレイヤーの得点を保持)
class Scoresheet:

  def __init__(self, names, score=0):
    self.names = names
    self.score = score

HumanクラスComputerクラスに共通してある「属性」は、"名前"と"勝利ポイント"です。前回の「②ヒューマンクラスとコンピュータクラスに名前と勝利ポイントを受け取る初期化メソッドを追加」ではHumanクラスComputerクラスにそれぞれ初期化メソッドで"名前"と"勝利ポイント"を保持していたのですが、今回はScoresheetスーパークラスを使います。ScoresheetクラスHumanクラスComputerクラスを包含する関係にあるため、プレイヤーの”名前”と”勝利ポイント”をまとめて全員分一つのクラスの初期化メソッドに保持しておくと関係が分かりやすいです。また、後々全員の「属性」に対してまとめて処理を施したいときに役立ちます。

クラスの継承の基礎について
既存のクラスAのインスタンス変数インスタンスメソッドを新たに作ったクラスBが引き継いで使用することができます。この仕組みを継承と言います。
継承されるクラスを「スーパークラス」「親クラス」「基底クラス」、
継承するクラスを「サブクラス」「子クラス」「派生クラス」などと言います。
※今後は「スーパークラス/サブクラス」を使って説明していきます。
あっち向いてほいプログラム 継承.png

オーバーライドについて
スーパークラスに既存のインスタンス変数インスタンスメソッドをサブクラスで新たに書き換えたい場合に行うのがオーバーライドです。
だた、書き換えた後に元のインスタンスメソッドインスタンス変数を使いたい場合があります。そんな時に使うのがsuper()です。
インスタンスメソッドの場合
super().スーパー<font color="81C4FF">**クラス**</font>のインスタンスメソッド名()
インスタンス変数の場合
def __init__(self, スーパークラスの初期化メソッドの引数, サブクラスの初期化メソッドの引数):
super().__init__(スーパークラスの初期化メソッドの引数)

このようにしてサブクラスで書き換えたものと元のスーパークラスのもの両方使えるようになります。

⑨再度プレイするか選択させる機構を作成

⑴再度プレイ機構

  ##もう一度プレイするか選択
  while True:
    try:
      restart = input("\n\nもう一度プレイしますか?(Yes:y/No:n)")
      if restart == "y":
        hoi_battle_ground()
        break
      elif restart == "n":
        break
    except:
      print("yかnを入力してください")

【終わりに】

今回はあっち向いてほいプログラムを作っていきました。
難易度はいかがだったでしょうか。機能要件はいかがだったでしょうか。解説はいかがだったでしょうか。なるべく正確かつ分かりやすい解説に努めましたが、もしもコーディングの部分で間違いなどありましたら編集リクエストからご指摘いただけると幸いです。また、その他質問などございましたらコメントをお願い致します。

今回作ったプログラムで地味に大変だったのが、出力の見やすさを確保するためにprintでの改行や装飾の調整をすることでした。もっと見やすい形で出力できないかなと考えていた時に出会ったのがGUIでした。GUIGraphical User Interfaceと言って、ユーザーが見やすいようにウィンドウ上で図やボタンなどを表示して選択や操作ができるインターフェイスのことです。私たちが利用しているユーザー向けアプリのほとんどはこのGUIを使って使いやすさを実現しているようです。
ということで次回は、今回作ったあっち向いてほいプログラムから「あっち向いてほいプログラム」のGUIアプリを作りたいと思います。下記リンクからどうぞ!
ぬかさんエンジニアリングの次回作をお待ちください

この記事が良かったと感じたらLGTMを宜しくお願いします!それではまた次回!:wave:

0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1