キャラクターに防御力を設定して、相手の攻撃を相殺しよう
今回は前回のプログラムからキャラクターに防御力を設定して、相手の攻撃を相殺する処理を追加します。
ただし、攻撃を防御で相殺してしまうと相手に与えるダメージが少なくなってしまうので、一定の確率でダメージが2倍、3倍になるように調整します。
実行イメージ
ダメージが0の時は、「〇〇は△△の攻撃をかわした!」と表示するようにします。
実行例
C:\>python battle4-1.py
戦士A Aチーム HP[48] 攻撃力[ 2] 防御力[ 7] 敏捷性[ 5]
戦士B Aチーム HP[32] 攻撃力[15] 防御力[13] 敏捷性[13]
戦士C Aチーム HP[23] 攻撃力[ 4] 防御力[ 8] 敏捷性[19]
戦士D Bチーム HP[16] 攻撃力[14] 防御力[ 9] 敏捷性[12]
戦士E Bチーム HP[29] 攻撃力[11] 防御力[10] 敏捷性[ 7]
戦士F Bチーム HP[72] 攻撃力[20] 防御力[ 9] 敏捷性[ 8]
戦士Cは戦士Eに20のダメージ
→ 戦士Eの残HP[9]
戦士Fは戦士Aに18のダメージ
→ 戦士Aの残HP[30]
戦士Dは戦士Bに42のダメージ
.... 戦士Bは倒された ....
→ 戦士Bの残HP[0]
戦士Cは戦士Fに2のダメージ
→ 戦士Fの残HP[70]
戦士Eは戦士Aに11のダメージ
戦士Fは戦士Cの攻撃をかわした!
→ 戦士Aの残HP[19]
戦士Dは戦士Cに22のダメージ
→ 戦士Cの残HP[1]
戦士Fは戦士Aの攻撃をかわした!
戦士Cは戦士Dに30のダメージ
戦士Fは戦士Aに44のダメージ
→ 戦士Dの残HP[0]
→ 戦士Aの残HP[0]
.... 戦士Dは倒された ....
戦士Eは戦士Cに16のダメージ
→ 戦士Cの残HP[0]
.... 戦士Cは倒された ....
.... 戦士Aは倒された ....
++ Bチーム 戦士Fの勝利! ++
++ Bチーム 戦士Eの勝利! ++
Pythonスクリプト
前回の違いとして、Playerクラスに防御力(self.dfn)を追加します。
random.choices()を使って、攻撃力が一定の確率で2倍、3倍となるようにしています。
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 106 107 108 109 110 111 112 113 114 |
### インポート 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.dfn = random.randint( 1, 20) # 防御力 self.agi = random.randint( 1, 20) # 敏捷性 ### ステータスを表示 print("{:<4} {}チーム HP[{:>2}] 攻撃力[{:>2}] 防御力[{:>2}] 敏捷性[{:>2}]".format(self.name, self.team, self.hp, self.atk, self.dfn, 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 ### クリティカル係数取得(1倍x60%、2倍x30%、3倍x10%) critical = random.choices([1,2,3], weights=[6,3,1]) ### ダメージ値取得 damage = max(0, (self.atk + random.randint(0, 20) - enemy.dfn)) * critical[0] ### 相手プレイヤーのHPを減算 enemy.hp -= damage ### 相手プレイヤーのHPが0未満なら0にする if enemy.hp < 0: enemy.hp = 0 ### メッセージ表示 if damage == 0: print("{}は{}の攻撃をかわした!".format(enemy.name, self.name)) else: 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() |