메아리

Tour de IOCCC: 1994/westley

#if O
main(){}
#else
























#if rop&onut&((own&rain)|warf)
#include "                                                                The orc scrambles to the drain,                             trying to get the donut; you                                run out the door and escape!                                                                             The End                                                                        "
#else
#if escribe
#if ocument
#include "                                                                It reads:                                           Depress Dotted Dog                                                                      "
#else
#if oor
#include "                                                                The door is decorated with relief                       figures of various dog breeds                                                                           "
#else
#if rain
#include "                                                                Through the drain you see a dwarf                       in another cell                                                                                 "
#else
#if warf
#include "                                                                The gnarled dwarf looks thirsty                                                                         "
#else
#if ungeon|ebris
#include "                                                                You notice a desk, a phone, and                             a phone directory among the clutter                                                                 "
#else
#if esk
#include "                                                                There are some dimes on the desk                                                                "
#else
#if irectory
#include "                                                                It reads:                                           Pixie's Pub -                                   instant service -                                   Dial DUNgeon0614                                                                        "
#else
#include "                                                                You notice nothing unusual                                                                      "
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#else
#if ial&UNgeon0614
#include "                                                                Pixie takes your order, and                             magically, the room is filled                               with banana daiquiris                                                                       "
#endif
#if rink&aiquiri
#include "                                                                As you drink, a voice from                                  below says 'Could you drop                                  one down here?'                                                                         "
#endif
#if rop&aiquiri
#if warf|own
#include "                                                                The dwarf eagerly accepts                               the drink.  'Thanks!  Here,                                 I found this, but I can't                           understand it.'  He hands                           you a document                                                                          "
#else
#include "                                                                You drop the drink                                      on the floor                                                                            "
#endif
#endif
#if epress&(almatian|almation)
#include "                                                                As you press the dalmatian                                  figure, the door opens - only                               to reveal a menacing orc by                             a vending machine (with a                           sign reading 'DEPOSIT MONEY')                                                                   "
#endif
#if eposit&(ime|imes)
#include "                                                                Donuts spill out; you get                               some, the orc hungrily eats                                 the rest                                                                            "
#endif
#if rop&onut
#include "                                                                The orc quickly eats the                                donut; he still bars the                                way                                                                                 "
#endif
#if rop+epress+ime+eposit+rink+aiquiri+onut==1
#include "                                                                Be more specific                                                                        "
#endif
#include "                                                                You are in a debris-filled                                  dungeon; a door bars the                                way, and sludge trickles into                               a floor drain                                                                           "
#endif
#endif
#endif

심사 위원이 힌트에 써 놓았듯이, 모든 컴파일 에러가 나쁜 건 아닙니다.

뭘 하는 프로그램인가?

먼저 사용하고 있는 터미널의 가로 크기를 80칸으로 바꾸고, 혹시 탭 크기를 수동으로 설정할 수 있다면 8칸으로 고칩니다. 이것은 이 프로그램을 즐기기 위해 꼭 필요합니다. (뭐 설정하지 않아도 내용은 볼 수 있지만 보기 그렇게 좋진 않습니다.)

먼저 이 프로그램을 컴파일해 봅니다.

$ gcc westley.c
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

...웬 메시지랍니까? 무슨 파일이 없다는 건 확실한데 어떤 파일인지는 모르겠고 뭔가 메시지가 튀어 나왔네요. 해석하면,

당신은 파편(debris)들로 차 있는 지하 감옥(dungeon)에 있습니다. 나가는 길은 문(door)으로 막혀 있고 진창이 바닥의 배수구(drain)로 떨어져 내리고 있습니다.

뭔지 감을 못 잡으신 분을 위해서 다른 옵션으로 컴파일해 보겠습니다. 이 프로그램은 매크로를 통해 소통합니다.

$ gcc westley.c -Describe -Door
westley.c:36:132: error:
 The door is decorated with relief
 figures of various dog breeds

 : No such file or directory

해석하면,

문(door)은 다양한 개(dog) 모양이 새겨져 장식되어 있습니다.

바로 텍스트 어드벤처 게임입니다! "문을 설명하여라"(Describe Door) 같은 식으로 키워드를 넣으면 거기에 따라 반응하는 것입니다. 키워드를 넣을 때 사용하는 -D...는 매크로를 선언하는 컴파일러 옵션으로, 다른 말로 하면 모든 키워드는 모두 D로 시작하게 됩니다.

어떻게 동작하는가?

이 프로그램의 구조는 간단합니다. 매크로가 설정된 방법에 따라서 서로 다른 #include 문을 수행하고, 그 와중에 에러가 나는 것이지요.

-Door와 같이 선언된 매크로의 기본 값은 1입니다. (이 때 주의할 점은 이 매크로의 "이름"은 oor이라는 것입니다.) 한편 if에서 선언되지 않은 매크로를 참조하려고 할 경우 그 값은 0이 됩니다. 따라서 예를 들어 -Drop -Donut -Dwarf 같은 옵션을 줬을 경우, 다음 #if 문은:

