35-1.고스톱

35-1-가.게임 소개

여기까지 C++의 여러 가지 문법들을 열심히 배워 왔는데 이쯤에서 C++의 기능들을 골고루 활용한 예제를 하나 작성해 보자. 문법이란 약속에 불과하기 때문에 설명을 읽고 예제를 실행해 보면 대체로 이해하기 어렵지 않다. 그러나 인간의 뇌는 일부러라도 사용해 보지 않으면 금방 잊어 먹게 되어 있으므로 단편적인 예제보다는 완성된 프로그램 하나를 만들어 보는 실습이 꼭 필요하다. 시간이 좀 걸리더라도 실습을 직접 해 보기를 강력히 추천한다.

예제란 아무래도 짧아야 하고 너무 상세하고 거추장스러운 기능은 빼야 도움이 되는 법이다. 그러면서 문법 요소들을 골고루 사용해 보고 객체 지향과 잘 어울리는 예제를 선정해야 하는데 고민끝에 고스톱 게임을 만들어 보기로 했다. 이 게임을 실습 주제로 선택한 이유는 게임판에 객체들이 많이 등장해서 캡슐화, 추상화의 좋은 실습이 되기 때문이다. 이른바 도박 게임으로 분류되어 약간의 거부감이 들기도 하지만 한편에서는 전통 민속 놀이라는 주장이 있어 친근하기도 하다.

고스톱 외에도 몇 가지 보드 게임을 실습 주제로 선정해서 만들어 보았지만 고스톱이 가장 적합한 예제로 선정되었다. 왜냐하면 워낙 대중적이라 게임의 규칙을 설명할 필요가 없고 로직 파악 단계가 생략되기 때문이다. 복잡한 게임의 경우 규칙을 익히는데만도 상당한 시간이 드는데 비해 고스톱은 그럴 필요가 없어 설계와 구현에만 치중할 수 있다. 아주 드문 경우겠지만 고스톱을 한 번도 해 본적이 없는 간첩이나 탈북자는 친구들에게 부탁해서 게임 규칙부터 익히고 오도록 하자. 그깟짓 돈 몇 푼만 잃어주면 친절하게 가르쳐 줄 좋은 친구들은 얼마든지 있다. 여기서는 게임 규칙에 대해서는 잘 알고 있다고 가정한다.

고스톱은 여러 가지 방법으로 개발 가능하다. 구조적인 C로 짤 수도 있고 객체 지향적인 특성을 충분히 활용하여 C++로도 짤 수 있고 검색 알고리즘이 자주 사용되므로 STL도 적합하다. 논리가 확실히 만들어졌으면 화려한 그래픽 환경에서 예쁜 화투패들이 돌아 다니도록 할 수도 있고 네트워크 기능을 붙이면 여러 명이서 게임을 할 수도 있다. 여기서는 C 버전은 생략하고 C++ 버전을 만들어 보도록 하되 이 단계에서는 그래픽 프로그래밍을 모르는 경우가 대다수이므로 콘솔환경에서 작성하기로 한다. 그래픽 환경은 메시지 드리븐과 멀티 태스킹을 고려해야 하므로 게임 논리에만 치중할 수 없어 학습 효율이 떨어진다.

콘솔은 표현력이 너무 약해 게임 규칙은 가급적 간단하게 하고 대화상자나 마우스를 사용할 수 없으므로 사용자와 복잡한 대화가 필요한 기능은 제외하기로 한다. 두 명이서 게임을 진행하는 맞고 형식이되 한 컴퓨터에서 서로의 패를 숨길 수는 없으므로 아래, 위에 모두 펼쳐 놓고 게임을 진행한다. 어차피 학습을 위한 게임이므로 패를 다 보이도록 하는 것이 더 편리하다. 사실 두 명이서 한 컴퓨터로 카드 게임을 할 수는 없으므로 이 게임은 왕따가 혼자 시간 떼우기용이라고 봐야 할 것이다. 네트워크가 붙어야 제대로 된 2인용 게임이 된다. 고스톱의 게임 규칙은 다른 어떤 게임보다 복잡한 편인데 실습의 편의상 다음 기능은 일단 제외한다.

 

