こんにちは、Tech Samuraiです!
前回の記事「【実践OOPプロジェクト #2】RPGの心臓部!ターン制バトルシステムを構築しよう」では、キャラクターたちが自動で戦うための戦闘ループを実装しましたね。
私たちのRPGは動くようになりましたが、まだ少しシンプルすぎます。プレイヤーも敵も画一的で、回復する手段もありません。シリーズ最終回となる今回は、これまで学んだ**継承**の力を最大限に活用して、この世界に深みと戦略性を与える、以下の3つの要素を追加します!
- 独自のスキルを持つ専門職**「戦士 (Warrior)」クラス**
- 特殊な攻撃を仕掛けてくる強敵**「オーク (Orc)」クラス**
- 戦闘中にHPを回復できる**「回復薬 (Potion)」アイテム**
この最終章を通して、オブジェクト指向設計が、いかにプログラムを柔軟で拡張性の高いものにするかを、ぜひ体感してください!
ステップ1:継承で専門職を創る – 「Warrior」クラス
まずは、Player
クラスを継承して、より攻撃に特化した「戦士」クラスを作成します。戦士には、通常攻撃よりも強力ですが、少しだけ失敗する可能性もある必殺技「スマッシュ」を授けましょう。
# Playerクラスを継承
class Warrior(Player):
def __init__(self, name, hp, attack_power):
# 親クラス(Player)の初期化処理を呼び出す
super().__init__(name, hp, attack_power)
print(f"百戦錬磨の {self.name} が戦場に現れた!")
# Warrior独自のメソッド
def smash_attack(self, target):
print(f"💥 {self.name} の必殺技! スマッシュ!")
# 80%の確率で成功
if random.random() < 0.8:
damage = self.attack_power * 2 # ダメージは通常攻撃の2倍
target.take_damage(damage)
else:
print(" しかし、攻撃は外れてしまった!")
Player
を継承しているので、通常のattack()
ももちろん使えます。後ほど、戦闘ループの中で、プレイヤーが戦士だった場合にのみ、この「スマッシュ」を選択できるように変更します。
ステップ2:手強い敵を創る – 「Orc」クラス
同様に、Enemy
クラスを継承して、少し賢い強敵「オーク」を作成します。オークは、時々、痛恨の一撃(クリティカルヒット)を放ってくるという特徴を持たせましょう。
ここでは、親のattack
メソッドの振る舞いを変更する**オーバーライド**を使います。
# Enemyクラスを継承
class Orc(Enemy):
def __init__(self, name, hp, attack_power):
super().__init__(name, hp, attack_power)
print(f"屈強な {self.name} が雄叫びをあげている!")
# 親のattackメソッドをオーバーライド(上書き)
def attack(self, target):
print(f"💥 {self.name} の brutalな攻撃!")
# 25%の確率でクリティカルヒット
if random.random() < 0.25:
print(" 痛恨の一撃!")
damage = self.attack_power * 2
else:
damage = self.attack_power
target.take_damage(damage)
ステップ3:アイテムの導入とインベントリ
次に、戦闘の戦略性を高める「アイテム」を導入します。ここでもOOPの考え方を活かし、「アイテム」という大きな概念のクラスを作り、それを継承して具体的な「回復薬」クラスを作成します。
class Item:
"""アイテムの親クラス"""
def __init__(self, name):
self.name = name
def use(self, target):
# アイテムを使うという基本動作
print(f"{target.name} は {self.name} を使った!")
class Potion(Item):
"""回復薬クラス"""
def __init__(self, name, healing_amount):
super().__init__(name)
self.healing_amount = healing_amount
def use(self, target):
super().use(target) # 親のuseメソッドを呼び出す
print(f" HPが {self.healing_amount} 回復した!")
target.hp += self.healing_amount # セッター経由で安全にHPを更新
そして、プレイヤーがアイテムを持てるように、Player
クラスの__init__
を修正して、「インベントリ(所持品リスト)」を追加します。
# Playerクラスの__init__メソッドを修正
class Player(Character):
def __init__(self, name, hp, attack_power):
super().__init__(name, hp, attack_power)
self.inventory = [] # インベントリを追加
ステップ4:最終形態!進化したバトルシステム
新しい職業、敵、アイテムに対応するため、戦闘を司るBattle
クラスのstart
メソッドを大幅にアップグレードします。プレイヤーの行動選択肢を増やし、より複雑な判断ができるようにします。
# Battleクラスのstartメソッドを修正
class Battle:
# ... (initは同じ) ...
def start(self):
# ... (戦闘開始のメッセージなど) ...
while self.player.is_alive() and self.enemy.is_alive():
# ... (ステータス表示など) ...
# --- プレイヤーの行動選択 ---
print("どうする?")
action_list = ["1: 攻撃"]
# isinstance()で、プレイヤーがWarriorクラスのオブジェクトか判定
if isinstance(self.player, Warrior):
action_list.append("2: スマッシュ")
if self.player.inventory: # インベントリにアイテムがあれば
action_list.append("3: アイテム")
action_list.append("4: 逃げる")
action = input(" ".join(action_list) + ": ")
# --- 行動の分岐 ---
if action == '1':
self.player.attack(self.enemy)
elif action == '2' and isinstance(self.player, Warrior):
self.player.smash_attack(self.enemy)
elif action == '3' and self.player.inventory:
# アイテムを使う処理
for i, item in enumerate(self.player.inventory):
print(f"{i+1}: {item.name}")
item_choice = int(input("どのアイテムを使いますか?: ")) - 1
if 0 <= item_choice < len(self.player.inventory):
item = self.player.inventory.pop(item_choice)
item.use(self.player)
elif action == '4':
print(f"{self.player.name}は逃げ出した!")
break
else:
print("コマンドが認識できませんでした。")
# ... (敵のターンと戦闘終了の処理は同じ) ...
isinstance(player, Warrior)
という関数を使うことで、「もしプレイヤーが戦士なら」という、オブジェクトの種類に応じた条件分岐が実現できています。これぞポリモーフィズム(多態性)の入り口です。
まとめ:そして、冒険は続く
3回にわたる実践OOPプロジェクト、お疲れ様でした!私たちは、シンプルなクラスの定義から始め、継承とカプセル化を駆使して、職業、強敵、アイテムといった要素を持つ、拡張性の高いRPGの世界を創造しました。
- **継承**を使い、
Player
やEnemy
から専門的なクラス(Warrior
,Orc
)を派生させる方法。 - 親クラスのメソッドを**オーバーライド**し、子クラス独自の振る舞いを実装する方法。
- アイテムのような概念もクラスとして設計し、キャラクターの**属性(インベントリ)**として持たせる方法。
isinstance()
を使い、オブジェクトの種類に応じて処理を分岐させる、より高度なロジック。
このプロジェクトで学んだ「**変更や拡張がしやすいように、役割ごとにクラスを設計する**」という考え方は、あらゆるソフトウェア開発の現場で通用する、非常に強力なスキルです。
このゲームには、まだまだ拡張の余地が無限に残されています。魔法使いクラス、新しいアイテム、複数の敵との戦闘、経験値とレベルアップ…。ぜひ、あなたがゲームマスターとなって、この世界をさらに豊かにしてみてください。
これにて、テキストベースRPG開発シリーズは完結です。素晴らしい冒険でしたね! Happy Coding!
コメント