스타크래프트의 테란 유닛, 건물, 테크트리 및 자원 채취 시스템을 객체지향적으로 모델링할 수 있습니다. 이를 통해 각 유닛과 건물, 테크트리가 클래스와 상속, 메서드로 구현되고 상호작용하는 방식으로 구현할 수 있습니다. 예시로 주요 개념들을 설명하겠습니다.

1. 기본적인 객체 설계

(1) 유닛(Unit) 클래스

모든 유닛은 기본적으로 공통된 속성과 메서드를 갖는 Unit 클래스를 상속받습니다. 이 클래스는 모든 유닛이 가져야 할 기본적인 상태(체력, 공격력, 이동 속도)와 행동(이동, 공격)을 포함합니다.

class Unit {
protected:
    int health;
    int attackPower;
    float movementSpeed;

public:
    Unit(int h, int a, float m) : health(h), attackPower(a), movementSpeed(m) {}

    virtual void move(int x, int y) {
        std::cout << "Unit moves to (" << x << ", " << y << ")\n";
    }

    virtual void attack(Unit& target) {
        target.takeDamage(attackPower);
        std::cout << "Unit attacks for " << attackPower << " damage!\n";
    }

    void takeDamage(int damage) {
        health -= damage;
        if (health <= 0) {
            std::cout << "Unit destroyed\n";
        }
    }

    virtual ~Unit() {}
};

(2) 테란 유닛 클래스(Terran Units)

테란 유닛은 Unit 클래스를 상속받아 구체적인 속성 및 행동을 정의합니다. 예를 들어, 테란의 MarineSiegeTank는 각각 고유의 특수 능력을 가지고 있으며, 이를 specialAbility() 메서드로 구현할 수 있습니다.

class Marine : public Unit {
public:
    Marine() : Unit(40, 6, 1.875f) {} // 체력 40, 공격력 6, 이동속도 1.875

    void specialAbility() {
        std::cout << "Marine uses Stim Pack!\n";
    }
};

class SiegeTank : public Unit {
private:
    bool isSieged;

public:
    SiegeTank() : Unit(150, 30, 1.5f), isSieged(false) {}

    void specialAbility() {
        if (isSieged) {
            std::cout << "Siege Tank leaves siege mode!\n";
            isSieged = false;
        } else {
            std::cout << "Siege Tank enters siege mode!\n";
            isSieged = true;
        }
    }

    void attack(Unit& target) override {
        if (isSieged) {
            target.takeDamage(70); // 시즈 모드일 때는 더 강한 공격
            std::cout << "Siege Tank attacks in siege mode for 70 damage!\n";
        } else {
            Unit::attack(target); // 기본 모드의 공격
        }
    }
};

2. 건물(Building) 클래스

테란의 건물들도 객체로 표현되며, 각 건물은 건설 시간을 포함한 고유한 속성과 행동을 가집니다.

class Building {
protected:
    int buildTime;
    bool isOperational;

public:
    Building(int time) : buildTime(time), isOperational(false) {}

    void construct() {
        std::cout << "Building under construction...\n";
        // 일정 시간이 지나면 완성
        isOperational = true;
    }

    virtual void produceUnit() = 0; // 유닛을 생산하는 메서드 (추상화)

    virtual ~Building() {}
};

(1) 테란 건물(Terran Buildings)

건물들은 Building 클래스를 상속받아 구체적인 기능을 구현합니다. 예를 들어 BarracksMarine을 생산할 수 있고, FactorySiegeTank를 생산할 수 있습니다.

class Barracks : public Building {
public:
    Barracks() : Building(60) {} // 건설 시간 60초

    void produceUnit() override {
        std::cout << "Barracks produces a Marine!\n";
        Marine* newMarine = new Marine();
        // 유닛 생산 후 관리 로직
    }
};

class Factory : public Building {
public:
    Factory() : Building(100) {} // 건설 시간 100초

