은행 게임 만들어보기
간단한 은행 게임을 만들어 보려고 한다.
어떤 식으로 만들지는 전혀 정하지 않았다. 일단은 생각나는 대로 만들어 볼건데.
우선 Money 클래스를 정의하자.
간단한 생성자와 프로퍼티를 가진 Money 클래스이다.
이 클래스의 자식 클래스로 Gold, Silver, Bronze 를 정의한다.
이로써 돈의 단위 세가지를 만들었다. 이 단위들을 환전해주는 시스템을 구현해보자.
환전은 은행에서 이루어진다.
따라서 이번엔 은행 클래스를 만들어보자.
은행은 하나만 있으면 된다. 현실에서는 은행이 여러개이긴 하지만..
은행이 여러개인 게임은 그리 흔하지 않다. 게임에서의 은행은 영리적 목적으로 운영되는게 아니라,
유저의 편의를 위해 운영되는 시스템이기 때문이다. 롤이나 메이플의 은행을 생각해보면 되겠다.
어쨋든 그런 이유로 싱글톤 패턴을 써서 인스턴스의 개수를 하나로 제한하자.
환율은 우선 100 : 1 로 설정할 거지만 나중에 유동적으로 바꿀 수 있게 환율을 나타내는 rate 변수를 따로 만든다.
이제 환전하는 기능을 수행할 Exchange 메서드를 만들자.
100골드를 실버로 환전하면, 10000실버가 된다.
위의 예시처럼 돈을 환전할 때는,
1. 환전할 돈
2. 받고 싶은 화폐
두가지의 정보가 필요하다.
따라서 이 두가지의 정보를 매개변수로 받는 Exchange 메서드를 구현한다.
Currency는 열거형이다.
따라서 메서드는 이렇게 사용된다.
알고리즘 작성하기
환전 알고리즘을 작성해보자.
메서드에 들어온 정보를 다음과 같이 가정한다.
환전할 돈 : 100골드
받고 싶은 화폐 : 실버
이때 환전을 하면 다음과 같은 순서로 일을 처리한다.
1. 자신이 가지고 있는 골드가 100 이상이면
2. 자신의 보유 골드를 100 감소시키고
3. 자신의 보유 실버를 100 * rate 만큼 증가시킨다.
이떄 rate를 100으로 설정했기 때문에 실버는 1만이 증가된다.
받고 싶은 화폐를 브론즈로 해서 예시를 들어보자.
환전할 돈 : 100골드
받고 싶은 화폐 : 브론즈
1. 자신이 가지고 있는 골드가 100 이상이면
2. 자신의 보유 골드를 100 감소시키고
3. 자신의 보유 브론즈를 100 * rate * rate 만큼 증가시킨다.
따라서 브론즈는 100만이 증가된다.
다만 위의 과정을 유심히 살펴보면 다음과 같은 사실을 알 수 있다.
골드를 브론즈로 환전하는 행위는, 골드를 실버로 환전하고 다시 실버를 브론즈로 환전하는 행위와 같다.
즉 합성함수의 형태를 띤다.
환전하고 싶은 금액을 x 라고 하면,
골드를 실버로 환전할 때 다음과 같은 식이 나오고
f(x) = x * rate
골드를 브론즈로 환전할 때 다음과 같은 식이 나온다.
f(f(x)) = f(x) * rate = x * rate * rate
따라서 재귀함수 형태로 구현할 수도 있지만, 함수의 구조가 간단하기에,
수식으로 해결할 수도 있다.
그런데 골드와 실버, 골드와 브론즈, 실버와 브론즈 ... 등등의 케이스(순서를 고려하므로 총 6가지)를 다 if문으로 구별해서 구현하기에는 너무 귀찮다.
그리고 나중에 화폐의 종류가 추가되면 케이스가 엄청나게 늘어난다.
화폐 종류가 3개만 추가돼도 케이스가 30가지로 불어난다.
따라서 아래 사실에 주목하자.
골드와 브론즈는 2급 차이가 나기 때문에 rate가 두 번 곱해졌다.
수식에는 화폐 이름이 전혀 등장하지 않는다. 다만 두 화폐간의 급 차이가 rate의 차수를 결정한다.
따라서 아래처럼 하면 된다.
골드에는 숫자 2를 실버에는 1을 브론즈에는 0을 부여한다음, 두 수를 뺀다. 뺄셈은 순서를 구별하므로, 6가지 케이스를 모두 고려할 수 있다.
Gold, Silver, Bronze 클래스 모두 Money의 자식클래스이기 때문에 Money로 암시적 형변환이 된다.
다만 역은 성립하지 않는다. 즉 부모 클래스를 자식클래스로 형변환 할 수는 없다.
어쨋든 그렇게 넘어온 매개변수의 타입이 무엇인지 알아야 숫자 2, 1, 0 등등을 부여할 수 있을 것이다.
ToString() 메서드로 인스턴스의 FQDN을 알아낼 수 있다.
기능을 더 직관적으로 구현하기 위해 나는 ToString의 반환값을 FQDN이 아니라 다른 값으로 정할 것이다.
그러니 메서드 오버라이드.
위와 같은 작업을 세 화폐의 클래스에 모두 해준다.
이제 스위치문을 사용해서 각 화폐에 따라 숫자 2, 1, 0 을 저장해주자.
그리고 현재 가지고 있는 돈을 저장하기 위해 have 지역변수를 선언하고 각 케이스마다 처리해주자.
이제 급차이를 계산해주자
int d;
d = num - (int)currency;
다만 환전하려는 금액이 가지고 있는 금액보다 크면 환전이 불가하므로 이 부분을 처리해주자.
그리고 환전하려는 금액만큼 자신의 보유 금액을 없앤다.
이 작업 또한 스위치문을 사용한다.
1골드를 실버로 환전할 때처럼 상위 화폐에서 하위 화폐로 내려가는 경우와 다르게,
하위 화폐에서 상위 화폐로 올라갈 때는 고려해야 할 게 있다.
환율 100 기준 50실버를 골드로 환전하는 것은 불가능하기 때문.
물론 0.5 골드로 환전이 될 순 있지만 돈은 정수로 제한하려고 한다.
때문에 그런 경우 환전하려는 돈이 환율의 정수배인지 확인하는 작업을 해주어야 한다.
이제 증가시킬 값을 계산해보자.
그리고 매개변수로 넘어온 currency에 따라 스위치 문을 이용해 가지고 있는 화폐의 값을 증가시킨다.
그러면 exchange 매서드의 구현이 끝난다.
'C#' 카테고리의 다른 글
[C# / 객체지향] 9. 추상 클래스 (Abstract Class) (0) | 2020.01.20 |
---|---|
[C#] 은행 게임 코드 (수정본) (0) | 2020.01.17 |
[C# / 객체지향] 8. 다형성 - 오버로드 (Method Overload) (0) | 2020.01.08 |
[C# / 객체지향] 8. 다형성 - 메서드 오버라이드 (Method Override) (0) | 2019.12.19 |
[C# / 객체지향] 7. 클래스 상속 (class inheritance) (0) | 2019.12.17 |