#if rop&onut&((own&rain)|warf)

rop이 1, onut이 1, ownrain이 0, warf가 1로 평가되어, 최종적으로 전체 조건은 1이 됩니다. 매크로가 없다고 에러가 나는 게 아닙니다. (한편, 이렇게 할 경우 "0으로 선언된" 매크로와 선언되지 않은 매크로를 구분할 수 없다는 문제도 있습니다. 이를 위해서 defined x 수식은 선언된 매크로에 대해 항상 1을 반환합니다.)

한편 #include 문은 80칸에 맞춰서 쓰여진 텍스트입니다. 예를 들어 위 #if 바로 뒤에 있는 문장은 다음과 같습니다. (탭은 »로 표기했습니다.) 아 이거 스포일러인가요?

#include "»»»»»»  »»»»»»»»»»  The orc scrambles to the drain,»»»»»          trying to get the donut; you»»»»»»          run out the door and escape!»»»»»»»  »»»»»»»»»»  »       The End»»»»»»»»  »»»»»»»»»»  "

혹시나 이런 이름의 파일을 만들 수 있다면 이 프로그램은 좀 더 황당한 결과를 낼 수 있을 지도 모릅니다만... 설마 없을 거라 생각합니다.

그럼 한 가지 의문이 남습니다. 사용자로부터 컴파일 도중 프로그램을 입력받도록 하는 1988/spinellis 이후로 컴파일은 기본적으로 자동으로 가능해야 한다는 조항이 추가되었습니다. 이 프로그램은 1994년 출품작인데 어떻게 컴파일되지 않는 프로그램이 수상한 걸까요? 사실 이 코드는 맨 위에 다음과 같은 main 함수를 포함하고 있습니다.

#if O
main(){}
#else
/* ... */
#endif

이 코드는 -DO 옵션을 주었을 때만 컴파일되고, 아무 일도 하지 않습니다. 물론 Makefile에도 -DO 옵션이 들어 있지요. 은근슬쩍 규칙을 지키는 셈입니다.

스포일러!

영어로 되어 있어서 이 게임을 즐기기가 좀 뭐하신 분을 위해서 한 번 제가 직접 플레이해 봤습니다. 스포일러니까 직접 해 보실 분은 보지 마세요.

$ gcc westley.c
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

당신은 파편(debris)들로 차 있는 지하 감옥(dungeon)에 있습니다. 나가는 길은 문(door)으로 막혀 있고 진창이 바닥의 배수구(drain)로 떨어져 내리고 있습니다.

$ gcc westley.c -Describe -Door
westley.c:36:132: error:
 The door is decorated with relief
 figures of various dog breeds

 : No such file or directory

문(door)은 다양한 개(dog) 모양이 새겨져 장식되어 있습니다.

$ gcc westley.c -Describe -Dog
westley.c:53:79: error:
 You notice nothing unusual

 : No such file or directory

아무 이상한 점도 찾을 수 없습니다.

$ gcc westley.c -Describe -Drain
westley.c:39:119: error:
 Through the drain you see a dwarf
 in another cell

 : No such file or directory

배수구(drain)를 살펴 보니 난쟁이(dwarf)가 다른 방에 있는 게 보입니다.

$ gcc westley.c -Describe -Dwarf
westley.c:42:92: error:
 The gnarled dwarf looks thirsty

 : No such file or directory

쭈글쭈글한 난쟁이(dwarf)는 목 말라 보입니다.

$ gcc westley.c -Describe -Debris
westley.c:45:133: error:
 You notice a desk, a phone, and
  a phone directory among the clutter

 : No such file or directory

당신은 어질러진 잔해 중에 책상(desk), 전화, 전화번호부(phone directory)가 있는 걸 알아 챕니다.

$ gcc westley.c -Describe -Desk
westley.c:48:84: error:
 There are some dimes on the desk

 : No such file or directory

책상(desk) 위에 10센트짜리 동전(dime) 몇 개가 있습니다.

$ gcc westley.c -Describe -Dime
westley.c:53:79: error:
 You notice nothing unusual

 : No such file or directory

아무 이상한 점도 찾을 수 없습니다.

$ gcc westley.c -Describe -Directory
westley.c:51:159: error:
 It reads:
      Pixie's Pub -
     instant service -
     Dial DUNgeon0614

 : No such file or directory

전화번호부에 쓰여 있길: 픽시 펍 - 즉석 서비스 - DUNgeon0614로 전화 주세요

미국 등에서는 전화번호를 각 숫자에 배당된 문자(예를 들어 1은 a/b/c라거나)로 해석해서 홍보하는 경우가 적잖게 있습니다.

$ gcc westley.c -Dial -DUNgeon0614
westley.c:63:156: error:
 Pixie takes your order, and
 magically, the room is filled
  with banana daiquiris

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

