Перемещение позиций в Casting SPELs - PullRequest
3 голосов
/ 05 февраля 2011

Я прохожу Приведение SPEL в Лиспе , и это предлагаемое решение для обработки захвата объектов:

(define *location* 'living-room)

(define *object-locations*
  '((whiskey-bottle living-room)
    (bucket living-room)
    (chain garden)
    (frog garden)))

(define (pickup-object object)
  (cond [(is-at? object *location* *object-locations*)
         (push! (list object 'body) *object-locations*)
         (string-append "You're now carrying the " (symbol->string object) ".")]
        [else "There's no such object in here."]))

Я единственный, кто находит это неэффективным? Насколько я понимаю, функция push! cons - это новые значения pair до *object-locations* каждый раз, когда игрок поднимает объект. Хотя это не может быть большой проблемой в такой маленькой игре, как эта, но если бы вы добавили возможность складывать предметы из инвентаря, список *object-locations* мог бы расти бесконечно ... Не должен pickup-object заменить * Например, 1012 * из (whiskey-bottle living-room) вместо добавления другой копии pair?

Я новичок в Лиспе и, возможно, ошибаюсь ... Может кто-нибудь объяснить, верны ли мои предположения, и если да, то какой будет лучший способ справиться с подбором объектов в текстовом приключении на Лиспе?

1 Ответ

1 голос
/ 05 февраля 2011

Есть несколько проблем с кодом:

  • Список * object-location * является литералом. Литералы не должны быть изменены. Вы не можете изменить местоположение лягушки деструктивно. Так что вам нужно нажать на новое место впереди.
  • Список растет по мере прохождения игры.
  • STRING-APPEND создает новую строку для каждого действия захвата.

Но

  • Это просто и достаточно для примера с книгой.
  • Стек для местоположений объектов может привести к некоторой отмене.
  • Перенос новой ассоциации предмета и местоположения - быстрая операция.
  • Это дает читателю книги возможность повысить эффективность кода.

В Common Lisp это легко изменить:

(defvar *object-locations*
  (copy-tree
   '((whiskey-bottle living-room)
     (bucket living-room)
     (chain garden)
     (frog garden))))

(defun get-location (object)
  (second (assoc object *object-locations*)))

(defun set-location (object location)
  (setf (second (assoc object *object-locations*))
        location))

CL-USER > (get-location 'frog)
GARDEN

CL-USER > (set-location 'frog 'living-room)
LIVING-ROOM

CL-USER > (get-location 'frog)
LIVING-ROOM

CL-USER > *object-locations*
((WHISKEY-BOTTLE LIVING-ROOM)
 (BUCKET LIVING-ROOM)
 (CHAIN GARDEN)
 (FROG LIVING-ROOM))

См. Книгу Common Lisp: Нежное введение в символические вычисления Дэвида С. Турецкого для действительно базового введения в Lisp.

...