1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラミング未経験者や初心者のためのウォータフォールの詳細設計書クラス図入門

Last updated at Posted at 2025-07-16

プログラミング初心者のためのクラス図入門 - ポケモンで学ぶオブジェクト指向

目次

はじめに

詳細設計書でクラス図を作る必要があるけれど、そもそも「クラス」って何?という方のために、ポケモンを例にしてクラス図の基本を分かりやすく解説します。

1. クラスとは何か?

クラスは、同じような特徴や機能を持つものの「設計図」や「型」のことです。

ポケモンで例えると:

  • ポケモンクラス = すべてのポケモンが持つ共通の設計図
  • ピカチュウ、フシギダネ、ヒトカゲ = その設計図から作られた具体的なポケモン(インスタンス)

2. クラス図の基本構造

クラス図は3つの部分に分かれています:

2.1 クラス名

一番上の部分。クラスの名前を書きます。

2.2 属性(フィールド)

真ん中の部分。そのクラスが持つデータ(特徴)を書きます。

2.3 メソッド(操作)

一番下の部分。そのクラスができること(機能)を書きます。

3. 具体的なポケモンクラス図

属性の説明:

  • name: ポケモンの名前(例:ピカチュウ)
  • type: ポケモンのタイプ(例:でんき)
  • level: レベル(例:25)
  • hp: 体力(例:100)
  • attack_power: 攻撃力(例:55)

メソッドの説明:

  • getName(): 名前を取得する
  • attack(): 他のポケモンを攻撃する
  • takeDamage(): ダメージを受ける
  • levelUp(): レベルアップする
  • isAlive(): 生きているかチェックする

Pythonコード例

