I'm writing a dungeon crawler game in CL, and I'm having trouble with the case form.
Two things:
- Common Lisp complains
Duplicate keyform QUOTE in CASE statement
(make-instance 'cl-rogue:tile tile-type 'wall)
should print as "#", but the object prints as " " no matter which tile-type I use.
The code:
(in-package :cl-user)
(defpackage :cl-rogue
(:use :common-lisp)
(:export
:*rows*
:*cols*
:*levels*
:tile
:tile-type
:tile-contents
:tile-hidden
:tile-locked
:tile-closed
:main))
(in-package :cl-rogue)
(defparameter *cols* 80)
(defparameter *rows* 24)
(defparameter *levels* 26)
The class:
(defclass tile ()
((tile-type
:initarg :tile-type
:accessor tile-type
:initform 'floor
:documentation "Type of tile")
(tile-contents
:initarg :tile-contents
:accessor tile-contents
:initform '()
:documentation "Any items the tile holds")
(tile-hidden
:initarg :tile-hidden
:accessor tile-hidden
:initform nil
:documentation "Whether the tile is hidden or shown")
(tile-locked
:initarg :tile-locked
:accessor tile-locked
:initform nil
:documentation "Whether the tile is locked")
(tile-closed
:initarg :tile-closed
:accessor tile-closed
:initform nil
:documentation "Whether the tile is open or closed")))
The print method:
(defmethod print-object ((object tile) stream)
(with-slots (tile-type tile-contents tile-hidden tile-locked tile-closed) object
(if tile-hidden
(format stream " ")
(let ((an-item (car tile-contents)))
(if an-item
(format stream "~a" an-item)
(format stream (case tile-type
('wall "#")
('upstair "<")
('downstair ">")
('door (if tile-closed "+" "\\"))
(otherwise " "))))))))
You don't need to quote the symbols in
CASE
.Symbols in CASE clauses are not evaluated.
WALL
andDOOR
are purely symbols and not evaluated as variables.The Lisp reader reads
'foo
as(quote foo)
.You wrote:
Which is the equivalent of:
But you can't quote a symbol in
CASE
. You have to provide the symbols as literal constants.If you write:
This returns
:WE-REALLY-HAVE-A-FOO
. BecauseCASE
uses constant data, not variables.CASE
accepts a list of items. Since you haveQUOTE
as a symbol in more than clause, the compiler showed a warning.As I said, there is no quoting possible, since the items are not evaluated.
As for
CASE
accepting a list of items in the clauses, it looks like this:For the
WALL
symbol, you need to make sure that it is in the right package when you create the object.Better use a keyword symbol, such as
:wall
. Then you don't need to export it and there is no confusion about in which package the symbol is.About the formatting of the code: You had a bullet list and right after it a code section. This is not rendered as you expect. I have added the text 'The code:' before the code. Then the rendering works as expected.