Вопрос

Я пытаюсь переписать игру Wizard от "Land of Lisp" http://landoflisp.com/wizards_game.lisp

(def *nodes* {:living-room "you are in the living-room. a wizard is snoring loudly on the couch."
          :garden "you are in a beautiful garden. there is a well in front of you."
          :attic "you are in the attic. there is a giant welding torch in the corner."})

(def *edges* {:living-room '((garden west door) (attic upstairs ladder))
          :garden '(living-room east door)
          :attic '(living-room downstairs ladder)})

(defn describe-location [location nodes]
  (nodes location))

(defn describe-path-raw [edge]
  `(there is a ~(last edge) going ~(second edge) from here.))

(defn describe-path [edge]
   (map #(symbol (name %)) (describe-path-raw edge)))

(defn describe-paths [location edges]
   (apply concat (map describe-path-raw (location edges))))

При попытке:

   (println (describe-paths :attic *edges*))

Я получил это исключение:

Исключение в потоке "Main" java.lang.runtimeexception: java.lang.illegalargumentException: не знаю, как создавать ISEQ из: clojure.lang.symbol (Wizard-game.clj: 0)

У меня еще нет свободного глаза, что я делаю не так?

Это было полезно?

Решение

Поместить это в реплику, и бежать следование:

user> (ns foo (:use clojure.contrib.trace))
nil

На этом этапе я копирую в вашем коде в реплику. (не показаны)

Далее я запускаю след:

foo> (dotrace [describe-location describe-path-raw describe-path describe-paths]
              (describe-paths :attic *edges*))
TRACE t1662: (describe-paths :attic {:living-room ((garden west door) (attic upstairs ladder)),     :garden (living-room east door), :attic (living-room downstairs ladder)})
TRACE t1663: |    (describe-path-raw living-room)
; Evaluation aborted.
foo> 

Таким образом, проблема в том (Destive-Path-Raw Livel-Room). Как указывает сообщение об ошибке, гостиная является символом, и эта функция пытается делать такие вещи, как Call Last и Second, что можно сделать только на последовательностях.

Так почему это происходит?

Внутри описывающих путей вы звоните (края местоположения). Здесь местоположение: чердак, а края - карта. Следовательно, (края местоположения) работает (гостиная внизу лестницы). Вы нанесете на карту «Опишите пап-рост» в этот список, который работает:

((describe-path-raw living-room) (describe-path-raw downstairs) (describe-path-raw ladder))

И это бросает исключение на первом вызове, так как гостиная является символом, а не последовательности.

Другие советы

Это выглядит как describe-paths ожидает, что ценность посмотрела в *edges* Карта будет списком списков, а не просто списком. Обратите внимание на разницу между :living-room вход и :garden а также :attic Записи: у первого есть позвоночник верхнего уровня, ниже которого вы найдете два трех-тура, тогда как последние два имеют только один три тупе.

Функция describe-path-raw Ожидается получить кортеж, по крайней мере, второй размер, но на самом деле это имеет смысл только для тех, кто имеет третий размер; кормить это любым из четырех трех ударов в *edges* Карта будет работать. Проблема, с которой вы столкнулись, связана с применением map в *edges* запись для :attic, который берет список

(living-room downstairs ladder)

и кормит объекты списка один за другим describe-path-raw:

(describe-path-raw living-room)
(describe-path-raw downstairs)
(describe-path-raw ladder)

В каждой из этих трех форм аргумент передан describe-path-raw это символ, а не список, ожидаемый describe-path-raw.

Короче говоря, попробуйте добавить дополнительный набор скобок вокруг двух вторых значений в вашем *edges* Карта, гнездя каждый список в новом списке верхнего уровня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top