Problem with setf/aref and arrays
Posted: Mon Apr 07, 2014 9:33 pm
Hello, I'm writing a dungeon crawing game.
The Dungeon class is pretty simple. It consists of a 2D array of Tile structs.
The tiles can be either solid of not solid.
My problem comes with the carve-room function.
Instead of just setting the desired Tiles in the array to be nil for :solid it sets all tiles to nil for solid.
Please look at the ascii-draw routine which draws the Dungeon to the terminal. This will show that the tiles are all getting set to non solid.
The Dungeon class is pretty simple. It consists of a 2D array of Tile structs.
The tiles can be either solid of not solid.
My problem comes with the carve-room function.
Instead of just setting the desired Tiles in the array to be nil for :solid it sets all tiles to nil for solid.
Please look at the ascii-draw routine which draws the Dungeon to the terminal. This will show that the tiles are all getting set to non solid.
Code: Select all
;;;; Dungeon class
(defstruct Tile (solid t))
(defclass Dungeon ()
((width :accessor Dungeon-width
:initarg :width
:initform nil)
(height :accessor Dungeon-height
:initarg :height
:initform nil)
(tile-array :accessor Dungeon-tile-array
:initarg :tile-array
:initform (make-Tile))))
;;; Methods for Dungeon
(defmethod make-floor ((d Dungeon))
"Creates a solid uncarved floor for the Dungeon"
(setf (Dungeon-tile-array d) (make-array `(,(Dungeon-width d)
,(Dungeon-height d))
:initial-element
(make-Tile :solid t))))
(defmethod carve-room ((d Dungeon) x y width height)
"Carves a room out of the floor if it fits"
(and (>= x 0)
(>= y 0)
(>= width 1)
(>= height 1)
(<= (+ x width) (Dungeon-width d))
(<= (+ y height) (Dungeon-height d))
(dotimes (xx width)
(dotimes (yy height)
(setf (Tile-solid (aref (Dungeon-tile-array d)
(+ x xx)
(+ y yy))) nil)))))
;;; Testing here
(defmethod ascii-print ((d Dungeon))
(dotimes (y (Dungeon-height d))
(dotimes (x (Dungeon-width d))
(if (Tile-solid (aref (Dungeon-tile-array d) x y))
(princ "x")
(princ ".")))
(terpri)))
(defparameter *d* (make-instance 'Dungeon :width 10 :height 10))
(make-floor *d*)
(carve-room *d* 1 1 4 4)
(ascii-print *d*)