목차
2주차 진입, C# 종합 프로그래밍 챕터 3, 4, TextRPG 기획
챕터2 과제인 틱택토 게임 만들기를 수정하고 제출했다.
완벽하게 마음에 들진 않지만.. 일단은 완성하고 제출해야 다음 강의를 들을 수 있으므로 디테일은 포기했다.
2025.07.06 - [부트캠프/개인학습] - C# 객체 지향 프로그래밍
C# 객체 지향 프로그래밍
2025.07.01 - [부트캠프/개인학습] - C# 프로그래밍 기초 C# 프로그래밍 기초팀원들 기다리거나, 애매하게 남은 시간을 활용하기 위해 예전에 구매해놓고 완강하지 못한 강의를 동시에 진행하려고 한
j000.tistory.com
챕터3 (강의 3주차)를 듣고 Object-Oriented Programming, 구조체, 클래스와 객체, 상속과 다형성, 고급 문법 및 기능을 정리했다.
숙제도 진행하려고 했는데, 요구사항 디테일이 없어서 물어보니 일단은 공란으로 넘기고 강의 계속 들으면 된다고 하셨다...
챕터4에서는 인터페이스, 열거형, 예외 처리, 값형과 참조형, 박싱과 언박싱, 델리게이트, 람다, Func과 Action, LINQ, Nullable, StringBuilder들을 정리했다.
이 부분은 반복해서 공부한 적이 없어서 실제로 정리하고나서 AI에게 더블체크를 받는 식으로 학습했다. 모르는 부분 집요하게 물어볼 수 있다는 점이 꽤 유용하더라.
이해는 되는 데 머릿속에 들어오질 않는다. 연습하고 직접 활용하면서 익히는 수 밖에 없겠지!
C# 종합 프로그래밍 챕터2 숙제
틱택토 게임 만들기
emptyCube 갯수를 체크하여 0이 되면 비긴 처리를
//보드 상황: 유저(O)와 컴퓨터(X)가 둔 말의 위치
static string[] board = new string[9];
//좌표
static int[] coordinateX = { 0, 1, 2 }; //왼쪽부터
static int[] coordinateY = { 0, 1, 2 }; //윗쪽부터
public void Assignment2()
{
//틱택토 게임 만들기
int userInput = 0;
//보드 초기화
int printIndex = 0;
foreach (int x in coordinateX)
{
foreach (int y in coordinateY)
{
board[printIndex++] = ((x * 3) + (y + 1)).ToString();
}
}
bool isEnd = false;
bool isUsersTurn = true;
bool isPlayerWin = false;
int emptyCube = 9;
Random random = new Random();
//유저 입력 받기. 1~9 숫자 중에 점유당하지 않은 숫자만 선택 가능.
do
{
if (emptyCube == 0)
{
isEnd = true;
break;
}
PrintBoard();
if (isUsersTurn) //유저 턴
{
Console.WriteLine("상단의 보드에서 원하는 좌표를 선택해주세요.");
userInput = GetInteger();
if (IsValidCoordinate(userInput))
{
Console.WriteLine($"당신은 {userInput}을 점유했습니다.");
board[userInput - 1] = "*"; //유저가 점유함.
emptyCube--;
isUsersTurn = false;
}
else
{
Console.WriteLine($"{userInput}은 이미 점유된 좌표입니다.");
continue;
}
}
else //컴퓨터 턴
{
Console.WriteLine("컴퓨터의 차례입니다...");
bool isValid = false;
do
{
int computerInput = random.Next(1, 10);
isValid = IsValidCoordinate(computerInput);
if (isValid)
{
Console.WriteLine($"컴퓨터가 {computerInput}을 점유했습니다.");
board[computerInput - 1] = "X"; //컴퓨터가 점유함
emptyCube--;
}
} while (!isValid);
isUsersTurn = true;
}
isEnd = IsGameEnd(out isPlayerWin);
} while (!isEnd);
PrintBoard();
if (isPlayerWin)
{
Console.WriteLine("축하합니다! 승리했습니다!");
}
else if(emptyCube == 0)
{
Console.WriteLine("비겼습니다.");
}
else
{
Console.WriteLine("저런, 컴퓨터가 이겼습니다.");
}
}
static int GetInteger()
{
bool isSuccessful = false;
int integer;
do
{
string input = Console.ReadLine();
isSuccessful = int.TryParse(input, out integer);
if (!isSuccessful)
{
Console.WriteLine("숫자(정수)만 입력해주세요.");
}
} while (!isSuccessful);
return integer;
}
static void PrintBoard()
{
//출력하기 (좌표): 각 좌표별 인덱스 (x * 3) + (y + 1)
//---------------------------
//| 1, 1 | 1, 2 | 1, 3 |
//---------------------------
//| 2, 1 | 2, 2 | 2, 3 |
//---------------------------
//| 3, 1 | 3, 2 | 3, 3 |
//---------------------------
int printIndex = 0;
Console.WriteLine("\nYour tokens: *\nComputer's tokens: X");
Console.WriteLine("\n--------------------");
foreach (int x in coordinateX)
{
Console.Write(" | ");
foreach (int y in coordinateY)
{
Console.Write(board[printIndex++]);
Console.Write(" | ");
}
Console.WriteLine("\n--------------------");
}
}
static bool IsValidCoordinate(int userInput)
{
bool isValid = false;
if (userInput < 1 || userInput > 10) //범위 바깥의 좌표 선택 시
{
Console.WriteLine("1-9 범위 내의 좌표를 선택하세요.");
}
else
{
// O이거나, X이면 false
if (int.TryParse(board[userInput - 1], out int result))
{
isValid = true;
}
else
{
isValid = false;
}
}
return isValid;
}
static bool IsGameEnd(out bool isPlayerWin)
{
int[][] winConditions =
{
[0, 1, 2], // 가로
[3, 4, 5],
[6, 7, 8],
[0, 3, 6], // 세로
[1, 4, 7],
[2, 5, 8],
[0, 4, 8], // 대각선
[2, 4, 6]
};
bool isEnd = false;
string mark = "";
foreach(int[] condition in winConditions)
{
string a = board[condition[0]];
string b = board[condition[1]];
string c = board[condition[2]];
if (board[condition[0]] == board[condition[1]] && board[condition[1]] == board[condition[2]])
{
mark = board[condition[0]];
isEnd = true;
}
}
isPlayerWin = (mark == "*") ? true : false;
return isEnd;
}
FlowChart 및 다이어그램 그리기
구글링 해보고 괜찮은 Chart 그리기 웹앱을 발견했다.
Mermaid Chart
A smarter way of creating diagrams.
www.mermaidchart.com
텍스트로 작성하면 자동으로 다이어그램을 생성해준다.
마우스 쓰는 걸 극도로 싫어하는 나에게 정말 딱 맞는 방법인 것 같아서 바로 채택했다.
2주차 TextRPG 필수 기능에 필요한 요소들만 일단 만들어보려고 한다.
도전 기능 구현까지 포함해서 시작하고는 싶은데, 그러면 나중에 도전 기능 구현 시작할 때 정~말 뿌듯하고 스무스하게 진행될거 같긴 한데, 그 전에 시작 부분을 코딩 시작하면 압도당할 것 같음...
+던전 기능과 저장 기능을 제외하고 다시 작성함.
Flow Chart
flowchart LR
GameStart["GameStart"] -- 1입력 --> Status["Status"]
Status -- 0입력 --> GameStart
GameStart -- 2입력 --> Inventory["Inventory"]
Inventory -- 1입력 --> Equipment["Equipment"]
Equipment -- ItemId 입력 --> isEquippedCheck{Is Equipped?}
isEquippedCheck --Yes--> Unequip["Unequip(ItemId)"] --> Equipment
isEquippedCheck --No--> Equip["Equip(ItemId)"] -->Equipment
Inventory -- 0입력 --> GameStart
GameStart -- 3입력 --> Store["Store"]
Store -- 1입력 --> Purchase["Purchase"]
Purchase -- ItemId 입력 --> isOwnedCheck{Is Owned?}
isOwnedCheck --Yes--> UnableToPurchase --> Purchase
isOwnedCheck --No--> PurchaseItem["Purchase(ItemId)"] -->Purchase
Purchase -- 0입력 --> Store
Store -- 0입력 --> GameStart
%% %%여기부터는 도전구현
%% isEquippedCheck --Yes--> Unequip["Unequip(Slot, ItemId)"] --> Equip["Equip(Slot, ItemId)"]--> Equipment
%% Store -- 2입력 --> Sell["Sell"]
%% Sell -- ItemId 입력 --> SellItem["SellItem(ItemId)"] --> Sell
%% GameStart -- 4입력 --> Dungeon["Dungeon"]
%% Dungeon --1입력--> isEasyCleared{"이지: 방어력 < 권장 방어력(5)"}
%% isEasyCleared --"40%"--> Failed["보상X 체력 50%감소"]
%% isEasyCleared --"60%"--> Cleared["클리어 보상 수령, 체력 감소"]
%% Dungeon --2입력--> isNormalCleared{"노멀: 방어력 < 권장 방어력(11)"}
%% isNormalCleared --"40%"--> Failed["보상X 체력 50%감소"]
%% isNormalCleared --"60%"--> Cleared["클리어 보상 수령, 체력 감소"]
%% Dungeon --3입력--> isHardCleared{"하드: 방어력 < 권장 방어력(17)"}
%% isHardCleared --"40%"--> Failed["보상X 체력 50%감소"]
%% isHardCleared --"60%"--> Cleared["클리어 보상 수령, 체력 감소"]
%% Failed -->Dungeon
%% Cleared -->Dungeon
%% Dungeon -- 0입력 --> GameStart
%% GameStart -- 5입력 --> Rest["Rest"]
%% Rest -- 1입력 --> TakeRest["TakeRest()"]
%% Rest -- 0입력 --> GameStart


