現在の見出し:4.2節:複数敵戦闘の作成
見出し一覧
- 4.2節:複数敵戦闘の作成
- - for文・range()による連続戦闘機能の実装
- - リスト操作による敵データ管理機能の実装
【PR】『Python』を学べる企業・個人向けのプログラミングコース
for文・range()による連続戦闘機能の実装
前節(第4章4.1節)で作成したコードを基盤として、for文とrange()関数関数は一定の処理をまとめたプログラムの塊です。を使った連続戦闘機能を実装します。今までは1体の敵との戦闘でしたが、今回は3体の敵「ゴブリン」「オーク」「ドラゴン」と連続で戦うRPGシステムを構築します。
for文とrange(3)により3回の戦闘を繰り返し、各敵のステータスを戦闘回数に応じて段階的に強化します。勝利すると次の敵との戦闘に進み、敗北するとゲームオーバーとなります。連続戦闘のバランス調整として、各戦闘の勝利時にHPの小回復を行い、プレイヤーが最後まで戦い抜けるよう配慮されています。
この連続戦闘システムにより、RPGらしい戦略性の高いゲーム体験が実現できます。プレイヤーは各戦闘でのHP管理と行動選択を慎重に行い、3体すべての敵を倒すという明確なゴールに向かって戦略を立てることになります。
# コード
print("=== RPGゲーム開始 ===")
player_name = input("プレイヤー名を入力してください: ")
player_hp = int(input("初期HPを入力してください: "))
player_attack = int(input("攻撃力を入力してください: "))
# 初期データ管理変数の設定
max_player_hp = player_hp
player_defense = 5
game_active = True
is_defending = False
print(f"\n【プレイヤー情報】")
print(f"名前: {player_name}")
print(f"HP: {player_hp}/{max_player_hp}")
print(f"攻撃力: {player_attack}")
print(f"防御力: {player_defense}")
print("プレイヤー作成完了!")
print(f"\n=== 連続戦闘開始 ===")
print(f"{player_name}は3体の敵と連続で戦うことになった!")
# for文・range()による連続戦闘の実装
for battle_count in range(3):
print(f"\n=== 戦闘 {battle_count + 1}/3 ===")
# 敵データの動的生成
enemy_names = ["ゴブリン", "オーク", "ドラゴン"]
enemy_name = enemy_names[battle_count]
enemy_max_hp = int(player_hp * 1.2) + (battle_count * 20)
enemy_hp = enemy_max_hp
enemy_attack = int(player_attack * 0.8) + (battle_count * 5)
enemy_defense = 3 + (battle_count * 2)
print(f"\n【敵ステータス計算過程】")
print(f"基本HP: {int(player_hp * 1.2)} + {battle_count} × 20 = {enemy_max_hp}")
print(f"基本攻撃力: {int(player_attack * 0.8)} + {battle_count} × 5 = {enemy_attack}")
print(f"基本防御力: 3 + {battle_count} × 2 = {enemy_defense}")
print(f"\n【敵情報】")
print(f"名前: {enemy_name}")
print(f"HP: {enemy_hp}/{enemy_max_hp}")
print(f"攻撃力: {enemy_attack}")
print(f"防御力: {enemy_defense}")
print("敵データ自動生成完了!")
print(f"\n=== 戦闘開始 ===")
print(f"{player_name} vs {enemy_name}")
# while文による戦闘ループの実装
turn_count = 0
max_turns = 20
escape_attempts = 0
while player_hp > 0 and enemy_hp > 0:
turn_count += 1
print(f"\n=== ターン {turn_count} ===")
print(f"{player_name} HP: {player_hp}/{max_player_hp}")
print(f"{enemy_name} HP: {enemy_hp}/{enemy_max_hp}")
# 長期戦による自動引き分け判定
if turn_count > max_turns:
print(f"\n【引き分け】{max_turns}ターンが経過したため戦闘を終了します")
break
# 行動選択システムの実装
print(f"\n=== {player_name}のターン ===")
print("行動を選択してください:")
print("1. 攻撃 (1/攻撃/ATTACK/A)")
print("2. 防御 (2/防御/DEFENSE/D)")
print("3. 回復 (3/回復/HEAL/H)")
print("4. 逃走 (4/逃走/ESCAPE/E)")
action = input("行動選択: ").upper()
# 行動分岐処理機能の実装
if action in ["1", "攻撃", "ATTACK", "A"]:
print(f"\n【攻撃選択】{player_name}が攻撃を選択しました!")
player_damage = player_attack - enemy_defense
player_damage = 1 if player_damage < 1 else player_damage
enemy_hp -= player_damage
print(f"{player_name}が{enemy_name}に{player_damage}のダメージを与えた!")
print(f"{enemy_name}のHP: {enemy_hp}/{enemy_max_hp}")
elif action in ["2", "防御", "DEFENSE", "D"]:
print(f"\n【防御選択】{player_name}が防御を選択しました!")
is_defending = True
temp_defense_boost = 10
total_defense = player_defense + temp_defense_boost
print(f"{player_name}は身を守る構えを取った!")
print(f"防御力が一時的に {player_defense} → {total_defense} に向上!")
print(f"次に受けるダメージが半減されます")
elif action in ["3", "回復", "HEAL", "H"]:
print(f"\n【回復選択】{player_name}が回復を選択しました!")
heal_amount = int(max_player_hp * 0.3)
before_heal_hp = player_hp
player_hp = player_hp + heal_amount if player_hp + heal_amount <= max_player_hp else max_player_hp
actual_heal = player_hp - before_heal_hp
print(f"{player_name}は回復魔法を唱えた!")
print(f"回復量計算: {max_player_hp} × 0.3 = {heal_amount}ポイント")
print(f"HP計算: {before_heal_hp} + {heal_amount} = {before_heal_hp + heal_amount}")
if before_heal_hp + heal_amount > max_player_hp:
print(f"上限制限適用: {before_heal_hp + heal_amount} → {max_player_hp} (最大HP)")
print(f"実際の回復量: {actual_heal}ポイント")
print(f"{player_name}のHP: {before_heal_hp} → {player_hp}")
elif action in ["4", "逃走", "ESCAPE", "E"]:
print(f"\n【逃走選択】{player_name}が逃走を選択しました!")
escape_attempts += 1
# 攻撃力の差による逃走成功率の計算
attack_difference = player_attack - enemy_attack
base_success_rate = 50
if attack_difference > 0:
success_rate = base_success_rate + (attack_difference * 2)
success_rate = 90 if success_rate > 90 else success_rate
else:
success_rate = base_success_rate + (attack_difference * 2)
success_rate = 10 if success_rate < 10 else success_rate
print(f"逃走判定: 攻撃力差 {attack_difference} による成功率 {success_rate}%")
# 逃走試行回数による判定
if escape_attempts >= 2:
print(f"逃走試行 {escape_attempts} 回目: 自動成功")
print(f"{player_name}は戦闘から逃走した!")
print(f"逃走成功! 連続戦闘を中断します")
break
elif (turn_count * 17) % 100 < success_rate:
print(f"逃走試行 {escape_attempts} 回目: 成功")
print(f"{player_name}は戦闘から逃走した!")
print(f"逃走成功! 連続戦闘を中断します")
break
else:
print(f"逃走試行 {escape_attempts} 回目: 失敗")
print(f"逃走に失敗! {enemy_name}に捕まった!")
print(f"敵のターンに移行します")
else:
print(f"\n【エラー】無効な選択です: {action}")
print("有効な選択肢: 1/攻撃/ATTACK/A, 2/防御/DEFENSE/D, 3/回復/HEAL/H, 4/逃走/ESCAPE/E")
print("もう一度選択してください")
continue
# 敵HP確認と戦闘継続判定
if enemy_hp <= 0:
print(f"\n【勝利】{enemy_name}を倒した!")
# 勝利時の小回復処理
victory_heal = int(max_player_hp * 0.2)
before_victory_hp = player_hp
player_hp = player_hp + victory_heal if player_hp + victory_heal <= max_player_hp else max_player_hp
actual_victory_heal = player_hp - before_victory_hp
print(f"勝利ボーナス: HP {victory_heal} 回復!")
print(f"実際の回復量: {actual_victory_heal}ポイント")
print(f"{player_name}のHP: {before_victory_hp} → {player_hp}")
break
# 逃走成功時の連続戦闘中断判定
if escape_attempts >= 1 and (escape_attempts >= 2 or (turn_count * 17) % 100 < success_rate):
print(f"\n【連続戦闘中断】逃走により連続戦闘を終了します")
break
# 敵の攻撃ターン
print(f"\n=== {enemy_name}のターン ===")
base_enemy_damage = enemy_attack - player_defense
base_enemy_damage = 1 if base_enemy_damage < 1 else base_enemy_damage
if is_defending:
temp_defense_boost = 10
enhanced_defense = player_defense + temp_defense_boost
enhanced_enemy_damage = enemy_attack - enhanced_defense
enhanced_enemy_damage = 1 if enhanced_enemy_damage < 1 else enhanced_enemy_damage
final_enemy_damage = enhanced_enemy_damage // 2
final_enemy_damage = 1 if final_enemy_damage < 1 else final_enemy_damage
print(f"【防御効果発動】")
print(f"基本ダメージ: {enemy_attack} - {enhanced_defense} = {enhanced_enemy_damage}")
print(f"防御により半減: {enhanced_enemy_damage} ÷ 2 = {final_enemy_damage}")
player_hp -= final_enemy_damage
print(f"{enemy_name}の攻撃を防御! {final_enemy_damage}のダメージ!")
is_defending = False
else:
final_enemy_damage = base_enemy_damage
player_hp -= final_enemy_damage
print(f"{enemy_name}が{player_name}に{final_enemy_damage}のダメージを与えた!")
print(f"{player_name}のHP: {player_hp}/{max_player_hp}")
# プレイヤーHP確認と戦闘継続判定
if player_hp <= 0:
print(f"\n【敗北】{player_name}は力尽きた...")
break
# 各戦闘終了後の結果判定
if player_hp <= 0:
print(f"\n【ゲームオーバー】")
print(f"{player_name}は{battle_count + 1}戦目で力尽きました")
print(f"到達した戦闘: {battle_count + 1}/3")
print(f"倒した敵の数: {battle_count}")
break
elif escape_attempts >= 1 and (escape_attempts >= 2 or (turn_count * 17) % 100 < success_rate):
print(f"\n【連続戦闘中断】")
print(f"{player_name}は{battle_count + 1}戦目で逃走しました")
print(f"到達した戦闘: {battle_count + 1}/3")
print(f"倒した敵の数: {battle_count}")
break
elif turn_count > max_turns:
print(f"\n【引き分け終了】")
print(f"{player_name}は{battle_count + 1}戦目で引き分けました")
print(f"到達した戦闘: {battle_count + 1}/3")
print(f"倒した敵の数: {battle_count}")
break
else:
print(f"\n【戦闘 {battle_count + 1} 完了】")
if battle_count < 2:
print(f"次の敵との戦闘に進みます")
print(f"現在のHP: {player_hp}/{max_player_hp}")
else:
print(f"\n【全戦闘勝利】")
print(f"{player_name}は全ての敵を倒した!")
print(f"勇者の完全勝利!")
print(f"最終HP: {player_hp}/{max_player_hp}")
print(f"\n=== 連続戦闘結果 ===")
print(f"連続戦闘機能実装完了!")
行数 | 種別 | コード | 解説 |
---|---|---|---|
7行目 | 変更 | game_active = True |
前節の「battle_count = 0」を「game_active = True」に変更し、連続戦闘の進行状況管理に対応 |
18行目 | 新規 | print(f"\n=== 連続戦闘開始 ===") |
連続戦闘モードの開始を表示するメッセージを追加 |
19行目 | 新規 | print(f"{player_name}は3体の敵と連続で戦うことになった!") |
3体の敵との連続戦闘であることをプレイヤーに説明 |
21行目 | 新規 | for battle_count in range(3): |
for文とrange(3)を使って3回の戦闘を繰り返すループを開始 |
22行目 | 新規 | print(f"\n=== 戦闘 {battle_count + 1}/3 ===") |
現在の戦闘番号と総戦闘数を表示(battle_countは0から始まるため+1で調整) |
24行目 | 新規 | enemy_names = ["ゴブリン", "オーク", "ドラゴン"] |
3体の敵の名前をリストで定義し、battle_countで順次選択できるように設定 |
25行目 | 変更 | enemy_name = enemy_names[battle_count] |
前節の固定敵名「ゴブリン」を、リストからbattle_countに応じた敵名を取得する方式に変更 |
26行目 | 変更 | enemy_max_hp = int(player_hp * 1.2) + (battle_count * 20) |
前節の「(battle_count * 10)」を「(battle_count * 20)」に変更し、より大きな段階的強化を実現 |
28行目 | 変更 | enemy_attack = int(player_attack * 0.8) + (battle_count * 5) |
前節の「(battle_count * 2)」を「(battle_count * 5)」に変更し、攻撃力の段階的強化を強化 |
29行目 | 変更 | enemy_defense = 3 + (battle_count * 2) |
前節の「3 + battle_count」を「3 + (battle_count * 2)」に変更し、防御力の段階的強化を強化 |
31行目 | 変更 | print(f"基本HP: {int(player_hp * 1.2)} + {battle_count} × 20 = {enemy_max_hp}") |
前節の「× 10」を「× 20」に変更し、HP強化計算式の表示を更新 |
32行目 | 変更 | print(f"基本攻撃力: {int(player_attack * 0.8)} + {battle_count} × 5 = {enemy_attack}") |
前節の「× 2」を「× 5」に変更し、攻撃力強化計算式の表示を更新 |
33行目 | 変更 | print(f"基本防御力: 3 + {battle_count} × 2 = {enemy_defense}") |
前節の単純加算から「× 2」を追加し、防御力強化計算式の表示を更新 |
125行目 | 変更 | print(f"逃走成功! 連続戦闘を中断します") |
前節の「逃走成功!」に「連続戦闘を中断します」を追加し、連続戦闘への影響を明示 |
130行目 | 変更 | print(f"逃走成功! 連続戦闘を中断します") |
前節の「逃走成功!」に「連続戦闘を中断します」を追加し、連続戦闘への影響を明示 |
143行目 | 新規 | victory_heal = int(max_player_hp * 0.2) |
勝利ボーナスとして最大HPの20%を回復量として計算 |
144行目 | 新規 | before_victory_hp = player_hp |
勝利時回復前のHP値を記録し、実際の回復量計算に使用 |
145行目 | 新規 | player_hp = player_hp + victory_heal if player_hp + victory_heal <= max_player_hp else max_player_hp |
三項演算子三項演算子は条件分岐を簡潔に記述するための構文で、1つの式で条件式と2つの結果を表現し、if-else文の省略形として機能します。により勝利時回復を適用し、最大HPを超えない制限を設定 |
146行目 | 新規 | actual_victory_heal = player_hp - before_victory_hp |
実際に回復したHP量を計算(上限制限により計算値と異なる場合があるため) |
147行目 | 新規 | print(f"勝利ボーナス: HP {victory_heal} 回復!") |
勝利時の回復ボーナスをプレイヤーに通知 |
148行目 | 新規 | print(f"実際の回復量: {actual_victory_heal}ポイント") |
上限制限を考慮した実際の回復量を表示 |
149行目 | 新規 | print(f"{player_name}のHP: {before_victory_hp} → {player_hp}") |
勝利時回復による HP の変化を before → after の形式で表示 |
153行目 | 新規 | if escape_attempts >= 1 and (escape_attempts >= 2 or (turn_count * 17) % 100 < success_rate): |
逃走試行が発生し、かつ成功条件(2回目以降 or 成功率判定)を満たした場合の判定 |
154行目 | 新規 | print(f"\n【連続戦闘中断】逃走により連続戦闘を終了します") |
逃走成功により連続戦闘全体を中断することを表示 |
155行目 | 新規 | break |
逃走成功時にwhile文による戦闘ループから脱出 |
181行目 | 新規 | if player_hp <= 0: |
プレイヤーが敗北した場合の処理分岐を設定 |
182行目 | 新規 | print(f"\n【ゲームオーバー】") |
プレイヤー敗北時のゲームオーバーメッセージを表示 |
183行目 | 新規 | print(f"{player_name}は{battle_count + 1}戦目で力尽きました") |
どの戦闘で敗北したかを表示(battle_countは0から始まるため+1で調整) |
184行目 | 新規 | print(f"到達した戦闘: {battle_count + 1}/3") |
総戦闘数に対してどこまで到達したかを表示 |
185行目 | 新規 | print(f"倒した敵の数: {battle_count}") |
敗北戦闘前までに倒した敵の数を表示 |
186行目 | 新規 | break |
敗北時にbreak文でfor文の連続戦闘ループから脱出 |
187行目 | 新規 | elif escape_attempts >= 1 and (escape_attempts >= 2 or (turn_count * 17) % 100 < success_rate): |
逃走成功により連続戦闘が中断された場合の処理分岐 |
188行目 | 新規 | print(f"\n【連続戦闘中断】") |
逃走による連続戦闘の中断を表示 |
189行目 | 新規 | print(f"{player_name}は{battle_count + 1}戦目で逃走しました") |
どの戦闘で逃走したかを表示 |
190行目 | 新規 | print(f"到達した戦闘: {battle_count + 1}/3") |
逃走時の到達戦闘数を表示 |
191行目 | 新規 | print(f"倒した敵の数: {battle_count}") |
逃走前までに倒した敵の数を表示 |
192行目 | 新規 | break |
逃走時にbreak文でfor文の連続戦闘ループから脱出 |
193行目 | 新規 | elif turn_count > max_turns: |
引き分けにより戦闘が終了した場合の処理分岐 |
194行目 | 新規 | print(f"\n【引き分け終了】") |
引き分けによる戦闘終了を表示 |
195行目 | 新規 | print(f"{player_name}は{battle_count + 1}戦目で引き分けました") |
どの戦闘で引き分けになったかを表示 |
196行目 | 新規 | print(f"到達した戦闘: {battle_count + 1}/3") |
引き分け時の到達戦闘数を表示 |
197行目 | 新規 | print(f"倒した敵の数: {battle_count}") |
引き分け前までに倒した敵の数を表示 |
198行目 | 新規 | break |
引き分け時にbreak文でfor文の連続戦闘ループから脱出 |
199行目 | 新規 | else: |
戦闘に勝利して次の戦闘に進む場合の処理分岐 |
200行目 | 新規 | print(f"\n【戦闘 {battle_count + 1} 完了】") |
現在の戦闘の勝利完了を表示 |
201行目 | 新規 | if battle_count < 2: |
まだ次の戦闘が残っている場合(0, 1番目の戦闘)の判定 |
202行目 | 新規 | print(f"次の敵との戦闘に進みます") |
次の戦闘への進行を表示 |
203行目 | 新規 | print(f"現在のHP: {player_hp}/{max_player_hp}") |
次戦闘に向けた現在のHP状況を表示 |
204行目 | 新規 | else: |
全ての戦闘に勝利した場合(2番目の戦闘完了)の処理分岐 |
205行目 | 新規 | print(f"\n【全戦闘勝利】") |
3体全ての敵に勝利したことを表示 |
206行目 | 新規 | print(f"{player_name}は全ての敵を倒した!") |
プレイヤーの完全勝利を表示 |
207行目 | 新規 | print(f"勇者の完全勝利!") |
英雄的な勝利を讃えるメッセージを表示 |
208行目 | 新規 | print(f"最終HP: {player_hp}/{max_player_hp}") |
全戦闘勝利時の最終HP状況を表示 |
210行目 | 変更 | print(f"\n=== 連続戦闘結果 ===") |
前節の「最終戦闘結果」を「連続戦闘結果」に変更し、連続戦闘機能に対応 |
211行目 | 変更 | print(f"連続戦闘機能実装完了!") |
前節の「戦闘制御機能実装完了!」を「連続戦闘機能実装完了!」に変更 |