게임의 요소 등을 숫자로 생각하고, 이 숫자에 별명을 붙여 알아보기 쉽게 만들어 주는 기능이다.
예를 들어 가위바위보 게임을 만들었을 때, 가위, 바위, 보 라는 각각의 변수를 지정할 것이다.
static void Main(string[] args)
{
// 가위 바위 보 게임
string command = "가위"
switch (command)
{
case "가위":
Console.WriteLine("가위를 냅니다.");
break;
case "바위":
Console.WriteLine("바위를 냅니다.");
break;
case "보":
Console.WriteLine("보를 냅니다.");
break;
default:
Console.WriteLine("잘못 냈습니다.");
break;
}
}
가위바위보 게임은 정상적으로 구동할 테지만, 이러한 방식으로 만들었을 때의 문제점이 있다
- 코드작성자의 실수로 command나 case에서 오타가 발생할 경우?
- 다른 사람의 해당 코드를 잘못 해석하여 변수를 임의로 변경할 경우?
이런 부분을 방지하기 위해 열거형이란 것에 대해 알아보고자 한다.
열거형을 만들기 위해선 우선 enum을 선언해야 한다.
위의 가위바위보를 열거형으로 다시 표현하기 위해 enum을 선언해 보자.
enum RockPaperScissor
{
Rock,
Paper,
Scissor
}
이와 같이 작성하고 메인에서 가위바위보 게임을 다시 만들어보자.
static void Main(string[] args)
{
// 가위 바위 보 게임
RockPaperScissor command = RockPaperScissor.Rock;
switch (command)
{
case RockPaperScissor.Scissor:
Console.WriteLine("가위를 냅니다.");
break;
case RockPaperScissor.Rock:
Console.WriteLine("바위를 냅니다.");
break;
case RockPaperScissor.Paper:
Console.WriteLine("보를 냅니다.");
break;
default:
Console.WriteLine("잘못 냈습니다.");
break;
}
}
전체적인 코드로만 볼 때에는 별 차이가 없어 보이지만, 실제로 코드를 작성할 때에 그 특징을 알 수 있다.
이와 같이 RockPaperScissor을 사용할 때마다 자동완성이 되며, 오타가 문법오류로 표시된다.
이를 활용하면 함부로 변수를 오인해서 잘못 사용하거나, 오탈자를 방지할 수 있다.
열거형에는 한 가지 특징이 있는데, 위에서 사용한 가위바위보 열거형을 예시로 보자.
enum으로 선언된 가위바위보 변수 중, Rock = 0이라고 표시되어 있다.
다른 변수 선언을 하지 않았다면 Scissor는 1, Paper는 2로 되어 있다.
이는 열거형 자체가 컴퓨터가 판단하기로는 숫자로 판단하고, 인간이 식별 가능한 별명으로 표기한 것이기 때문이다.
이러한 부분을 활용할 수 있는 부분이 있다.
1.3.1) 열거형의 첫 순서 바꾸기
enum RockPaperScissor
{
Rock = 1,
Paper,
Scissor
}
이런 식으로 선언해주면 Rock은 1, Paper는 2, Scissor는 3으로 바뀐다.
1.3.2) exit과 reset
enum RockPaperScissor
{
Rock = 1,
Paper,
Scissor,
exit = 9,
reset
}
9나 exit을 입력하면 종료를 하도록 할 수 있다.
1.3.3) 형변환으로 숫자 직접 입력하기
enum 에 들어있는 변수에 저장된 숫자를 직접 쓸 수도 있다.
RockPaperScissor command = (RockPaperScissor)1;
Console.WriteLine(command);
1.3.4) (응용)현업에서 사용하는 장비부위 별명 달기
먼저 장비 부위명을 enum으로 선언한다
enum Equipment
{
Head, Body, Foot, Arm, Size // 맨 마지막에 Size를 붙인다.(배열처럼 맨 끝을 선언)
}
메인에 배열을 선언하고 장비 속성을 닉네임으로 사용하여 부위를 헷갈리지 않고 오기입 방지 및 작업속도를 높일 수 있다.
static void Main(string[] args) // 배열을 선언한다.
{
string[] equipment = new string[(int)Equipment.Size];
equipment[(int)Equipment.Body] = "철갑옷";
}
* 열거형의 예시 : console.Backgroundcolor / consolekey key = console.readkey().key
사용자 정의 데이터 유형(Data Type), 비유하자면 여러 데이터를 담을 수 있는 박스이다.
예를 들어, 스킬을 정리해야 할 때 아래와 같은 정보가 있다고 하자.
// 파이어볼에 대한 정보
string skillName1 = "파이어볼";
float coolTime1 = 2.5f;
int cost1 = 18;
float range1 = 3.5f;
// 강타에 대한 정보
string skillName2 = "강타";
float coolTime2 = 2f;
int cost2 = 10;
float range2 = 2.5f;
현재 코드로도 변수를 일일이 1, 2로 설정하는 번거로움과. 이렇게 작성함으로서 항목의 누락이나 오타 등을 찾기가 어려울 것이다. 이를 방지하기 위해 필요한 것이 구조체이다.
위의 스킬을 정리하기 위한 구조체를 선언해주자.
struct Skill
{
public string name;
public float coolTime;
public int cost;
public float range;
}
* 아직은 객체지향에 관해 배우기 전 단계이니, 우선은 외부의 접근이 가능한 public으로 선언해야 한다는 것만 알아두자. (외부에서 접근하면 안 되는 항목은 private로 선언해야 함)
이와 같이 선언하고 메인에 스킬을 정리하면 다음과 같이 정리할 수 있다.
static void Main(string[] args) // 배열을 선언한다.
{
Skill fireball;
fireball.name = "파이어볼";
fireball.coolTime = 2.5f;
fireball.cost = 10;
fireball.range = 3.5f;
Skill Smash;
Smash.name = "강타";
Smash.coolTime = 2f;
Smash.cost = 10;
Smash.range = 2.5f;
}
이와 같이 코드를 간단하게 저장할 수 있으며, 아래와 같이 입력 시에도 오타가 날 시 문법오류로 표시되므로 오탈자를 방지할 수 있다.
스킬을 4개 만들고, 각각을 q, w, e, r 스킬로 생각하고 배열로 만들 수 있다.
Skill[] skills = new Skill[4]; // qskill, wskill, eskill, rskill
Skill fireball;
fireball.name = "파이어볼";
fireball.coolTime = 2.5f;
fireball.cost = 10;
fireball.range = 3.5f;
Skill Smash;
Smash.name = "강타";
Smash.coolTime = 2f;
Smash.cost = 10;
Smash.range = 2.5f;
Skill lance;
lance.name = "창던지기";
lance.coolTime = 1f;
lance.cost = 0;
lance.range = 1f;
Skill ultimalte;
ultimalte.name = "궁극기";
ultimalte.coolTime = 180f;
ultimalte.cost = 200;
ultimalte.range = 20f;
skills[0] = fireball;
skills[1] = Smash;
skills[2] = lance;
skills[3] = ultimalte;
while(true)
{
Console.Write("사용할 스킬 : ");
int value = int.Parse(Console.ReadLine());
Console.WriteLine("{0} 스킬을 사용합니다!!!", skills[value].name);
Console.WriteLine("마나가 {0} 감소합니다.", skills[value].cost);
Console.WriteLine("쿨타임을 {0} 초 돌립니다.", skills[value].coolTime);
Console.WriteLine("공격 범위 {0} 을 확인합니다.", skills[value].range);
}