現在の見出し:4.1節:連続戦闘の作成
見出し一覧
- 4.1節:連続戦闘の作成
- - while文による戦闘ループ機能の実装
- - continue文による入力エラー処理と逃走機能の実装
【PR】『Python』を学べる企業・個人向けのプログラミングコース
while文による戦闘ループ機能の実装
前節(第3章3.2節)で作成したコードを基盤として、while文を使った連続戦闘システムを実装します。前節では1ターンのみの戦闘で複雑な攻撃順序判定が必要でしたが、while文により「プレイヤー行動→敵行動→勝敗判定」を繰り返す単純な流れに整理されています。
while文の条件には「player_hp > 0 and enemy_hp > 0」を設定し、どちらか一方のHPが0以下になった時点で戦闘が終了する仕組みです。戦闘ループ内では前節までの行動選択・ダメージ計算・防御効果・回復機能をそのまま活用し、ターン数カウンターを追加することで戦闘の進行状況を把握できます。各ターン終了後に戦闘継続条件を自動的に判定し、長期戦でも現在の戦況を確認しながらプレイできます。
while文による戦闘ループの実装により、攻撃・防御・回復の選択タイミングが勝敗に大きく影響する本格的なRPGが完成します。プレイヤーは長期的な戦略を立てながら戦闘を進行でき、より深いゲーム体験を得ることができます。
# コード
print("=== RPGゲーム開始 ===")
player_name = input("プレイヤー名を入力してください: ")
player_hp = int(input("初期HPを入力してください: "))
player_attack = int(input("攻撃力を入力してください: "))
# 初期データ管理変数の設定
max_player_hp = player_hp
player_defense = 5
battle_count = 0
game_active = True
is_defending = False
# 敵データ自動計算
enemy_name = "ゴブリン"
enemy_max_hp = int(player_hp * 1.2) + (battle_count * 10)
enemy_hp = enemy_max_hp
enemy_attack = int(player_attack * 0.8) + (battle_count * 2)
enemy_defense = 3 + battle_count
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"基本HP: {player_hp} × 1.2 + {battle_count} × 10 = {enemy_max_hp}")
print(f"基本攻撃力: {player_attack} × 0.8 + {battle_count} × 2 = {enemy_attack}")
print(f"基本防御力: 3 + {battle_count} = {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
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}")
# 行動選択システムの実装
print(f"\n=== {player_name}のターン ===")
print("行動を選択してください:")
print("1. 攻撃 (1/攻撃/ATTACK/A)")
print("2. 防御 (2/防御/DEFENSE/D)")
print("3. 回復 (3/回復/HEAL/H)")
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}")
else:
print(f"\n【エラー】無効な選択です: {action}")
print("有効な選択肢: 1/攻撃/ATTACK/A, 2/防御/DEFENSE/D, 3/回復/HEAL/H")
continue
# 敵HP確認と戦闘継続判定
if enemy_hp <= 0:
print(f"\n【勝利】{enemy_name}を倒した!")
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
# 戦闘結果の表示
print(f"\n=== 最終戦闘結果 ===")
print(f"戦闘ターン数: {turn_count}")
print(f"{player_name} 最終HP: {player_hp}/{max_player_hp}")
print(f"{enemy_name} 最終HP: {enemy_hp}/{enemy_max_hp}")
if player_hp > 0:
print(f"\n【勝利】{player_name}の勝利!")
print(f"{enemy_name}に与えたダメージ: {enemy_max_hp - enemy_hp}")
print(f"受けたダメージ: {max_player_hp - player_hp}")
print(f"勝利までのターン数: {turn_count}")
else:
print(f"\n【敗北】{enemy_name}の勝利...")
print(f"{enemy_name}に与えたダメージ: {enemy_max_hp - enemy_hp}")
print(f"受けたダメージ: {max_player_hp}")
print(f"生存ターン数: {turn_count}")
print(f"\n戦闘ループ処理完了!")
行数 | 種別 | コード | 解説 |
---|---|---|---|
36行目 | 新規 | turn_count = 0 |
戦闘ターン数をカウントする変数を初期化 |
38行目 | 新規 | while player_hp > 0 and enemy_hp > 0: |
プレイヤーと敵の両方が生存している間は戦闘を継続するwhile文の条件設定 |
39行目 | 新規 | turn_count += 1 |
各ターン開始時にターン数を1増加させる |
40行目 | 新規 | print(f"\n=== ターン {turn_count} ===") |
現在のターン数を表示してターンの区切りを明確化 |
41行目 | 新規 | print(f"{player_name} HP: {player_hp}/{max_player_hp}") |
各ターン開始時にプレイヤーの現在HP状況を表示 |
42行目 | 新規 | print(f"{enemy_name} HP: {enemy_hp}/{enemy_max_hp}") |
各ターン開始時に敵の現在HP状況を表示 |
74行目 | 新規 | continue |
無効な行動選択時にループの次の繰り返しに進む |
76行目 | 新規 | if enemy_hp <= 0: |
プレイヤーの行動後に敵のHPが0以下になったかを判定 |
77行目 | 新規 | print(f"\n【勝利】{enemy_name}を倒した!") |
敵を倒した時の勝利メッセージを表示 |
78行目 | 新規 | break |
敵を倒した時点でwhile文の戦闘ループから脱出 |
80行目 | 新規 | print(f"\n=== {enemy_name}のターン ===") |
敵の攻撃ターンの開始を表示 |
103行目 | 新規 | if player_hp <= 0: |
敵の攻撃後にプレイヤーのHPが0以下になったかを判定 |
104行目 | 新規 | print(f"\n【敗北】{player_name}は力尽きた...") |
プレイヤーが力尽きた時の敗北メッセージを表示 |
105行目 | 新規 | break |
プレイヤーが力尽きた時点でwhile文の戦闘ループから脱出 |
107行目 | 新規 | print(f"\n=== 最終戦闘結果 ===") |
戦闘終了後の最終結果セクションの開始を表示 |
108行目 | 新規 | print(f"戦闘ターン数: {turn_count}") |
最終的な戦闘に要したターン数を表示 |
109行目 | 新規 | print(f"{player_name} 最終HP: {player_hp}/{max_player_hp}") |
プレイヤーの戦闘終了時のHP状況を表示 |
110行目 | 新規 | print(f"{enemy_name} 最終HP: {enemy_hp}/{enemy_max_hp}") |
敵の戦闘終了時のHP状況を表示 |
112行目 | 新規 | if player_hp > 0: |
戦闘終了後にプレイヤーが生存しているかで勝敗を判定 |
113行目 | 新規 | print(f"\n【勝利】{player_name}の勝利!") |
プレイヤーが勝利した場合の最終勝利メッセージを表示 |
114行目 | 新規 | print(f"{enemy_name}に与えたダメージ: {enemy_max_hp - enemy_hp}") |
敵に与えた総ダメージ量を計算して表示 |
115行目 | 新規 | print(f"受けたダメージ: {max_player_hp - player_hp}") |
プレイヤーが受けた総ダメージ量を計算して表示 |
116行目 | 新規 | print(f"勝利までのターン数: {turn_count}") |
勝利までに要したターン数を表示 |
117行目 | 新規 | else: |
プレイヤーが敗北した場合の処理分岐 |
118行目 | 新規 | print(f"\n【敗北】{enemy_name}の勝利...") |
プレイヤーが敗北した場合の最終敗北メッセージを表示 |
119行目 | 新規 | print(f"{enemy_name}に与えたダメージ: {enemy_max_hp - enemy_hp}") |
敗北時でも敵に与えた総ダメージ量を表示 |
120行目 | 新規 | print(f"受けたダメージ: {max_player_hp}") |
敗北時はプレイヤーの最大HPがそのまま受けたダメージ量になる |
121行目 | 新規 | print(f"生存ターン数: {turn_count}") |
敗北までにプレイヤーが生存したターン数を表示 |
123行目 | 新規 | print(f"\n戦闘ループ処理完了!") |
while文による戦闘ループ機能の実装完了を表示 |