0

这是我第二次尝试 Lisp 程序,作为 Mythender(一个免费分发的桌面 RPG)的掷骰子。但它有几个问题:

  • 加载后,我会收到确认创建包的提示。当然这个文件应该创建它?

  • 当我尝试使用 LispWorks 应用程序构建器独立构建它时,它会给出一个错误,说我正在尝试在编译时调用 CAPI 函数,但我看不到它在哪里。

  • 我从与我交谈过的一些 lisp 人那里得到了关于 (null ()) 部分的负面评论,这些部分表示一个函数没有返回,所以没有必要在堆栈上留下任何东西——这是否正确?有更好的方法吗?

任何一般性建议也将受到欢迎。

(defpackage :mythender (:add-use-defaults t) (:use "CAPI"))
(in-package :mythender)

(defun d6 () (the fixnum (+ 1 (random 6))))

(defun d6s (count)
  (declare (type fixnum count))
  (the list (loop for x from 1 to count collecting (d6))))

(defun d6over (count threshold) 
  (declare (type fixnum count threshold))
  (the fixnum (count-if 
   (lambda (x) (> threshold x)) 
   (d6s count))))

(defvar *storm* 3)
(defvar *thunder* 3)
(defvar *lightning* 0)

(declare (ftype (function) printstate))
(defun printstate ()
  (print *storm*)
  (print *thunder*)
  (print *lightning*)
  (the null ()))

(defun roll () 
  (incf *lightning* (d6over *thunder* 3))
  (incf *thunder* (d6over *storm* 3))
  (the null ()))

(defun damage (threshold)
  (setf *thunder* (d6over *thunder* threshold))
  (the null ()))

(defun doroll (&rest args)
  (roll)
  (update-interface)
  (the null ()))


(define-interface mythender-interface () ()
  (:panes
   (roll-button push-button :data "Roll" :callback #'doroll)
   (damage-button push-button :data "Damage")
   (storm-pane display-pane :title "Storm:" :title-position :left)
   (thunder-pane display-pane :title "Thunder:" :title-position :Left)
   (lightning-pane display-pane :title "Lightning:" :title-position :left))
  (:layouts
   (main-layout column-layout '(storm-pane thunder-pane lightning-pane buttonlayout))
   (buttonlayout row-layout '(roll-button damage-button))))

(defvar *interface*)

(defun update-interface-slot (slotname value)
  (declare (type string slotname) (type fixnum value))
  (setf (display-pane-text (slot-value *interface* slotname)) (write-to-string value))
  (the null ()))

(defun update-interface () 
  (update-interface-slot 'storm-pane *storm*)
  (update-interface-slot 'thunder-pane *thunder*)
  (update-interface-slot 'lightning-pane *lightning*)
  (the null ()))


(defun start () 
  (setf *interface* (make-instance 'mythender-interface))
  (display *interface*)
  (the null (update-interface)))
4

1 回答 1

3

您的构建问题的答案必须等到您告诉我们构建语句和错误消息。

你的最后一个问题:

(declare (ftype (function) printstate))
(defun printstate ()
  (print *storm*)
  (print *thunder*)
  (print *lightning*)
  (the null ()))

众所周知,它是一个函数。无需声明。声明这样的类型,在普通的 Common Lisp 中只是为了向编译器提供优化提示,编译器可能会忽略它。只有 CMUCL(以及衍生的编译器,如 SBCL 和 SCL)实际上对声明的类型做了更多的事情。

没有人用 Lisp 编写这样的代码。最好省略类型。请记住:Lisp 不是静态类型语言。

(defun printstate ()
  (print *storm*)
  (print *thunder*)
  (print *lightning*)
  (values))

Using(values)导致函数不返回值。这通常是首选,而不是返回NIL

如果您想在运行时以有意义的方式实际检查类型,请使用ASSERT,CHECK-TYPE和/或DEFMETHOD.

(defun d6s (count)
  (declare (type fixnum count))
  (the list (loop for x from 1 to count collecting (d6))))

只是:

(defmethod d6s ((n integer))
  "Returns a list of n dice rolls."
  (loop repeat n collect (d6)))

不要忘记以人类可读的形式描述函数的语义。

于 2014-05-11T07:46:04.920 回答