과제1의 확장입니다. 플레이어에게 4개의 스킬이 있고, 각각의 스킬명이 존재합니다. 초기값은 다음과 같습니다. 변수를 쓰셔도, 배열을 쓰셔도 상관 없습니다

콘솔을 킨 첫 화면에서 일단 모든 스킬과 턴을 보여줍니다.
그 아래에 유저에게 선택권을 줍니다.
- 턴을 넘길지,
- 스킬을 사용할 지 두 선택지를 줍니다.

- 스킬을 선택하였다면, 어느 스킬을 사용할 지 입력받고 만약 그 스킬의 쿨타임이 0이면 다시 쿨타임 초기 숫자로 원복(Q는 5, W는3, E는 10, R은 7) 쿨타임이 돌아오지 않은 것을 선택 시, 쿨타임이 돌아오지 않았다는 메시지 출력
- 턴 넘김을 사용 시, 모든 스킬 쿨타임 1 감소. 만약 쿨타임 0이고 스킬을 사용하지 않는다면 0으로 유지. 만약 쿨타임이 0이라면 0을 출력하는 것이 아닌, “스킬준비완료” 를 출력합니다
- 원하는 대로 커스터마이징 해도 괜찮습니다
아래는 예시입니다. 형태가 똑같을 필요는 없습니다. 더 이쁘게 만드셔도 됩니다

숫자 0을 입력받을때까지 이를 무한으로 반복합니다