    void produceUnit() override {
        std::cout << "Factory produces a Siege Tank!\n";
        SiegeTank* newTank = new SiegeTank();
        // 유닛 생산 후 관리 로직
    }
};

3. 테크트리(Tech Tree)

테크트리는 유닛과 건물의 연구 및 발전 경로를 정의하는 시스템입니다. 이를 통해 특정 건물을 먼저 건설해야 다음 단계의 유닛을 생산할 수 있습니다.

class TechTree {
private:
    bool hasBarracks;
    bool hasFactory;
    bool hasArmory;

public:
    TechTree() : hasBarracks(false), hasFactory(false), hasArmory(false) {}

    void unlockBarracks() {
        hasBarracks = true;
        std::cout << "Barracks unlocked!\n";
    }

    void unlockFactory() {
        if (hasBarracks) {
            hasFactory = true;
            std::cout << "Factory unlocked!\n";
        } else {
            std::cout << "You need Barracks to unlock Factory!\n";
        }
    }

    void unlockArmory() {
        if (hasFactory) {
            hasArmory = true;
            std::cout << "Armory unlocked!\n";
        } else {
            std::cout << "You need Factory to unlock Armory!\n";
        }
    }

    bool canProduceTank() const {
        return hasFactory;
    }
};

4. 자원 채취(Resource Harvesting)

테란의 자원 채취 시스템은 미네랄과 가스를 수집하여 유닛 및 건물 생산에 사용됩니다. 이를 자원 관리 시스템으로 객체화할 수 있습니다.

class Resource {
private:
    int minerals;
    int gas;

public:
    Resource() : minerals(0), gas(0) {}

    void gatherMinerals(int amount) {
        minerals += amount;
        std::cout << "Gathered " << amount << " minerals. Total: " << minerals << "\n";
    }

    void gatherGas(int amount) {
        gas += amount;
        std::cout << "Gathered " << amount << " gas. Total: " << gas << "\n";
    }

    bool spendResources(int mineralCost, int gasCost) {
        if (minerals >= mineralCost && gas >= gasCost) {
            minerals -= mineralCost;
            gas -= gasCost;
            std::cout << "Spent " << mineralCost << " minerals and " << gasCost << " gas.\n";
            return true;
        } else {
            std::cout << "Not enough resources!\n";
            return false;
        }
    }

    int getMinerals() const {
        return minerals;
    }

    int getGas() const {
        return gas;
    }
};

5. 예시: 테크트리와 자원 사용 예제

유닛 생산 및 테크트리 적용의 실제 게임 흐름을 객체지향적으로 설명하면 다음과 같습니다.

int main() {
    Resource resources;
    TechTree techTree;

    // 미네랄과 가스 채취
    resources.gatherMinerals(500);
    resources.gatherGas(100);

    // Barracks 건설 및 유닛 생산
    techTree.unlockBarracks();
    if (resources.spendResources(150, 0)) {
        Barracks* barracks = new Barracks();
        barracks->construct();
        barracks->produceUnit(); // Marine 생산
    }

    // Factory 건설 및 유닛 생산
    techTree.unlockFactory();
    if (resources.spendResources(200, 100) && techTree.canProduceTank()) {
        Factory* factory = new Factory();
        factory->construct();
        factory->produceUnit(); // Siege Tank 생산
    }

    return 0;
}

결론

이 객체지향 모델에서는 유닛건물이 각각 클래스로 정의되고, 상속다형성을 통해 서로 다른 행동을 가집니다. 테크트리는 연구 및 건물의 순서를 관리하며, 자원 관리 시스템을 통해 유닛과 건물 생산에 필요한 자원을 조절할 수 있습니다. 이러한 구조는 유지 보수가 용이하고 확장성이 뛰어나, 다양한 게임 요소를 추가하거나 수정할 때 유리한 설계를 제공합니다.

+ Recent posts