픽시가 주문을 받자, 마법으로 방에 바나나 다이키리(daiquiri, 칵테일의 일종)가 채워집니다.

그 다음 메시지는 처음에 시작했을 때의 메시지와 같은데, 이건 컴파일러에 따라서 #include가 실패해도 계속 다음 문장을 해석하려 하기 때문에 나타나는 현상입니다. 해당하는 부분의 번역은 생략합니다.

$ gcc westley.c -Drink -Daiquiri
westley.c:66:153: error:
 As you drink, a voice from
  below says 'Could you drop
  one down here?'

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

다이키리를 마시자(drink) 아래에서 "한 방울만 여기로 떨어뜨려(drop) 주실 수 없나요?"라는 목소리가 들려 옵니다.

$ gcc westley.c -Drop -Daiquiri
westley.c:72:102: error:
 You drop the drink
  on the floor

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

당신은 음료수(drink)를 바닥에 떨어뜨립니다(drop).

땅바닥이 아니라 난쟁이에게 떨어뜨리려면 어떻게 해야 할까요?

$ gcc westley.c -Drop -Dwarf -Daiquiri
westley.c:70:220: error:
 The dwarf eagerly accepts
  the drink.  'Thanks!  Here,
  I found this, but I can't
 understand it.'  He hands
 you a document

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

난쟁이는 열심히 음료수(drink)를 받아 먹습니다. "고맙습니다! 여기서 이런 걸 찾았는데, 이게 뭔지는 모르겠어요." 그는 당신에게 문서(document)를 넘겨 줍니다.

$ gcc westley.c -Describe -Document
westley.c:33:102: error:
 It reads:
      Depress Dotted Dog

 : No such file or directory

문서에 쓰여 있길: 점박이(dotted) 개(dog)를 누르시오(depress).

$ gcc westley.c -Depress -Dotted -Dog
westley.c:85:70: error:
 Be more specific

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

좀 더 자세히 말해 주세요.

이런, 점박이 개가 여러 마리 있나 봅니다. 점박이 개 중에서 D로 시작하는 게 있을까요?

$ gcc westley.c -Depress -Dalmatian
westley.c:76:239: error:
 As you press the dalmatian
  figure, the door opens - only
  to reveal a menacing orc by
 a vending machine (with a
 sign reading 'DEPOSIT MONEY')

 : No such file or directory
westley.c:85:70: error:
 Be more specific

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

달마시안(dalmatian) 상을 누르자 문(door)이 열렸지만, 나타난 것은 ("돈을 넣으시오(deposit)"라고 쓰여진) 자판기와 위협스런 오크 뿐이었습니다.

처음에 잔해 사이에 있던 동전을 기억하시나요?

$ gcc westley.c -Deposit -Dime
westley.c:79:147: error:
 Donuts spill out; you get
  some, the orc hungrily eats
  the rest

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

도넛(donut)들이 떨어져 내립니다. 당신이 몇 개를 가져간 사이, 오크가 허겁지겁 나머지를 다 먹어 버립니다.

오크가 배가 고팠던 모양이군요. 어떻게 하면 오크의 시선을 피해서 도망칠 수 있을까요?

$ gcc westley.c -Drop -Donut
westley.c:82:139: error:
 The orc quickly eats the
  donut; he still bars the
  way

 : No such file or directory
westley.c:87:195: error:
 You are in a debris-filled
  dungeon; a door bars the
  way, and sludge trickles into
  a floor drain

 : No such file or directory

오크가 재빨리 도넛(donut)을 먹습니다. 그는 여전히 길을 지키고 있습니다.

앞에서 -Drop -Daiquiri라고 했을 때와 마찬가지로 도넛은 땅바닥에 떨어져 내린 것입니다. 그럼 난쟁이에게 떨어뜨려 주면 어떨까요?

$ gcc westley.c -Drop -Dwarf -Donut
westley.c:29:208: error:
 The orc scrambles to the drain,
  trying to get the donut; you
  run out the door and escape!

               The End

 : No such file or directory

오크가 도넛(donut)을 잡으려고 배수구(drain)로 기어 들어 갑니다. 당신은 문 바깥으로 나가서 탈출합니다! - 끝 -

지하 감옥을 빠져 나오는 데 성공했습니다! 사실 텍스트 어드벤쳐는 예상치 못 한 키워드를 찾는 것이 묘미긴 하지만 이 게임의 경우 소스 코드에 그냥 박혀-_-; 있기 때문에 약간 김이 빠지는 게 사실입니다. (심지어 키워드를 쓰는 순서도 의미가 없고요.) 그리고 사실은 위에 보인 메시지들이 소스 코드에 있는 모든 메시지고요. 하지만 컴파일러 에러로 게임을 한다니, 좀 기발하지 않습니까?


Copyright © 1999–2009, Kang Seonghoon.