+ 위 내용에서 마음껏 커스텀 해봐도 좋다고 한다.
이번에는 작성 매뉴얼처럼 따를 수 있었던 스텝 별 정리가 없다.
그러므로 직접 한 단계씩 구성해보면서 코드를 만들어 나가자.
우선 스킬키와 쿨타임을 배열로 정의하자.
딕셔너리를 통해 짝짓는 편이 더 편리할 거 같은 기분이 들지만 배열 심화 과제이니 배열을 활용해보자
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 스킬 키 및 쿨타임 정의
char[] skillKeys = new char[4] { 'Q', 'W', 'E', 'R' };
int[] skillCoolTimes = new int[4] { 5, 3, 10, 7 };
int[] skillInitialCoolTimes = new int[4] { 5, 3, 10, 7 };
}
}
}
다음은 예시처럼 콘솔을 출력할 건데 콘솔 출력하는 부분은 따로 함수로 분리해서 만들어볼 예정이다.
그 이유는, 스킬 쿨타임이 갱신 될 때마다 콘솔이 아래로 계속 출력되면 보기 불편하기 때문이다.
그리고 스킬 사용 후, 사용할 스킬을 또 물어보는 것도 조금 불편하다.
처음부터 Q W E R 을 입력하면 스킬 사용, 1을 누르면 턴 스킵, 0을 입력하면 종료하도록 구성해보도록 하자.
일단 콘솔 갱신 함수다
// 콘솔 갱신 함수
static void PrintConsole(char[] skillKeys, int[] skillCoolTimes, string comment = "")
{
Console.Clear();
Console.WriteLine("사용 가능한 스킬은 다음과 같습니다");
Console.WriteLine("---------------------------------------");
for (int i = 0; i < skillKeys.Length; i++)
{
Console.WriteLine(skillCoolTimes[i] > 0
? $"{skillKeys[i]} 스킬 : {skillCoolTimes[i]}"
: $"{skillKeys[i]} 스킬 : 스킬준비완료");
}
Console.WriteLine("---------------------------------------");
Console.WriteLine("액션을 선택해주세요");
Console.WriteLine("---------------------------------------");
Console.WriteLine("1. 턴 넘김");
Console.WriteLine("Q, W, E, R 스킬 사용");
Console.WriteLine("0. 종료");
Console.WriteLine("---------------------------------------");
}
첫 라인의 클리어를 통해 콘솔 갱신 함수가 불릴 때마다 싹 지우고 출력해서
같은 자리에서 특정 텍스트만 바뀐 것처럼 표현할 거다.
이제 입력을 받는 루프를 while문을 통해 만들어보자.
덤으로 이번에는 Console.ReadLine이 아닌 Console.ReadKey라는 걸 사용할 거다.
엔터를 누르지 않아도 특정 키를 입력하면 작동하게 해서 더욱 게임 같아 보이게 하기 위함이다.
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 스킬 키 및 쿨타임 정의
char[] skillKeys = new char[4] { 'Q', 'W', 'E', 'R' };
int[] skillCoolTimes = new int[4] { 5, 3, 10, 7 };
int[] skillInitialCoolTimes = new int[4] { 5, 3, 10, 7 };
PrintConsole(skillKeys, skillCoolTimes);
// 턴 무한 반복
while (true)
{
char inputChar = Console.ReadKey(true).KeyChar;
// 0 입력시 종료, 1 입력시 턴 스킵
if (inputChar == '0') break;
if (inputChar == '1')
{
// 턴 스킵 로직
PrintConsole(skillKeys, skillCoolTimes, "턴을 넘겼다.");
continue;
}
// 입력받은 문자 대문자로 변환 후 인덱스 추출, 인덱스에 해당하는 스킬 사용
char key = char.ToUpper(inputChar);
int idx = Array.IndexOf(skillKeys, key);
if (idx >= 0 && idx <= 3)
{
// 스킬 사용 로직
}
}
}
// 콘솔 갱신 함수
static void PrintConsole(char[] skillKeys, int[] skillCoolTimes, string comment = "")
{
Console.Clear();
Console.WriteLine("사용 가능한 스킬은 다음과 같습니다");
Console.WriteLine("---------------------------------------");
for (int i = 0; i < skillKeys.Length; i++)
{
Console.WriteLine(skillCoolTimes[i] > 0
? $"{skillKeys[i]} 스킬 : {skillCoolTimes[i]}"
: $"{skillKeys[i]} 스킬 : 스킬준비완료");
}
Console.WriteLine("---------------------------------------");
Console.WriteLine("액션을 선택해주세요");
Console.WriteLine("---------------------------------------");
Console.WriteLine("1. 턴 넘김");
Console.WriteLine("Q, W, E, R 스킬 사용");
Console.WriteLine("0. 종료");
Console.WriteLine("---------------------------------------");
Console.WriteLine(comment);
}
}
}
키보드 입력이 이상하게 소, 대문자가 구분되어서 Upper를 통해서 소문자던 대문자던 같은 알파벳으로 처리했다.
또한 Array.IndexOf를 통해 입력한 키가 배열에서 몇번째 인덱스를 갖고있는지를 추출해냈다.
이것으로 스킬 사용 함수를 굳이 Q W E R 에 대해 일일이 조건문을 만들 필요 없이 간편하게 처리해볼 거다.
턴 스킵과 스킬 사용 함수를 한 번에 만들어 보도록 하자.
// 턴 스킵 함수
static void SkipTurn(int[] skillCoolTimes)
{
for (int i = 0; i < skillCoolTimes.Length; i++)
{
// 쿨타임이 0보다 큰 스킬만 쿨타임 1 감소
if (skillCoolTimes[i] > 0) skillCoolTimes[i]--;
}
}
// 스킬 사용 함수
static void UseSkill(char[] skillKeys, int idx, int[] skillCoolTimes, int[] skillInitialCoolTimes)
{
// 쿨타임 0이면 스킬 사용
if (skillCoolTimes[idx] == 0)
{
// 턴 진행 (쿨타임 감소)
SkipTurn(skillCoolTimes);
// 사용한 스킬은 쿨타임 초기값으로 지정
skillCoolTimes[idx] = skillInitialCoolTimes[idx];
PrintConsole(skillKeys, skillCoolTimes, $"{skillKeys[idx]}스킬을 사용했다!");
}
else
{
PrintConsole(skillKeys, skillCoolTimes, "쿨타임이 돌아오지 않았습니다.");
}
}
턴 스킵 함수는 스킬 쿨타임을 파라미터로 받아, for문을 통해 쿨타임이 0보다 크면 1씩 감소하게 했다.
스킬 사용 함수는 쿨타임이 0인 경우 스킬을 사용할 수 있고, 없으면 쿨타임이 돌아오지 않았다고 텍스트를 출력시킬 거다.
스킬 사용시 SkipTurn 함수를 호출해 전체 쿨타임을 진행시킨 뒤, 사용한 스킬은 쿨타임을 처음에 정의해둔 SkillInitialCollTimes 배열을 통해 초기화해주었다.
이제 이 코드를 전부 합치면
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 스킬 키 및 쿨타임 정의
char[] skillKeys = new char[4] { 'Q', 'W', 'E', 'R' };
int[] skillCoolTimes = new int[4] { 5, 3, 10, 7 };
int[] skillInitialCoolTimes = new int[4] { 5, 3, 10, 7 };
PrintConsole(skillKeys, skillCoolTimes);
// 턴 무한 반복
while (true)
{
char inputChar = Console.ReadKey(true).KeyChar;
// 0 입력시 종료, 1 입력시 턴 스킵
if (inputChar == '0') break;
if (inputChar == '1')
{
SkipTurn(skillCoolTimes);
PrintConsole(skillKeys, skillCoolTimes, "턴을 넘겼다.");
continue;
}
// 입력받은 문자 대문자로 변환 후 인덱스 추출, 인덱스에 해당하는 스킬 사용
char key = char.ToUpper(inputChar);
int idx = Array.IndexOf(skillKeys, key);
if (idx >= 0 && idx <= 3)
{
UseSkill(skillKeys, idx, skillCoolTimes, skillInitialCoolTimes);
}
}
}
// 턴 스킵 함수
static void SkipTurn(int[] skillCoolTimes)
{
for (int i = 0; i < skillCoolTimes.Length; i++)
{
// 쿨타임이 0보다 큰 스킬만 쿨타임 1 감소
if (skillCoolTimes[i] > 0) skillCoolTimes[i]--;
}
}
// 스킬 사용 함수
static void UseSkill(char[] skillKeys, int idx, int[] skillCoolTimes, int[] skillInitialCoolTimes)
{
// 쿨타임 0이면 스킬 사용
if (skillCoolTimes[idx] == 0)
{
// 턴 진행 (쿨타임 감소)
SkipTurn(skillCoolTimes);
// 사용한 스킬은 쿨타임 초기값으로 지정
skillCoolTimes[idx] = skillInitialCoolTimes[idx];
PrintConsole(skillKeys, skillCoolTimes, $"{skillKeys[idx]}스킬을 사용했다!");
}
else
{
PrintConsole(skillKeys, skillCoolTimes, "쿨타임이 돌아오지 않았습니다.");
}
}
// 콘솔 갱신 함수
static void PrintConsole(char[] skillKeys, int[] skillCoolTimes, string comment = "")
{
Console.Clear();
Console.WriteLine("사용 가능한 스킬은 다음과 같습니다");
Console.WriteLine("---------------------------------------");
for (int i = 0; i < skillKeys.Length; i++)
{
Console.WriteLine(skillCoolTimes[i] > 0
? $"{skillKeys[i]} 스킬 : {skillCoolTimes[i]}"
: $"{skillKeys[i]} 스킬 : 스킬준비완료");
}
Console.WriteLine("---------------------------------------");
Console.WriteLine("액션을 선택해주세요");
Console.WriteLine("---------------------------------------");
Console.WriteLine("1. 턴 넘김");
Console.WriteLine("Q, W, E, R 스킬 사용");
Console.WriteLine("0. 종료");
Console.WriteLine("---------------------------------------");
Console.WriteLine(comment);
}
}
}
짜잔
완성이다
잘 돌아가나 확인해보자

