Lisp 在铸造SPEL中推送项目位置

Lisp 在铸造SPEL中推送项目位置,lisp,scheme,push,adventure,Lisp,Scheme,Push,Adventure,我正在经历,这是处理拾取对象的建议解决方案: (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* *o

我正在经历,这是处理拾取对象的建议解决方案:

(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
每次玩家拾取一个对象时,将一个新的
添加到
*对象位置*
。虽然这在这样的小游戏中可能不是一个大问题,但如果你想添加从库存中放下物品的选项,
*对象位置*
列表可能会无限增长。。。例如,
拾取对象是否应该替换
(威士忌瓶客厅)
cdr
,而不是添加另一对
的副本


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

代码有一些问题:

  • 列表*对象位置*是一个文本。不应修改文本。你不能破坏性地改变青蛙的位置。所以你需要在前面推一个新的位置
  • 随着游戏的进行,列表会不断增加
  • 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的基本介绍,请参阅本书。

在函数式语言中,什么是处理这种情况的标准/好方法?在C#、JS或AS中,我可以简单地创建一个数组或列表,并在必要时更改各个条目。然而,在函数式编程中,似乎一个人应该尽可能不改变任何东西。。。我可以看到在解析一些数据或进行计算时这是如何可能的,但我真的看不到在其他实际应用中有效地应用这一范式的方法,比如一个必须1的游戏。跟踪各种状态和事件2。改变清单等内容@Philip Seyfi:“Lisp”(与Common Lisp一样)不是一种具有不变数据结构的纯函数式语言。它有可变的cons单元格、可变的数组、可变的对象、可变的哈希表——可以随意使用。在我的示例中,有没有办法将
(青蛙花园)
变为
(青蛙身体)
?@Philip Seyfi:查看扩展答案。