ログアウト中 ログイン

学習パッケージを選択

【Python】簡易RPG作成講座 第4章4.2節「複数敵戦闘の作成」




現在の見出し: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"連続戦闘機能実装完了!") 前節の「戦闘制御機能実装完了!」を「連続戦闘機能実装完了!」に変更
リスト操作による敵データ管理機能の実装

第4章4.2節「リスト操作による敵データ管理機能の実装」の続きを見る


すべてのカリキュラムを無料登録で学ぶ

プログラミング・マーケティング・AI活用方法を
今すぐ無料登録すると、全てのコンテンツが視聴可能になります。