スレッドを使ってチーム戦の戦闘シミレーションで作ろう
今回はスレッドを使って、チーム戦の戦闘シミュレーションを作りましょう。
大まかなプログラムは前回と同じですが、プレイヤーの定義に名前の他にチーム名を設定して、攻撃対象を相手チームのみにします。
実行イメージ
6人をAチームとBチームに分けて、相手チームのメンバーを攻撃します。
どちらかのチームが全滅したら終了となります。
実行例
C:\>python battle3-1.py
戦士A Aチーム HP[38] 攻撃力[ 4] 敏捷性[ 3]
戦士B Aチーム HP[29] 攻撃力[17] 敏捷性[14]
戦士C Aチーム HP[72] 攻撃力[ 4] 敏捷性[18]
戦士D Bチーム HP[12] 攻撃力[ 7] 敏捷性[ 8]
戦士E Bチーム HP[66] 攻撃力[ 3] 敏捷性[ 5]
戦士F Bチーム HP[26] 攻撃力[ 6] 敏捷性[14]
戦士Cは戦士Dに4のダメージ
→ 戦士Dの残HP[8]
戦士Bは戦士Dに17のダメージ
→ 戦士Dの残HP[0]
戦士Fは戦士Aに14のダメージ
.... 戦士Dは倒された ....
→ 戦士Aの残HP[24]
戦士Cは戦士Fに9のダメージ
→ 戦士Fの残HP[17]
戦士Fは戦士Cに15のダメージ
戦士Bは戦士Fに26のダメージ
→ 戦士Fの残HP[0]
戦士Eは戦士Cに12のダメージ
→ 戦士Cの残HP[45]
.... 戦士Fは倒された ....
中略
戦士Aは戦士Eに9のダメージ
戦士Eは戦士Aに3のダメージ
→ 戦士Eの残HP[18]
→ 戦士Aの残HP[21]
戦士Bは戦士Eに24のダメージ
→ 戦士Eの残HP[0]
.... 戦士Eは倒された ....
++ Aチーム 戦士Aの勝利! ++
++ Aチーム 戦士Cの勝利! ++
++ Aチーム 戦士Bの勝利! ++
Pythonスクリプト
前回との違いは、以下の通りです。
- プレイヤーの定義を2次元配列にして名前とチーム名を設定する
- 同じチーム名の場合は攻撃をしない
- 相手チームのスレッドが無くなったら処理を終了する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
### インポート import time import random import threading ### 定数 PLAYER = [["戦士A","A"], ["戦士B","A"], ["戦士C","A"], ["戦士D","B"], ["戦士E","B"], ["戦士F","B"]] ############################ ### プレイヤークラス ############################ class Player(threading.Thread): ############################ ### 初期化メソッド ############################ def __init__(self, name, team): ### Threadクラスの初期化 threading.Thread.__init__(self) ### クラス変数設定 self.name = name # プレイヤー名 self.team = team # 所属チーム self.hp = random.randint(10, 99) # 体力 self.atk = random.randint( 1, 20) # 攻撃力 self.agi = random.randint( 1, 20) # 敏捷性 ### ステータスを表示 print("{:<4} {}チーム HP[{:>2}] 攻撃力[{:>2}] 敏捷性[{:>2}]".format(self.name, self.team, self.hp, self.atk, self.agi)) ############################ ### 攻撃メソッド ############################ def run(self): ### 自分のHPが0になるまでループ while self.hp > 0: ### 次の攻撃まで待機 time.sleep(5 / (self.agi + random.randint(0, 10))) ### Main以外のスレッドを取得 enemies = [enemy for enemy in threading.enumerate()[1:]] ### 対象をシャッフル random.shuffle(enemies) ### 対象をループ for enemy in enemies: ### 自チームだったら飛ばす if self.team == enemy.team: continue ### 自分または相手のHPが0なら終了 if self.hp == 0 or enemy.hp == 0: break ### 相手プレイヤーのHPを減算 damage = self.atk + random.randint(0, 10) enemy.hp -= damage ### 相手プレイヤーのHPが0未満なら0にする if enemy.hp < 0: enemy.hp = 0 ### メッセージ表示 print("{}は{}に{}のダメージ".format(self.name, enemy.name, damage)) print(" → {}の残HP[{}]".format(enemy.name, enemy.hp)) ### 一人倒したら一旦終了 break ### 自分のHPが0ならメッセージ表示 if self.hp == 0: print(" .... {}は倒された ....".format(self.name)) break ### 相手チームがいなければ終了 enemies = [enemy for enemy in enemies if self.team != enemy.team] if len(enemies) == 0: print("++ {}チーム {}の勝利! ++".format(self.team, self.name)) break ############################ ### メイン関数 ############################ def main(): ### プレイヤーを作成 players = [Player(name[0],name[1]) for name in PLAYER] ### スレッドを開始 for player in players: player.start() ############################ ### メイン関数呼び出し ############################ if __name__ == "__main__": ### 処理開始 main() |