Class Diagram
classDiagram
class Player {
-int id
-int level
-string name
-string job
-int attack
-int defence
-int health
-int gold
-List~Item~ inventory
%%----도전 기능
%% -Dictionaly~ItemSlot, Item~ equipment
%% -exp : 던전 횟수 카운트
%% +void TakeRest()
%% +void EnterDungeon(Dungeon dungeon)
+void DisplayPlayerStatus()
+void DisplayInventory()
+void PurchaseItem(Item item)
%%실제 아이템 획득 및 골드 소모
%%----도전 기능
%% +void TakeRest()
%% +void SellItem(Item item) 상점은 조건 체크 X 하고 무조건 매입
%% +void LevelUp()
}
class Store{
-List~Item~ itemsForSale
+void DisplayItems()
+bool SellToPlayer(Player player, Item item)
%%구매 가능 여부 체크(이미 소지중? 골드 충분?)
%%----도전 기능
}
class Item{
-int id
-bool IsEquipped
-string name
-int price
-string description
-Dictionary~Ability, int~
%% -ItemSlot slot
+void ToString()
+void Equip()
+void Unequip()
}
%% 도전기능
%% class Dungeon {
%% -int id
%% -string name
%% -int requiredAttack
%% -int requiredDefence
%% -int rewardGold
%% -int rewardExp
%% +bool TryEnter(Player player)
%% +void Rewarded(Player player)
%% }
class Ability {
<<enumeration>>
Attack
Defence
Health
}
class ItemSlot {
<<enumeration>>
Head
Top
Bottom
Shoes
}
Player "1" --> "*" Item : inventory
Item "*" --> "*" Ability : abilities
Store "1" --> "*" Item : itemsForSale


