2025. 10. 13. 14:47ㆍTIL
C# 콘솔 RPG 게임 개발 회고 (1주 프로젝트)
프로젝트 개요
1주일 동안 C# 콘솔 기반의 텍스트 RPG 게임을 개발했습니다. 플레이어가 던전을 탐험하고, 아이템을 구매/판매하며, 장비를 관리하는 시스템을 구현했습니다.
사용 기술 스택
- 언어: C#
- 핵심 기술: LINQ, Tuple, Dictionary, List, JSON 직렬화/역직렬화, Enum, TryParse를 활용한 입력 검증
- 디자인 패턴: 상속 구조, Static 활용
핵심 구조 설계
1. 데이터 구조
Enum을 활용한 아이템 타입 정의
// 아이템 타입을 Enum으로 관리
// 처음엔 Weapon, Potion 등으로 선언하려 했으나
// 아이템 이름을 통해 정보를 받아오는 방식으로 구현
아쉬운 점: 아이템 타입을 Weapon, Potion 같은 일반적인 형태가 아닌 아이템 이름 기반으로 구현한 부분이 개선의 여지가 있습니다.
ItemInfo 구조체
아이템의 모든 정보를 담는 구조체를 설계했습니다.
- 이름
- 타입
- 능력치 보너스
- 설명
- 가격
생성자를 통해 초기화하도록 구현했습니다.
자주 사용하거나 밸런스 조정이 필요한 값들은 상수(const)로 선언해 관리했습니다.
2. 클래스 설계
Character 클래스 (베이스 클래스)
몬스터와 플레이어가 공유하는 공통 속성을 정의했습니다.
// 공통 속성
- 이름
- 레벨
- HP
- 공격력
- 방어력
Player 클래스 (상속)
Character 클래스를 상속받아 플레이어만의 고유 속성을 추가했습니다
// 플레이어 전용 속성
- 직업
- 골드
- 스태미나
- 경험치
// 이니셜라이저를 통해 base(Character) 속성 초기화
주요 시스템 구현
1. 아이템 관리 시스템
데이터 구조
// Dictionary를 활용한 아이템 데이터 관리
Dictionary<Item, ItemInfo> itemData;
// List를 활용한 인벤토리 시스템
static List<Item> playerInventory = new List<Item>();
static List<Item> equipItem = new List<Item>();
static List<Item> shopItem = new List<Item>();
ItemInit 메서드
// 반환형: Dictionary<Item, ItemInfo>
// 역할: 게임 시작 시 모든 아이템 데이터 초기화
2. 인벤토리 & 장비 시스템
Inven 클래스
- 인벤토리 화면 표시
- 장비창으로 이동 기능
- 한글 정렬 문제 해결: Utility.PaddingKorean 메서드를 사용해 글자 수 정렬 구현
EquipManager 클래스
장비 장착/해제를 관리하는 핵심 시스템입니다.
장착 여부 체크
bool isEquip; // 장착 여부 플래그
// IsEquipIndex(i) 메서드로 체크
// 현재 장착 중인 아이템이 플레이어 인벤토리에 포함되어 있는지 확인
// true → [E] 표시
// false → - 표시
EquipToggle 메서드
- 아이템 번호 입력 시 장착/해제
- 이미 장착 중이면 → 해제
- 장착 중이 아니면 → 장착
- HP 포션은 → 사용 후 제거
- 같은 타입의 아이템 중복 방지: 기존 아이템 자동 해제 후 새 아이템 장착
3. 상점 시스템
Shop 메서드
// LINQ의 OrderBy를 활용한 가격순 정렬
shopItem.OrderBy(item => itemData[item].Price);
ShopBuy 메서드 (구매)
- 이미 구매한 아이템 체크
- 포션은 중복 구매 가능하도록 별도 처리
ShopSell 메서드 (판매)
- 플레이어 인벤토리에서 아이템 선택
- 판매 시 인벤토리와 장착 리스트에서 모두 제거
4. 탐험 & 던전 시스템
TownPatrol 메서드
// Tuple(var)을 사용한 이벤트 관리
// break를 통한 누적값 계산 처리
// → break 없이 foreach 계속 실행 시 조건에 맞는 모든 값이 중복 계산되는 문제 방지
Dungeon 메서드
던전 입장을 관리하는 핵심 메서드입니다.
기능:
- 던전 이름과 보상 초기화
- 방어력과 공격력에 따른 성공/실패 판정
- 결과 출력
CalcDamage 메서드
// 던전에서 플레이어가 받는 데미지 계산
// 매개변수: 던전 인덱스 (어떤 던전인지)
// 제시된 공식에 따라 계산
CalcReward 메서드
// 플레이어 공격력에 따른 보상 계산
// 매개변수: 던전 인덱스, 보상(골드, 경험치)
// 제시된 공식에 따라 계산
DungeonResult 메서드
던전 결과를 콘솔에 표시하는 메서드입니다.
매개변수:
- 던전 이름
- 성공 여부
- 받은 데미지
- 던전 인덱스
- 보상
처리 로직:
- 성공 시 → CalcReward 호출
- 경험치 획득 → CheckLevelUp 실행
- 성공/실패 결과 출력
5. 레벨 시스템
CheckLevelUp 메서드
플레이어의 레벨업을 담당하는 메서드입니다.
기능:
- 레벨업 시 요구 경험치 증가
- 능력치 자동 상승
- 최대 레벨 도달 시 레벨업 중지
- 다중 레벨업 지원: While문을 사용해 한 번에 2레벨 이상 오를 만큼 경험치를 획득해도 처리 가능
저장/불러오기 시스템
SaveLoad 메서드
저장 슬롯: 총 3개
기능:
- 저장 데이터 유무에 따라 다른 출력
- 기존 데이터가 있는 슬롯 선택 시 → "덮어쓰기" 또는 "불러오기" 선택
- GameManager.cs의 GameSaveManager 클래스를 static으로 선언해 GameSave, GameLoad 메서드 호출
로드 처리:
- SaveData 클래스에서 슬롯 정보 읽기
- 새로운 플레이어 객체 생성
- Start 메서드에 로드된 플레이어 객체를 매개변수로 전달
GameManager.cs
SaveData 클래스
세이브 데이터에 저장될 변수들을 선언한 클래스입니다.
생성자 2개 구현 이유:
- 빈 생성자: 역직렬화(로드)를 위해 필요
- 매개변수 생성자: 직렬화(저장)를 위해 필요
GameSaveManager 클래스
JSON 한글 저장 문제 해결
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), // 한글 포함 모든 유니코드 출력
WriteIndented = true // 줄바꿈과 들여쓰기 적용
};
// WriteIndented 옵션 비교
// false: 한 줄로 압축, 파일 크기 작음, 가독성 낮음 → 네트워크 전송/대용량 데이터
// true: 줄바꿈과 들여쓰기, 파일 크기 큼, 가독성 높음 → 디버깅/세이브 파일
GameSave 메서드
// 매개변수: 현재 플레이어 정보, 인벤토리, 장착 아이템
// 1. 새로운 SaveData 객체 생성
// 2. JsonSerializer.Serialize로 직렬화
// 3. File.WriteAllText로 파일 저장
GameLoad 메서드
// 반환형: SaveData
// 매개변수: 슬롯 번호
// 1. 파일에서 JSON 읽기
// 2. JsonSerializer.Deserialize로 역직렬화
// 3. SaveData 객체 반환
유틸리티 시스템
Util.cs (Utility 클래스)
편의 기능 메서드를 모아둔 static 클래스입니다.
주요 메서드:
- PaddingKorean: 한글 글자 수 정렬
- IntInput: TryParse를 활용한 숫자 입력 검증
- 숫자만 입력 허용
- 문자 입력 시 "숫자만 입력해주세요!" 출력
메인 진입점
Main 메서드
// 콘솔 제목 설정
// 플레이어 객체 생성
// 커서 숨기기
// Init() 호출
// Start() 호출
간결하게 두 개의 메서드만 호출하도록 설계했습니다.
Init 메서드
// 1. ItemInit 메서드로 itemData 초기화
// 2. foreach문으로 상점에 아이템 추가
Start 메서드
가장 긴 메서드입니다. 이유는 시작 화면에서 이동 가능한 뷰가 많기 때문입니다.
기능:
- 사용자 입력 받기
- 각 화면으로 이동 처리
- 문자열 입력 버그 방지 → Utility.IntInput 사용
프로젝트를 통해 학습한 기술
1. LINQ (Language Integrated Query)
- OrderBy를 활용한 데이터 정렬
2. Tuple
- 여러 값을 묶어서 반환
- 이벤트 관리에 활용
3. Dictionary & List
- Dictionary로 키-값 쌍 관리
- List로 동적 컬렉션 관리
4. JSON 직렬화/역직렬화
- 게임 데이터 저장/불러오기
- 한글 인코딩 문제 해결
5. Static 활용
- 외부 C# 파일에서 유틸리티 메서드 바로 호출
- 코드 재사용성 향상
6. Enum (열거형)
- 상수 그룹 관리
- 타입 안정성 확보
7. 상속 구조 설계
- Character 베이스 클래스
- Player 파생 클래스
- 코드 중복 최소화
8. TryParse 활용
- 안전한 자료형 변환
- 예외 처리 없이 유효성 검증
개선이 필요한 부분
- 아이템 타입 관리: Enum을 더 효과적으로 활용할 수 있었음
- 코드 모듈화: 일부 메서드가 너무 길어져 분리 필요
- 에러 처리: 예외 상황에 대한 더 견고한 처리 필요
마치며
1주일이라는 짧은 시간 동안 C#의 다양한 기능을 활용해 콘솔 RPG 게임을 완성했습니다. 특히 JSON 직렬화를 통한 저장 시스템과 LINQ를 활용한 데이터 처리, 그리고 상속 구조 설계를 실제로 구현해보면서 많은 것을 배울 수 있었습니다.
다음 프로젝트에서는 이번에 아쉬웠던 부분들을 개선하고, 더 나은 설계 패턴을 적용해보려고 합니다!
'TIL' 카테고리의 다른 글
| [2025_10_15]아이템 장착 및 포션사용 (0) | 2025.10.15 |
|---|---|
| [2025_10_14]새로운 팀원과 TextRpg팀프로젝트 시작 (0) | 2025.10.14 |
| [2025_10_02]Json-1 (0) | 2025.10.02 |
| [2025_10_01]foreach문에서의 데이터 변경 (0) | 2025.10.01 |
| [2025_09_29]클래스와 메서드 나누기 (0) | 2025.09.29 |