3

我正在学习 Lisp 中的 Casting 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的。虽然这在像这样的小型游戏中可能不是主要问题,但如果要添加从库存中放下物品的选项,列表可能会无限增长......不应该替换of ,例如,而不是添加另一个副本?pair*object-locations**object-locations*pickup-objectcdr(whiskey-bottle living-room)pair

我是 Lisp 的新手,可能会弄错......有人可以解释我的假设是否正确,如果是的话,在 Lisp 文本冒险中处理拾取对象的最佳方法是什么?

4

1 回答 1

1

代码有几个问题:

  • 列表 *object-locations* 是一个文字。不应修改文字。你不能破坏性地改变青蛙的位置。所以你需要在前面推一个新的位置。
  • 该列表会随着您浏览游戏而增加。
  • 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))

有关 Lisp的真正基本介绍,请参阅David S. Touretzky所著的Common Lisp: A Gentle Introduction to Symbolic Computation 一书。

于 2011-02-05T10:31:30.027 回答