5KB C언어로 만든 터미널용 카드놀이
Oscar Toledo G.가 난독화 C언어 경진대회(IOCCC)를 위해 5KB 미만의 C언어와 curses 라이브러리를 활용해 터미널 기반의 클론다이크 솔리테어 게임을 개발한 후기를 소개합니다. 개발자는 제한된 용량 안에 게임을 구현하기 위해 UI와 코드를 극단적으로 최적화하고, 마우스 대신 키보드(Tab, Space) 조작 방식을 채택하는 등의 문제 해결 과정을 거쳤습니다.
메인 페이지 인텔 8080 에뮬레이터 체스 프로그램 대회 스토어 레트로게임 FAQ 링크 내 소개 스페인어로 보기
curses용 5KB 크기의 클론다이크 솔리테어 게임 Oscar Toledo G. 작성. 2026년 6월 7일
약간의 여가 시간이 생겼고, 마침 29회 IOCCC가 시작된 것을 보게 되었습니다. 그래서 이 대회에 출품할 작품을 코딩하기로 결정했습니다. '국제 난독화 C 코드 대회(IOCCC)'를 처음 들어보셨다면, 이 대회는 1984년부터 열려온 Landon Curt Noll이 창설한 대회입니다. 이 대회의 목적은 규칙에 명시된 특정 크기 제한 내에서 난독화된 C 프로그램을 작성하는 것입니다. 내가 과거에 수상했던 IOCCC 출품작들은 대회(Contests) 섹션에서 확인할 수 있습니다.
올해 최대 크기는 4993바이트(5킬로바이트보다 약간 작음)이며, 인쇄 가능한 문자 수는 2503자입니다. 인쇄 가능한 문자에 대한 몇 가지 특별한 규칙이 있기 때문에, 지금은 이를 확인하기 위한 'iocccsize'라는 도구가 있습니다.
내가 말하는 난독화된 C 코드란, 목적은 수행하지만 코드가 명확하게 읽히지 않는 형태로 C 코드를 작성하는 방식을 뜻합니다. 예를 들어, 1부터 10까지 세는 간단한 루프는 보통 이렇게 작성합니다:
#include <stdio.h> int main(void) { int c; for (c = 1; c <= 10; c++) printf("%d\n", c); }
하지만 C 문법의 강력함을 아주 약간만 이용하면, 다음과 같이 작성할 수 있습니다:
#include <stdio.h> int main(void) {int c=1;while(printf("%d\n",c),11>++c);}
이 정도면 난독화된 C 코드가 대략 무엇인지 감을 잡으실 수 있을 것입니다. 해마다 열리는 IOCCC에서 최고의 원라이너(한 줄 짜리 코드)를 해독하는 것은 하나의 도전입니다! 그리고 이는 여러분의 C언어 지식을 테스트하는 좋은 방법이기도 합니다.
발상 여러 아이디어를 생각해 본 끝에, 내 경력 동안 여러 차례 코딩했던 클론다이크 솔리테어 게임을 C언어로 만들기로 결정했습니다. 약 20년 전에는 나만의 운영체제용으로 만들었고(이것에 대해서도 나중에 더 글을 써야겠네요), 최근에는 인텔리비전(Intellivision) 콘솔용 클론다이크를 코딩하기도 했습니다.
아시다시피 솔리테어는 지뢰찾기와 함께 윈도우 3.1에 포함된 게임이었습니다. 당시 윈도우용 게임 시장이 거의 전무했기 때문에 이 두 게임은 완전한 성공을 거두었습니다. 윈도우 3.1을 쓰며 지루했던 사람들은 지뢰찾기와 솔리테어를 시작했고, 그것은 중독성이 있었습니다! 직접 플레이해 보고 규칙을 이해하기 전까지는 그 사실을 몰랐습니다. 또한 '페이튼스(patience)'라고도 불리는 여러 종류의 솔리테어 게임이 있다는 것을 알게 되었고, 윈도우에 있던 것은 그중 '클론다이크' 변형이었습니다. 모든 게임에서 승리할 수 있는 것은 아니라는 사실을 알게 되었을 때 나는 이 게임을 완전히 접었습니다.
사실 수학자들은 한 장씩 카드를 뽑는 게임의 경우 단 43%만 승리할 수 있다고 추정하며, 세 장을 뽑을 때는 이 숫자가 18%로 급감한다고 합니다. 모든 카드를 볼 수 있다고 해도 이기는 것이 결코 쉽지 않습니다.
[윈도우 3.1의 클론다이크 솔리테어 (PCjs Machines에서 실행)]
코딩 시작! 나는 2026년 2월 6일에 코딩을 시작했습니다. C언어로 핵심 로직을 작성하는 데 3일이 걸렸고, 카드 화면을 구현하기 위해 'curses' 라이브러리를 사용하기로 결정했습니다. 컬러를 지원하고 카드 기호를 표시하기 위해 유니코드 문자도 추가했습니다. curses 라이브러리는 사용 중인 터미널의 종류에 구애받지 않고 텍스트 기반 인터페이스를 만들기 위해 화면을 제어할 수 있게 해줍니다.
물론 이 게임의 첫 번째 버전은 대회의 크기 제한에 비해 너무 컸기 때문에 코드 최적화를 시작해야만 했습니다. 또한 카드를 선택하고 놓는 사용자 인터페이스 문제도 해결해야 했습니다. 기존 클론다이크의 인터페이스는 카드 위로 커서를 옮기고, 집어 들고, 다른 곳에 놓는 방식에 초점이 맞춰져 있습니다. 전설에 따르면 윈도우 3.1이 이 게임을 포함시킨 이유는 사용자에게 마우스로 물건을 끌어다 놓는(drag & drop) 방법을 가르치기 위해서였다고 합니다.
대회의 용량 제한에 맞추기 위해, 내 사용자 인터페이스는 카드를 선택할 때는 Tab 키를, 카드를 놓을 때는 Space 키를 사용하는 방식으로 획기적으로 단순화할 수밖에 없었습니다.
curses 배우기 curses를 배우는 것은 당신이 사악한 마법사라면 아주 좋을 겁니다... 아, 죄송합니다. 제 말은 curses '라이브러리'를 배우는 것이라는 뜻입니다. :P 이 게임에 적용하기까지의 학습 곡선은 영원히 끝나지 않을 것처럼 느껴졌습니다. 이 라이브러리에는 여러 버전이 있다는 것을 알게 되었고, 경험상 모든 리눅스 및 Mac 배포판에 어떤 형태로든 이 라이브러리가 포함되어 있다는 것을 알고 있습니다. curses의 가장 큰 문제는 버전이 너무 많다는 것입니다! 그리고 각 운영 체제마다 미묘하게 다른 버전을 통합하고 있습니다...