ジョブを設定して戦闘にバリエーションをつけよう
今回はキャラクターを戦士、盗賊、術師というジョブに分けて、そのジョブに対応したパラメーターを設定してみましょう。
戦士はHPや防御力は高いが敏捷性が低く、盗賊は敏捷性は高いがその他は平均的なステータス、術師は攻撃力は高いがHPや防御力が低くなるようにしています。
実行イメージ
実行イメージは、以下の通りです。
画面の表示は、前回と同様です。
実行例
C:\>python battle5-1.py
戦士A Aチーム HP[69] 攻撃力[17] 防御力[15] 敏捷性[ 3]
盗賊B Aチーム HP[67] 攻撃力[ 7] 防御力[11] 敏捷性[20]
術師C Aチーム HP[45] 攻撃力[26] 防御力[ 3] 敏捷性[ 7]
戦士D Bチーム HP[78] 攻撃力[14] 防御力[15] 敏捷性[ 5]
盗賊E Bチーム HP[68] 攻撃力[ 7] 防御力[10] 敏捷性[14]
術師F Bチーム HP[30] 攻撃力[26] 防御力[ 5] 敏捷性[10]
盗賊Eは盗賊Bの攻撃をかわした!
術師Fは戦士Aに28のダメージ
→ 戦士Aの残HP[41]
盗賊Eは盗賊Bに3のダメージ
→ 盗賊Bの残HP[64]
戦士Dは盗賊Bの攻撃をかわした!
術師Cは盗賊Eに44のダメージ
戦士Dは術師Cに25のダメージ
→ 盗賊Eの残HP[24]
→ 術師Cの残HP[20]
中略
術師Cは盗賊Eに44のダメージ
→ 盗賊Eの残HP[0]
.... 盗賊Eは倒された ....
盗賊Bは術師Fに20のダメージ
→ 術師Fの残HP[10]
戦士Dは術師Cに30のダメージ
→ 術師Cの残HP[0]
盗賊Bは戦士Dに2のダメージ
→ 戦士Dの残HP[35]
術師Fは盗賊Bに40のダメージ
→ 盗賊Bの残HP[0]
.... 術師Cは倒された ....
.... 盗賊Bは倒された ....
戦士Aは術師Fに20のダメージ
→ 術師Fの残HP[0]
戦士Dは戦士Aに33のダメージ
→ 戦士Aの残HP[0]
.... 術師Fは倒された ....
.... 戦士Aは倒された ....
++ Bチーム 戦士Dの勝利! ++
Pythonスクリプト
Playerクラスに新たにself.jobという変数を追加して、ジョブによってパラメーターの値を変えるようにしています。
戦士のみ攻撃が確率でクリティカルになるように設定しています。(96行目)
また、術師の攻撃は防御力が無効となります。(100行目)
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
### インポート import time import random import threading ### 定数 PLAYER = [["戦士A","A","WAR"], ["盗賊B","A","THF"], ["術師C","A","MAG"], ["戦士D","B","WAR"], ["盗賊E","B","THF"], ["術師F","B","MAG"]] ############################ ### プレイヤークラス ############################ class Player(threading.Thread): ############################ ### 初期化メソッド ############################ def __init__(self, name, team, job): ### Threadクラスの初期化 threading.Thread.__init__(self) ### クラス変数設定 self.name = name # プレイヤー名 self.team = team # 所属チーム self.job = job # 職業 ### 体力 if self.job == "WAR": self.hp = random.randint(30, 90) elif self.job == "THF": self.hp = random.randint(24, 72) else: self.hp = random.randint(18, 54) ### 攻撃力 if self.job == "WAR": self.atk = random.randint( 9, 18) elif self.job == "THF": self.atk = random.randint( 6, 12) else: self.atk = random.randint(18, 36) ### 防御力 if self.job == "WAR": self.dfn = random.randint( 9, 18) elif self.job == "THF": self.dfn = random.randint( 6, 12) else: self.dfn = random.randint( 3, 6) ### 敏捷性 if self.job == "WAR": self.agi = random.randint( 3, 6) elif self.job == "THF": self.agi = random.randint(12, 24) else: self.agi = random.randint( 6, 12) ### ステータスを表示 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]) ### ダメージ値取得 if self.job == "WAR": damage = max(0, (self.atk + random.randint(0, 20) - enemy.dfn)) * critical[0] if self.job == "THF": damage = max(0, (self.atk + random.randint(0, 20) - enemy.dfn)) else: damage = max(0, (self.atk + random.randint(0, 20))) ### 相手プレイヤーの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],name[2]) for name in PLAYER] ### スレッドを開始 for player in players: player.start() ############################ ### メイン関数呼び出し ############################ if __name__ == "__main__": ### 処理開始 main() |