① 같은 카드 세 장이 들어오면 흔들 수 있고 중간에 세 장을 한꺼번에 내면 폭탄이라 하여 점수를 곱절로 올릴 수 있다. 이 기능은 사용자가 선택할 수 있어 대화가 필요하며 점수를 계산하는 것은 게임 운영 규칙이 아니므로 무시하기로 한다. 또한 한꺼번에 4장이 들어오면 총통이라고 해서 기본 점수를 얻으며 담요에 4장이 깔리면 1등이 이 패를 모두 먹는데 이 규칙은 일종의 비정상적인 예외 상황일 뿐이므로 처리하지 않는다.

② 점수 계산 규칙을 단순화한다. 어떤 카드는 쌍피로 취급하고 9십 짜리 카드는 피가 되거나 십이 될 수 있는데 이 옵션도 제거한다. 보너스 카드 같은 것은 취급하지 않는다. 첫 설사시 일정액의 돈을 상대편이 물어야 하는 규칙도 있고 세 번씩이나 설사를 하는 불쌍한 사람을 위해 기본 점수를 부여하기도 하는데 이런 규칙도 구현하지 않는다.

③ 점수 계산은 하되 피박, 광박 등 점수를 2배하는 규칙은 적용하지 않으므로 상대방 패를 보고 알아서 계산하도록 하자. 오고 가는 현금속에 싹트는 우리 우정이라는 고스톱의 절대 규칙이 있기는 하지만 이 게임에서는 어차피 현금이 오고 갈 수 없으므로 중요한 규칙이 아니다.

 

이것 저것 따 빼 버리고 나면 남은 규칙이 별로 없을 것 같지만 이렇게 해도 고스톱은 충분히 복잡한 게임이다. 이나마도 2인용 맞고라 이 정도인데 3~4인용으로 만들면 광팔기, 독박, 쇼당 같은 규칙이 더 추가되어야 한다. 쇼당은 다자간의 대화와 타협이 필요한 워낙 복잡한 기능이라 상용 고스톱 게임도 구현하는 예가 거의 없을 정도다.

빠진 규칙들도 꼭 만들고자 한다면 그리 어려울 것도 없다. 이 예제를 이해하고 난 다음에 제외된 규칙 중 한 두가지를 선정하여 직접 만들어 보아라. 후반부의 개작예에서는 이 중 몇 가지를 선정하여 실습해 볼 것이다. 설사, 싹쓸이, 쪽, 따닥 같은 기능은 게임의 핵심이라 구현하며 상대방의 피를 뺏들어 오기도 한다. 구현된 실행 파일의 모습은 다음과 같다.

아래쪽에 남군, 위쪽에 북군 패를 표시하고 오른쪽에 각각이 먹은 카드와 점수, 고 회수를 출력해 놓았다. 플레이어의 이름을 청군, 백군 따위로 붙일려고 했는데 위치로 이름을 짓는 것이 분석에는 가장 편리할 것 같아 남북으로 이름을 지었다. 중간에는 담요가 펼쳐져 있는데 이 위에 몇 개의 카드가 펼쳐져 있고 뒤집을 카드 목록인 데크가 ???로 표시되어 있다. 담요는 실제 고스톱의 용어를 빌려온 것인데 코드에서도 담요라고 칭한다. 물론 실제 게임에서는 신문지일 수도 있지만 으례 국방색 담요인 경우가 가장 많아 실제 사물대로 추상화했다.

그래픽이 아니라 무척 썰렁해 보이고 마우스를 쓸 수 없으므로 키보드의 숫자키로 패를 선택해야 한다. 그래서 플레이어의 패 아래쪽에 일련 번호를 출력해 놓았다. 그래픽이나 네트워크 기능은 이 예제를 분석한 후 직접 구현해 보기 바란다. 콘솔 환경이지만 이 게임의 자료 구조와 알고리즘은 그래픽 버전, 네트워크 버전에서 그대로 재사용될 수 있다.

솔직히 이 게임은 혼자서 하는 게임이라 별로 재미가 없다. 하지만 분석을 위해서는 일단 게임을 여러 번 해 봐야 한다. 어떻게 동작하는지 규칙을 좀 파악해야 클래스 계층도 쉽게 파악되고 프로그램과 친해져야 분석해 볼 마음이 생기는 것이다. 한 10 분 정도 게임을 실행해 보고 나 같으면 저런 프로그램을 어떻게 만들지 대충 머리속으로라도 디자인해 본 후 분석 결과를 읽어 보자.