4장에서는 실제 지도를 만드는 법에 대해서 살펴본다.
해당하는 이미지는 아래 링크에서 가져올 수 있다.
http://www.atariarchives.org/adventure/picture04-1.gif
그럼 해당하는 지도를 보면..
이런 식이다. 각 방은 지정된 다른 방으로 이동할 수 있는 문이 있다.
이것을 일련의 리스트로 분류해보면 다음과 같다.
1번 방은 동쪽으로 3번, 남쪽으로 2번방과 연결되어 있다. 즉 북/남/동/서에 따른 리스트로 보면..
(0 2 3 0)
이라고 쓸 수 있다. 편의상 0은 막혔다고 가정해본다.
이런 식으로 5번방까지를 모두 리스트로 표시하면
'((0 2 3 0)
(1 0 5 0)
(0 4 0 1)
(3 5 0 0)
(4 0 0 2))
로 표현할 수 있다. 여기에서는 베이직 코드를 가급적 1:1로 LISP으로 변환하는 중이니 일단 딴지는 금물..
이제 각 방과 각 방의 문이 어디로 통해지는지를 LISP코드로 작성하면..
(defvar *map*
'((0 2 3 0)
(1 0 5 0)
(0 4 0 1)
(3 5 0 0)
(4 0 0 2)))
(defun get-room (which)
(cond ((< which 1)
(error "방코드가 1보다 작습니다."))
(t
(nth (- which 1) *map*))))
(defun get-direction (dir)
(cond ((string= dir "north") 0)
((string= dir "south") 1)
((string= dir "east") 2)
((string= dir "west") 3)
(t
(error "지원되지 않는 방향입니다."))))
(defun get-door (room dir)
(nth (get-direction dir) (get-room room)))
이제 기본적인 방을 돌아다닐 수 있다.
개별적인 방의 door를 얻어 이를 문장으로 표현해보면 다음과 같다.
<br />(defun desc-door (door)<br /> (cond ((= door 1) "북쪽으로 가는 문이 있습니다.")<br /> ((= door 2) "남쪽으로 가는 문이 있습니다.")<br /> ((= door 3) "동쪽으로 나갈 수 있습니다.")<br /> ((= door 4) "서쪽으로 가는 문이 열려 있습니다.")))<br /><br />(defun desc-room (room)<br /> (let ((which-room (get-room room)))<br /> (format t "당신은 ~A번 방에 있습니다.~%" room)<br /> (labels ((iter (room)<br /> (cond ((null room) '())<br /> (t<br /> (let ((room_text (desc-door (car room))))<br /> (cond ((not (null room_text))<br /> (format t "이 방에는 ~A~%" (desc-door (car room))))))<br /> (iter (cdr room))))))<br /> (iter which-room))))<br /><br />
이 된다.
이제 마지막으로 방을 돌아다니는 코드를 입력하자.
<br /><br />(defvar *current-room* nil)<br /><br />(defun goto-room ()<br /> (format t "몇번 방으로 가시겠습니까?:")<br /> (setf *current-room* (read))<br /> (desc-room *current-room*))<br /><br />(defun goto-door ()<br /> (format t "어느 방향으로 가시겠습니까?(N[orth]/S[outh]/E[ast]/W[est]:")<br /> (let ((direction (read-char)))<br /> (let ((room (get-door *current-room*<br /> (cond ((char= direction #\n) "north")<br /> ((char= direction #\s) "south")<br /> ((char= direction #\e) "east")<br /> ((char= direction #\w) "west")))))<br /> (cond ((= room 0) <br /> (format t "그쪽은 막혔습니다."))<br /> (t<br /> (setf *current-room* room))))))<br />
댓글 없음:
댓글 쓰기