학습일지/C와 C++

C++ 첫 번째 협업 체험 팀 프로젝트

Tsukino Ren 2026. 3. 26. 17:50

팀 프로젝트 콘솔RPG

이번 과제에서는 팀 프로젝트로 배정받은 파트를 구현하여 각자 협업하는 법을 배우며 프로젝트 완성하고 발표하기!

 

담당 파트

Monster Class

구현 내용

  • 몬스터는 이름, 체력, 공격력, 방어력을 가진다.
  • 스탯은 플레이어 레벨에 비례하여 랜덤 하게 생성되도록 한다.

스탯 생성 공식

  • 몬스터도 이름, 체력, 공격력을 가집니다.
  • 몬스터의 스탯은 캐릭터 레벨에 비례해서 랜덤 하게 설정합니다.
    • 체력: (레벨 × 20) ~ (레벨 × 30)
    • 공격력: (레벨 × 5) ~ (레벨 × 10)
 int minHp = playerLevel * 20;
 int maxHp = playerLevel * 30;
 hp_ = rand() % (maxHp - minHp + 1) + minHp;

 int minAtk = playerLevel * 5;
 int maxAtk = playerLevel * 10;
 attack_ = rand() % (maxAtk - minAtk + 1) + minAtk;

 defense_ = playerLevel * 3;

대미지 처리 구조

void Monster::TakeDamage(int takeDamage)
{
    if (takeDamage <= 0)
    {
        takeDamage = 1;
    }

    hp_ -= takeDamage;

    if (hp_ < 0)
    {
        hp_ = 0;
    }
}

설계 이유

  • 최소 대미지를 1로 보장하여 전투가 멈추지 않도록 설계함
  • HP가 음수가 되지 않도록 보정함
  • 대미지 계산과 적용을 분리함

사망 판정

bool Monster::IsDead() const
{
    return hp_ == 0;
}

설계 이유

  • 객체 내부 상태를 기반으로 사망 여부 판단하기 위함
  • 외부 시스템(BattleSystem)에서 쉽게 활용할 수 있게 구현함

※ 핵심 설계 포인트

  • 역할 분리

초기에는 이와 같은 구조를 사용했었다.

void TakeDamage(Player& player);​

 

이 구조의 문제점은 몬스터가 플레이어의 정보를 직접 참조해서 사용하다 보니 객체 간 의존성이 높아지는 문제가 생긴다.

 

문제를 방지하고자 최종적으로 아래와 같이 변경했다

Void TakeDamage(int takeDamage);

이를 통해 객체 간 의존성을 낮추고 확장성을 확보했다.


  • 레벨 기반 난이도 스케일링

플레이어 레벨을 기준으로 몬스터 스탯을 자동 생성하게 구현했다.

별도의 시스템 추가 없이 난이도 조절이 가능하게 했다.


트러블슈팅 (Git)

작업 중 Git에서 Clean 기능을 사용하여 커밋되지 않은 변경 사항이 사라지는 문제가 발생했었다.

 

◎ 해결 방법

  • Stash를 기능을 활용하여 작업 내용을 임시 저장
  • Apply Stash를 통해 복구

◎ 배운 점

  • 브랜치 이동 전에는 반드시 commit 또는 stash 필수
  • Clean은 작업 내용을 삭제하므로 진짜 신중하게 사용하기

개선점

  • rand()에서 <random> 기반으로 넘어가기!
  • Git 사용함에 있어 언제나 신중하게 하기!
  • 다른 파트와 통합 테스트 진행

마무리

이제는 기능을 단순히 구현하기보다 구조를 어떻게 설계해야겠다는 게 훨씬 중요함을 느꼈다.

 

특히 대미지 계산과 적용을 분리하여 객체 간 의존성을 줄이고 전투 시스템에서 확장하여 사용 가능하게 하였다

 

Git을 단순한 백업 도구나 공유 도구로 써가 아닌 작업 흐름을 관리하는 도구로 사용해야 함을 깨달았다.