ERD
ERD는... 고민이 필요하다.
Player_Item 테이블을 따로 빼서 player_id와 item_id를 동시에 수집하는, 플레이어들이 소유한 아이템들의 정보를 관리하는 테이블을 따로 빼고 싶다... 그치만 당장은 필요하지 않으니 일단 고!
(왜 플레이어들이냐고? 나의 원대한 계획이 있다... 흐흐 로그인 화면을 넣어서 캐릭터를 바꿔가며 플레이 할 수 있는 추가 도전 기능을 구현할 수 있다면 하고 싶어서...)
erDiagram
PLAYER {
int player_id PK
int level
string name
string job
int attack
int defence
int health
int gold
}
ITEM {
int item_id PK
string name
string description
int price
bool is_equipped
}
ITEM_ABILITY {
int item_ability_id PK
int item_id FK
enum ability_type
%% enum 형태로 관리 (Attack, Defence, Health)
int value
}
%%던전은 도전기능
DUNGEON {
int dungeon_id PK
string dungeon_name
int required_attack
int required_defence
int reward_gold
}
PLAYER ||--o{ ITEM : owns
ITEM ||--o{ ITEM_ABILITY : has


ToString() Placeholder
//.ToString("D2"): 2자리로 표현. 빈자리는 0으로 표기
Console.WriteLine($"Lv. {player.Level.ToString("D2")}"); //01
//.ToString("N2"): 소숫점 2자리 표현.
Console.WriteLine($"Lv. {10.ToString("N2")}"); //0.00
가장 자주 쓸법한 포맷.
TryParse 조건 검사
TryParse가 실패하면 && 뒤는 평가하지 않기 때문에, 정수 반환이 성공한 경우에만 범위 검사가 수행된다.
isSuccessful = int.TryParse(input, out integer) && (integer >= min && integer < max);
느낀점
2-3주차를 위한 팀 배치를 다시 받았다. 나쁘지 않은 느낌~!
다이어그램들을 텍스트로 그릴 수 있는 기능 너무 좋다. 비록 작성할때마다 딜레이가 너무 크지만ㅜ
AI한테 내가 리스트를 만들어주고 mermaid 언어로 바꿔달라고 하고 그걸 복붙하는 방법이 제일 편한 것 같다.
문법이 어려운건 아닌데 딜레이가 진짜 심각하다.
타이핑 할때마다 생성을 확인하고, 자꾸 오류났다면서 AI 부르라고 하니깐.. (Update()에 이런거 체크하면 안되는 이유 납득 완)
내일 학습 할 것은 무엇인지
본격적으로 TextRPG를 시작할 생각이다!
다만 알고리즘 강의(5주차 aka 챕터5)도 남아있으니 중간에 기분 전환용으로 들으면 좋을 듯!
'부트캠프 > 본캠프' 카테고리의 다른 글
| [내일배움캠프_2025JUL09] 알고리즘, TextRPG SceneManager 구현 (0) | 2025.07.09 |
|---|---|
| [내일배움캠프_2025JUL08] 알고리즘, TextRPG 구현 (0) | 2025.07.08 |
| [내일배움캠프_2025JUL06] C# 종합 프로그래밍 챕터 2 (0) | 2025.07.06 |
| [내일배움캠프_2025JUL05] C# 종합 프로그래밍 - 챕터1 (0) | 2025.07.05 |
| [내일배움캠프_2025JUL04] 팀 프로젝트 발표 및 TIL 특강 (0) | 2025.07.04 |