Python版ポケモンクラス
class Pokemon:
    def __init__(self, name: str, pokemon_type: str, level: int = 1, hp: int = 100, attack_power: int = 50):
        self._name = name
        self._type = pokemon_type
        self._level = level
        self._hp = hp
        self._max_hp = hp
        self._attack_power = attack_power
    
    def get_name(self) -> str:
        return self._name
    
    def get_type(self) -> str:
        return self._type
    
    def attack(self, target: 'Pokemon') -> None:
        damage = self._attack_power
        print(f"{self._name}の攻撃! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)
    
    def take_damage(self, damage: int) -> None:
        self._hp -= damage
        if self._hp < 0:
            self._hp = 0
        print(f"{self._name}の残りHP: {self._hp}")
    
    def level_up(self) -> None:
        self._level += 1
        self._hp += 10
        self._max_hp += 10
        self._attack_power += 5
        print(f"{self._name}がレベルアップ! レベル{self._level}になった!")
    
    def is_alive(self) -> bool:
        return self._hp > 0
    
    def __str__(self) -> str:
        return f"{self._name}(Lv.{self._level}, HP:{self._hp}/{self._max_hp})"

Javaコード例

Java版ポケモンクラス
public class Pokemon {
    private String name;
    private String type;
    private int level;
    private int hp;
    private int maxHp;
    private int attackPower;
    
    public Pokemon(String name, String type, int level, int hp, int attackPower) {
        this.name = name;
        this.type = type;
        this.level = level;
        this.hp = hp;
        this.maxHp = hp;
        this.attackPower = attackPower;
    }
    
    public String getName() {
        return name;
    }
    
    public String getType() {
        return type;
    }
    
    public int getLevel() {
        return level;
    }
    
    public int getHp() {
        return hp;
    }
    
    public void attack(Pokemon target) {
        int damage = this.attackPower;
        System.out.println(this.name + "の攻撃! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    public void takeDamage(int damage) {
        this.hp -= damage;
        if (this.hp < 0) {
            this.hp = 0;
        }
        System.out.println(this.name + "の残りHP: " + this.hp);
    }
    
    public void levelUp() {
        this.level++;
        this.hp += 10;
        this.maxHp += 10;
        this.attackPower += 5;
        System.out.println(this.name + "がレベルアップ! レベル" + this.level + "になった!");
    }
    
    public boolean isAlive() {
        return this.hp > 0;
    }
    
    @Override
    public String toString() {
        return name + "(Lv." + level + ", HP:" + hp + "/" + maxHp + ")";
    }
}

4. 継承関係を表現する

ポケモンには様々なタイプがあります。継承を使って表現してみましょう。

継承の意味:

  • ElectricPokemon FirePokemon GrassPokemonPokemonの特徴をすべて持っている
  • さらに、でんきタイプ特有の技や属性を追加で持っている
  • <|--の矢印は「継承」を表す

Pythonコード例

Python版ポケモン継承
class ElectricPokemon(Pokemon):
    def __init__(self, name: str, level: int = 1, hp: int = 100, attack_power: int = 50):
        super().__init__(name, "でんき", level, hp, attack_power)
        self._electric_power = 30
    
    def thunderbolt(self, target: Pokemon) -> None:
        damage = self._attack_power + self._electric_power
        print(f"{self._name}の10まんボルト! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)
    
    def spark(self, target: Pokemon) -> None:
        damage = self._attack_power + (self._electric_power // 2)
        print(f"{self._name}のスパーク! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)


class FirePokemon(Pokemon):
    def __init__(self, name: str, level: int = 1, hp: int = 100, attack_power: int = 50):
        super().__init__(name, "ほのお", level, hp, attack_power)
        self._fire_power = 35
    
    def flamethrower(self, target: Pokemon) -> None:
        damage = self._attack_power + self._fire_power
        print(f"{self._name}のかえんほうしゃ! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)
    
    def ember(self, target: Pokemon) -> None:
        damage = self._attack_power + (self._fire_power // 2)
        print(f"{self._name}のひのこ! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)


class GrassPokemon(Pokemon):
    def __init__(self, name: str, level: int = 1, hp: int = 100, attack_power: int = 50):
        super().__init__(name, "くさ", level, hp, attack_power)
        self._grass_power = 25
    
    def vine_whip(self, target: Pokemon) -> None:
        damage = self._attack_power + self._grass_power
        print(f"{self._name}のつるのムチ! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)
    
    def razor_leaf(self, target: Pokemon) -> None:
        damage = self._attack_power + (self._grass_power // 2)
        print(f"{self._name}のはっぱカッター! {target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)

Javaコード例

Java版ポケモン継承
public class ElectricPokemon extends Pokemon {
    private int electricPower;
    
    public ElectricPokemon(String name, int level, int hp, int attackPower) {
        super(name, "でんき", level, hp, attackPower);
        this.electricPower = 30;
    }
    
    public void thunderbolt(Pokemon target) {
        int damage = super.attackPower + this.electricPower;
        System.out.println(super.getName() + "の10まんボルト! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    public void spark(Pokemon target) {
        int damage = super.attackPower + (this.electricPower / 2);
        System.out.println(super.getName() + "のスパーク! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    protected void setElectricPower(int electricPower) {
        this.electricPower = electricPower;
    }
    
    protected int getElectricPower() {
        return electricPower;
    }
}

public class FirePokemon extends Pokemon {
    private int firePower;
    
    public FirePokemon(String name, int level, int hp, int attackPower) {
        super(name, "ほのお", level, hp, attackPower);
        this.firePower = 35;
    }
    
    public void flamethrower(Pokemon target) {
        int damage = super.attackPower + this.firePower;
        System.out.println(super.getName() + "のかえんほうしゃ! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    public void ember(Pokemon target) {
        int damage = super.attackPower + (this.firePower / 2);
        System.out.println(super.getName() + "のひのこ! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    protected void setFirePower(int firePower) {
        this.firePower = firePower;
    }
    
    protected int getFirePower() {
        return firePower;
    }
}

public class GrassPokemon extends Pokemon {
    private int grassPower;
    
    public GrassPokemon(String name, int level, int hp, int attackPower) {
        super(name, "くさ", level, hp, attackPower);
        this.grassPower = 25;
    }
    
    public void vineWhip(Pokemon target) {
        int damage = super.attackPower + this.grassPower;
        System.out.println(super.getName() + "のつるのムチ! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    public void razorLeaf(Pokemon target) {
        int damage = super.attackPower + (this.grassPower / 2);
        System.out.println(super.getName() + "のはっぱカッター! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    protected void setGrassPower(int grassPower) {
        this.grassPower = grassPower;
    }
    
    protected int getGrassPower() {
        return grassPower;
    }
}

5. 具体的なポケモンたち

考え方:

  • ElectricPokemonPokemon を継承して宣言している
  • Pikachu RaichuElectricPokemon を継承して宣言している

Pythonコード例

Python版具体的なポケモンクラス
class Pikachu(ElectricPokemon):
    def __init__(self, level: int = 25):
        super().__init__("ピカチュウ", level, 100, 55)
        self._electric_power = 40  # ピカチュウは電気技が得意
    
    def pika_pika(self) -> None:
        print("ピカピカ〜!")


class Raichu(ElectricPokemon):
    def __init__(self, level: int = 30):
        super().__init__("ライチュウ", level, 120, 65)
        self._electric_power = 50  # ライチュウはより強力
    
    def rai_rai(self) -> None:
        print("ライライ〜!")


class Charmander(FirePokemon):
    def __init__(self, level: int = 5):
        super().__init__("ヒトカゲ", level, 80, 45)
    
    def char_char(self) -> None:
        print("ヒトカゲ〜!")


class Bulbasaur(GrassPokemon):
    def __init__(self, level: int = 5):
        super().__init__("フシギダネ", level, 90, 40)
    
    def bulba_bulba(self) -> None:
        print("フシギダネ〜!")

Javaコード例

Java版具体的なポケモンクラス
public class Pikachu extends ElectricPokemon {
    public Pikachu() {
        this(25); // デフォルトレベル25
    }
    
    public Pikachu(int level) {
        super("ピカチュウ", level, 100, 55);
        super.setElectricPower(40); // ピカチュウは電気技が得意
    }
    
    public void pikaPika() {
        System.out.println("ピカピカ〜!");
    }
    
    @Override
    public void thunderbolt(Pokemon target) {
        System.out.println("ピカチュウの必殺技!");
        super.thunderbolt(target);
    }
}

public class Raichu extends ElectricPokemon {
    public Raichu() {
        this(30); // デフォルトレベル30
    }
    
    public Raichu(int level) {
        super("ライチュウ", level, 120, 65);
        super.setElectricPower(50); // ライチュウはより強力
    }
    
    public void raiRai() {
        System.out.println("ライライ〜!");
    }
    
    @Override
    public void thunderbolt(Pokemon target) {
        System.out.println("ライチュウの強力な電撃!");
        super.thunderbolt(target);
    }
}

public class Charmander extends FirePokemon {
    public Charmander() {
        this(5); // デフォルトレベル5
    }
    
    public Charmander(int level) {
        super("ヒトカゲ", level, 80, 45);
    }
    
    public void charChar() {
        System.out.println("ヒトカゲ〜!");
    }
    
    @Override
    public void flamethrower(Pokemon target) {
        System.out.println("ヒトカゲの炎攻撃!");
        super.flamethrower(target);
    }
}

public class Bulbasaur extends GrassPokemon {
    public Bulbasaur() {
        this(5); // デフォルトレベル5
    }
    
    public Bulbasaur(int level) {
        super("フシギダネ", level, 90, 40);
    }
    
    public void bulbaBulba() {
        System.out.println("フシギダネ〜!");
    }
    
    @Override
    public void vineWhip(Pokemon target) {
        System.out.println("フシギダネの草攻撃!");
        super.vineWhip(target);
    }
}

6. 関連関係を表現する

ポケモンとトレーナーの関係も表現できます。

関連の読み方:

  • トレーナーは1〜6匹のポケモンを持っている
  • トレーナーは複数のモンスターボールを使用する

Pythonコード例

Python版ポケモンとトレーナーの関連クラス

from typing import List, Optional

class Trainer:
    def __init__(self, name: str):
        self._name = name
        self._pokemons: List[Pokemon] = []
        self._badges = 0
        self._pokeballs: List['PokeBall'] = []
    
    def get_name(self) -> str:
        return self._name
    
    def catch_pokemon(self, pokemon: Pokemon, pokeball: 'PokeBall') -> bool:
        if len(self._pokemons) >= 6:
            print(f"{self._name}は既に6匹のポケモンを持っています!")
            return False
        
        if pokeball.catch_pokemon(pokemon):
            self._pokemons.append(pokemon)
            print(f"{self._name}{pokemon.get_name()}を捕まえた!")
            return True
        else:
            print(f"{pokemon.get_name()}は逃げてしまった...")
            return False
    
    def send_pokemon(self, index: int = 0) -> Optional[Pokemon]:
        if 0 <= index < len(self._pokemons):
            pokemon = self._pokemons[index]
            print(f"{self._name}{pokemon.get_name()}を繰り出した!")
            return pokemon
        return None
    
    def use_pokeball(self, pokeball_type: str = "モンスターボール") -> Optional['PokeBall']:
        for ball in self._pokeballs:
            if ball.get_type() == pokeball_type:
                self._pokeballs.remove(ball)
                return ball
        return None
    
    def add_pokeball(self, pokeball: 'PokeBall') -> None:
        self._pokeballs.append(pokeball)
    
    def battle_with(self, other_trainer: 'Trainer') -> None:
        print(f"{self._name} VS {other_trainer.get_name()}のバトル開始!")
        my_pokemon = self.send_pokemon(0)
        enemy_pokemon = other_trainer.send_pokemon(0)
        
        if my_pokemon and enemy_pokemon:
            my_pokemon.attack(enemy_pokemon)
    
    def get_pokemon_count(self) -> int:
        return len(self._pokemons)
    
    def __str__(self) -> str:
        pokemon_names = [p.get_name() for p in self._pokemons]
        return f"トレーナー {self._name} (バッジ: {self._badges}, ポケモン: {pokemon_names})"


class PokeBall:
    def __init__(self, ball_type: str = "モンスターボール"):
        self._type = ball_type
        self._catch_rate = self._get_catch_rate(ball_type)
    
    def _get_catch_rate(self, ball_type: str) -> float:
        rates = {
            "モンスターボール": 0.7,
            "スーパーボール": 0.8,
            "ハイパーボール": 0.9,
            "マスターボール": 1.0
        }
        return rates.get(ball_type, 0.7)
    
    def get_type(self) -> str:
        return self._type
    
    def catch_pokemon(self, pokemon: Pokemon) -> bool:
        import random
        success = random.random() < self._catch_rate
        print(f"{self._type}を投げた!")
        return success

Javaコード例

Java版ポケモンとトレーナーの関連クラス
import java.util.*;

public class Trainer {
    private String name;
    private List<Pokemon> pokemons;
    private int badges;
    private List<PokeBall> pokeballs;
    
    public Trainer(String name) {
        this.name = name;
        this.pokemons = new ArrayList<>();
        this.badges = 0;
        this.pokeballs = new ArrayList<>();
    }
    
    public String getName() {
        return name;
    }
    
    public boolean catchPokemon(Pokemon pokemon, PokeBall pokeball) {
        if (pokemons.size() >= 6) {
            System.out.println(name + "は既に6匹のポケモンを持っています!");
            return false;
        }
        
        if (pokeball.catchPokemon(pokemon)) {
            pokemons.add(pokemon);
            System.out.println(name + "は" + pokemon.getName() + "を捕まえた!");
            return true;
        } else {
            System.out.println(pokemon.getName() + "は逃げてしまった...");
            return false;
        }
    }
    
    public Pokemon sendPokemon() {
        return sendPokemon(0);
    }
    
    public Pokemon sendPokemon(int index) {
        if (index >= 0 && index < pokemons.size()) {
            Pokemon pokemon = pokemons.get(index);
            System.out.println(name + "は" + pokemon.getName() + "を繰り出した!");
            return pokemon;
        }
        return null;
    }
    
    public PokeBall usePokeball(String ballType) {
        for (Iterator<PokeBall> it = pokeballs.iterator(); it.hasNext();) {
            PokeBall ball = it.next();
            if (ball.getType().equals(ballType)) {
                it.remove();
                return ball;
            }
        }
        return null;
    }
    
    public void addPokeball(PokeBall pokeball) {
        pokeballs.add(pokeball);
    }
    
    public void battleWith(Trainer otherTrainer) {
        System.out.println(name + " VS " + otherTrainer.getName() + "のバトル開始!");
        Pokemon myPokemon = sendPokemon(0);
        Pokemon enemyPokemon = otherTrainer.sendPokemon(0);
        
        if (myPokemon != null && enemyPokemon != null) {
            myPokemon.attack(enemyPokemon);
        }
    }
    
    public int getPokemonCount() {
        return pokemons.size();
    }
    
    public List<Pokemon> getPokemons() {
        return new ArrayList<>(pokemons); // 防御的コピー
    }
    
    @Override
    public String toString() {
        List<String> pokemonNames = new ArrayList<>();
        for (Pokemon p : pokemons) {
            pokemonNames.add(p.getName());
        }
        return "トレーナー " + name + " (バッジ: " + badges + ", ポケモン: " + pokemonNames + ")";
    }
}

public class PokeBall {
    private String type;
    private double catchRate;
    private static final Random random = new Random();
    
    public PokeBall() {
        this("モンスターボール");
    }
    
    public PokeBall(String type) {
        this.type = type;
        this.catchRate = getCatchRate(type);
    }
    
    private double getCatchRate(String ballType) {
        switch (ballType) {
            case "モンスターボール":
                return 0.7;
            case "スーパーボール":
                return 0.8;
            case "ハイパーボール":
                return 0.9;
            case "マスターボール":
                return 1.0;
            default:
                return 0.7;
        }
    }
    
    public String getType() {
        return type;
    }
    
    public boolean catchPokemon(Pokemon pokemon) {
        System.out.println(type + "を投げた!");
        boolean success = random.nextDouble() < catchRate;
        
        if (success) {
            System.out.println("やったー! " + pokemon.getName() + "を捕まえた!");
        } else {
            System.out.println("あー! " + pokemon.getName() + "は逃げてしまった...");
        }
        
        return success;
    }
}

7. 実際の設計での活用

7.1 要件からクラスを抽出する

「ポケモンバトルシステムを作る」という要件から:

  1. 名詞を探す → ポケモン、トレーナー、技、アイテム
  2. 動詞を探す → 攻撃する、回復する、捕まえる
  3. 名詞がクラス、動詞がメソッドになる

7.2 完成したクラス図例

Pythonコード例

Python版クラス例
from typing import List
from enum import Enum

class SkillType(Enum):
    ELECTRIC = "でんき"
    FIRE = "ほのお"
    GRASS = "くさ"
    NORMAL = "ノーマル"

class Skill:
    def __init__(self, name: str, power: int, skill_type: SkillType):
        self._name = name
        self._power = power
        self._type = skill_type
    
    def get_name(self) -> str:
        return self._name
    
    def get_power(self) -> int:
        return self._power
    
    def get_type(self) -> SkillType:
        return self._type
    
    def execute(self, user: Pokemon, target: Pokemon) -> None:
        damage = self._power
        print(f"{user.get_name()}{self._name}")
        print(f"{target.get_name()}{damage}のダメージ!")
        target.take_damage(damage)


class BattleSystem:
    def __init__(self):
        self._current_battle = None
    
    def start_battle(self, trainer1: Trainer, trainer2: Trainer) -> None:
        print("=" * 50)
        print(f"ポケモンバトル開始!")
        print(f"{trainer1.get_name()} VS {trainer2.get_name()}")
        print("=" * 50)
        
        pokemon1 = trainer1.send_pokemon(0)
        pokemon2 = trainer2.send_pokemon(0)
        
        if pokemon1 and pokemon2:
            self._battle_loop(pokemon1, pokemon2)
    
    def _battle_loop(self, pokemon1: Pokemon, pokemon2: Pokemon) -> None:
        turn = 1
        while pokemon1.is_alive() and pokemon2.is_alive():
            print(f"\n--- ターン {turn} ---")
            
            # ポケモン1の攻撃
            if pokemon1.is_alive():
                pokemon1.attack(pokemon2)
            
            # ポケモン2の攻撃
            if pokemon2.is_alive():
                pokemon2.attack(pokemon1)
            
            turn += 1
            
            # 10ターンで強制終了
            if turn > 10:
                print("バトルは引き分けに終わった...")
                break
        
        self.end_battle(pokemon1, pokemon2)
    
    def end_battle(self, pokemon1: Pokemon, pokemon2: Pokemon) -> None:
        print("\n" + "=" * 50)
        if pokemon1.is_alive() and not pokemon2.is_alive():
            print(f"{pokemon1.get_name()}の勝利!")
        elif pokemon2.is_alive() and not pokemon1.is_alive():
            print(f"{pokemon2.get_name()}の勝利!")
        else:
            print("引き分け!")
        print("=" * 50)


# 使用例
def main():
    # ポケモンを作成
    pikachu = Pikachu(25)
    raichu = Raichu(30)
    charmander = Charmander(5)
    
    # トレーナーを作成
    satoshi = Trainer("サトシ")
    shigeru = Trainer("シゲル")
    
    # モンスターボールを作成
    pokeball1 = PokeBall("スーパーボール")
    pokeball2 = PokeBall("ハイパーボール")
    
    # トレーナーにモンスターボールを渡す
    satoshi.add_pokeball(pokeball1)
    shigeru.add_pokeball(pokeball2)
    
    # ポケモンを捕まえる
    satoshi.catch_pokemon(pikachu, pokeball1)
    shigeru.catch_pokemon(raichu, pokeball2)
    
    # トレーナー情報を表示
    print(satoshi)
    print(shigeru)
    
    # バトルシステムでバトル開始
    battle_system = BattleSystem()
    battle_system.start_battle(satoshi, shigeru)
    
    # 技を使ってみる
    print("\n--- 特別技のデモ ---")
    pikachu.thunderbolt(charmander)
    charmander.flamethrower(pikachu)

if __name__ == "__main__":
    main()

Java版クラス例
import java.util.*;

public enum SkillType {
    ELECTRIC("でんき"),
    FIRE("ほのお"),
    GRASS("くさ"),
    NORMAL("ノーマル");
    
    private final String typeName;
    
    SkillType(String typeName) {
        this.typeName = typeName;
    }
    
    public String getTypeName() {
        return typeName;
    }
}

public class Skill {
    private String name;
    private int power;
    private SkillType type;
    
    public Skill(String name, int power, SkillType type) {
        this.name = name;
        this.power = power;
        this.type = type;
    }
    
    public String getName() {
        return name;
    }
    
    public int getPower() {
        return power;
    }
    
    public SkillType getType() {
        return type;
    }
    
    public void execute(Pokemon user, Pokemon target) {
        int damage = this.power;
        System.out.println(user.getName() + "の" + this.name + "!");
        System.out.println(target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
}

public class Pokemon {
    private String name;
    private String type;
    private int level;
    private int hp;
    private int maxHp;
    private int attackPower;
    private List<Skill> skills;
    
    public Pokemon(String name, String type, int level, int hp, int attackPower) {
        this.name = name;
        this.type = type;
        this.level = level;
        this.hp = hp;
        this.maxHp = hp;
        this.attackPower = attackPower;
        this.skills = new ArrayList<>();
    }
    
    public String getName() {
        return name;
    }
    
    public String getType() {
        return type;
    }
    
    public int getLevel() {
        return level;
    }
    
    public int getHp() {
        return hp;
    }
    
    public void attack(Pokemon target) {
        int damage = this.attackPower;
        System.out.println(this.name + "の攻撃! " + target.getName() + "に" + damage + "のダメージ!");
        target.takeDamage(damage);
    }
    
    public void takeDamage(int damage) {
        this.hp -= damage;
        if (this.hp < 0) {
            this.hp = 0;
        }
        System.out.println(this.name + "の残りHP: " + this.hp);
    }
    
    public void levelUp() {
        this.level++;
        this.hp += 10;
        this.maxHp += 10;
        this.attackPower += 5;
        System.out.println(this.name + "がレベルアップ! レベル" + this.level + "になった!");
    }
    
    public boolean isAlive() {
        return this.hp > 0;
    }
    
    public void addSkill(Skill skill) {
        if (skills.size() < 4) {
            skills.add(skill);
            System.out.println(name + "は" + skill.getName() + "を覚えた!");
        } else {
            System.out.println(name + "は既に4つの技を覚えています!");
        }
    }
    
    public void useSkill(int skillIndex, Pokemon target) {
        if (skillIndex >= 0 && skillIndex < skills.size()) {
            Skill skill = skills.get(skillIndex);
            skill.execute(this, target);
        } else {
            System.out.println("その技は覚えていません!");
        }
    }
    
    public List<Skill> getSkills() {
        return new ArrayList<>(skills);
    }
    
    @Override
    public String toString() {
        return name + "(Lv." + level + ", HP:" + hp + "/" + maxHp + ")";
    }
}

public class Trainer {
    private String name;
    private List<Pokemon> pokemons;
    private int badges;
    
    public Trainer(String name) {
        this.name = name;
        this.pokemons = new ArrayList<>();
        this.badges = 0;
    }
    
    public String getName() {
        return name;
    }
    
    public void addPokemon(Pokemon pokemon) {
        if (pokemons.size() < 6) {
            pokemons.add(pokemon);
            System.out.println(name + "は" + pokemon.getName() + "を手持ちに加えた!");
        } else {
            System.out.println(name + "は既に6匹のポケモンを持っています!");
        }
    }
    
    public Pokemon sendPokemon() {
        return sendPokemon(0);
    }
    
    public Pokemon sendPokemon(int index) {
        if (index >= 0 && index < pokemons.size()) {
            Pokemon pokemon = pokemons.get(index);
            System.out.println(name + "は" + pokemon.getName() + "を繰り出した!");
            return pokemon;
        }
        return null;
    }
    
    public void battleWith(Trainer otherTrainer) {
        System.out.println(name + " VS " + otherTrainer.getName() + "のバトル開始!");
        Pokemon myPokemon = sendPokemon(0);
        Pokemon enemyPokemon = otherTrainer.sendPokemon(0);
        
        if (myPokemon != null && enemyPokemon != null) {
            myPokemon.attack(enemyPokemon);
        }
    }
    
    public int getPokemonCount() {
        return pokemons.size();
    }
    
    public List<Pokemon> getPokemons() {
        return new ArrayList<>(pokemons);
    }
    
    @Override
    public String toString() {
        List<String> pokemonNames = new ArrayList<>();
        for (Pokemon p : pokemons) {
            pokemonNames.add(p.getName());
        }
        return "トレーナー " + name + " (バッジ: " + badges + ", ポケモン: " + pokemonNames + ")";
    }
}

public class BattleSystem {
    private boolean currentBattle;
    
    public BattleSystem() {
        this.currentBattle = false;
    }
    
    public void startBattle(Trainer trainer1, Trainer trainer2) {
        System.out.println("=".repeat(50));
        System.out.println("ポケモンバトル開始!");
        System.out.println(trainer1.getName() + " VS " + trainer2.getName());
        System.out.println("=".repeat(50));
        
        Pokemon pokemon1 = trainer1.sendPokemon(0);
        Pokemon pokemon2 = trainer2.sendPokemon(0);
        
        if (pokemon1 != null && pokemon2 != null) {
            currentBattle = true;
            battleLoop(pokemon1, pokemon2);
        }
    }
    
    private void battleLoop(Pokemon pokemon1, Pokemon pokemon2) {
        int turn = 1;
        
        while (pokemon1.isAlive() && pokemon2.isAlive() && turn <= 10) {
            System.out.println("\n--- ターン " + turn + " ---");
            
            // ポケモン1の攻撃
            if (pokemon1.isAlive()) {
                pokemon1.attack(pokemon2);
            }
            
            // ポケモン2の攻撃
            if (pokemon2.isAlive()) {
                pokemon2.attack(pokemon1);
            }
            
            turn++;
        }
        
        endBattle(pokemon1, pokemon2);
    }
    
    public void endBattle(Pokemon pokemon1, Pokemon pokemon2) {
        System.out.println("\n" + "=".repeat(50));
        if (pokemon1.isAlive() && !pokemon2.isAlive()) {
            System.out.println(pokemon1.getName() + "の勝利!");
        } else if (pokemon2.isAlive() && !pokemon1.isAlive()) {
            System.out.println(pokemon2.getName() + "の勝利!");
        } else {
            System.out.println("引き分け!");
        }
        System.out.println("=".repeat(50));
        currentBattle = false;
    }
    
    public boolean isInBattle() {
        return currentBattle;
    }
}

// 使用例とメインクラス
public class PokemonBattleSystem {
    public static void main(String[] args) {
        // ポケモンを作成
        Pokemon pikachu = new Pokemon("ピカチュウ", "でんき", 25, 100, 55);
        Pokemon charmander = new Pokemon("ヒトカゲ", "ほのお", 20, 80, 50);
        Pokemon bulbasaur = new Pokemon("フシギダネ", "くさ", 18, 90, 45);
        
        // スキルを作成
        Skill thunderbolt = new Skill("10まんボルト", 90, SkillType.ELECTRIC);
        Skill flamethrower = new Skill("かえんほうしゃ", 85, SkillType.FIRE);
        Skill vineWhip = new Skill("つるのムチ", 70, SkillType.GRASS);
        Skill tackle = new Skill("たいあたり", 40, SkillType.NORMAL);
        
        // ポケモンにスキルを覚えさせる
        pikachu.addSkill(thunderbolt);
        pikachu.addSkill(tackle);
        charmander.addSkill(flamethrower);
        charmander.addSkill(tackle);
        bulbasaur.addSkill(vineWhip);
        bulbasaur.addSkill(tackle);
        
        // トレーナーを作成
        Trainer satoshi = new Trainer("サトシ");
        Trainer shigeru = new Trainer("シゲル");
        
        // トレーナーにポケモンを渡す
        satoshi.addPokemon(pikachu);
        satoshi.addPokemon(charmander);
        shigeru.addPokemon(bulbasaur);
        
        // トレーナー情報を表示
        System.out.println(satoshi);
        System.out.println(shigeru);
        
        // バトルシステムでバトル開始
        BattleSystem battleSystem = new BattleSystem();
        battleSystem.startBattle(satoshi, shigeru);
        
        // スキル使用のデモ
        System.out.println("\n=== スキル使用デモ ===");
        pikachu.useSkill(0, charmander); // 10まんボルト
        charmander.useSkill(0, bulbasaur); // かえんほうしゃ
        bulbasaur.useSkill(0, pikachu); // つるのムチ
    }
}

まとめ

クラス図は以下の手順で作成できます:

  1. 要件を分析して、登場する「もの」(名詞)を見つける
  2. クラス名を決める
  3. 属性(そのクラスが持つデータ)を決める
  4. メソッド(そのクラスができること)を決める
  5. クラス間の関係(継承、関連)を決める
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?