1을 입력하면 SkipTurn만 발동하여 전체 쿨타임이 줄어들 것이다.
과연?

굿
이제 스킬을 사용해보자
스킬 쿨타임이 가장 적게 남은 W를 사용해보자.

아직 쿨타임이 돌지 않아서 쿨타임이 돌아오지 않았다는 메세지가 출력된다.
이제 턴을 2번 넘겨서 W 스킬의 쿨타임을 0으로 만들어 보자

W 스킬 스킬 준비 완료
이제 W를 사용하면?

전체 쿨타임이 1 줄어들면서 W 스킬은 초기 쿨타임 값인 3으로 갱신된다.
다른 스킬들도 잘 작동하는 걸 확인했다.
별거 아닌 시스템을 구현했는데 왠지 RPG나 액션 게임을 만들 수 있을 것만 같은 기분이 들지만
일단 0을 눌러 종료하고 글을 마무리하자.
함수 심화 문제들도 남았다 갈 길이 멀다.
푸는 것보다 포스팅하는 시간이 더 오래 걸리는 거 같은 건 기분 탓일까..?

'C#' 카테고리의 다른 글
| C# - Main (0) | 2025.09.11 |
|---|---|
| C# - 함수 심화 문제 3종 (0) | 2025.09.11 |
| C# - 배열 심화 문제 - 인벤토리 크기 지정하기 (0) | 2025.09.11 |
| C# - 배열 심화 문제 - 2차원 배열 swap (0) | 2025.09.11 |
| C# - 함수 (Function) (0) | 2025.09.10 |