~octaspire/crates2

4cefcb1c7af919184724456c5ec4aef1cf5eb651 — octaspire 2 months ago 1064c7e
Add two levels, add option for logging input, fix input on NIL level

  * Add two levels.
  * Add option for logging and echoing user input. This can be
    used, for example, to record the steps needed for passing a level.
    When the option is given, the recorded steps are printed on
    the standard output when the game is quit. This output can
    be used as fake input for test runs.
  * Do not read input if the current level is NIL.
3 files changed, 472 insertions(+), 29 deletions(-)

M src/levels.lisp
M src/main.lisp
M src/textual.lisp
M src/levels.lisp => src/levels.lisp +430 -2
@@ 14,7 14,7 @@
;; limitations under the License.
(in-package :crates2)

(defparameter *num-levels* 22)
(defparameter *num-levels* 24)

(defun load-level (index)
  (ecase index


@@ 813,5 813,433 @@
                    (make-instance 'stepper :x 13  :y 9 :z -1)
                    (make-instance 'stepper :x 13  :y 10 :z -1)
                    (make-instance 'stepper :x 13  :y 11 :z -1)
                    (make-instance 'stepper :x 13  :y 12 :z -1))))))
                    (make-instance 'stepper :x 13  :y 12 :z -1))))
    (22 (list (list nil nil
                    :west nil nil nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil
                    :west nil nil nil nil nil nil nil
                    :east nil nil nil nil nil nil nil
                    :north nil nil nil
                    :west nil nil nil nil nil nil nil
                    :south nil nil nil
                    :west nil nil
                    :north nil nil
                    :west nil
                    :east nil nil nil nil nil nil
                    :north nil nil nil nil
                    :west nil nil nil
                    :south nil nil nil nil nil nil nil
                    :south nil
                    :north nil nil nil nil nil nil nil
                    :east nil nil nil
                    :south nil nil nil nil nil nil nil
                    :west nil nil nil
                    :north nil nil nil nil nil
                    :west nil nil nil
                    :south nil nil nil
                    :west nil nil
                    :north nil nil
                    :west nil nil
                    :east nil nil nil nil nil
                    :north nil nil
                    :west nil nil nil
                    :south nil nil nil
                    :west nil nil
                    :north nil nil
                    :west nil nil nil
                    :east nil nil nil nil
                    :south nil nil
                    :west nil nil
                    :east nil nil nil nil nil nil
                    :south nil nil nil
                    :west nil nil nil
                    :north nil nil nil nil nil
                    :west nil nil nil
                    :south nil nil nil
                    :west nil nil nil
                    :north nil nil
                    :west nil nil nil nil nil nil nil nil)
              (list (make-instance 'pulled :x 2  :y 2 :z 0 :north t :south t :east t :west t) ; Top pulled line
                    (make-instance 'pulled :x 3  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 2 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 3 :z 0 :north t :south t :east t :west t) ; Second pulled line
                    (make-instance 'pulled :x 3  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 4 :z 0 :north t :south t :east t :west t) ; Third pulled line
                    (make-instance 'pulled :x 3  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 5 :z 0 :north t :south t :east t :west t) ; Fourth pulled line
                    (make-instance 'pulled :x 3  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 6 :z 0 :north t :south t :east t :west t) ; Fifth pulled line (3 empty)
                    (make-instance 'pulled :x 3  :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 6 :z 0 :north t :south t :east t :west t)
                    ;; Three empty
                    (make-instance 'pulled :x 11 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 7 :z 0 :north t :south t :east t :west t) ; Sixth pulled line (5 empty)
                    (make-instance 'pulled :x 3  :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 7 :z 0 :north t :south t :east t :west t)
                    ;; Five empty
                    (make-instance 'pulled :x 12 :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 8 :z 0 :north t :south t :east t :west t) ; Seventh pulled line (7 empty)
                    (make-instance 'pulled :x 3  :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 8 :z 0 :north t :south t :east t :west t)
                    ;; Seven empty
                    (make-instance 'pulled :x 13 :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 9 :z 0 :north t :south t :east t :west t) ; Eight pulled line (7 empty) player's line
                    (make-instance 'pulled :x 3  :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 9 :z 0 :north t :south t :east t :west t)
                    ;; Seven empty
                    (make-instance 'pulled :x 13 :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 10 :z 0 :north t :south t :east t :west t) ; Ninth pulled line (7 empty)
                    (make-instance 'pulled :x 3  :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 10 :z 0 :north t :south t :east t :west t)
                    ;; Seven empty
                    (make-instance 'pulled :x 13 :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 10 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 11 :z 0 :north t :south t :east t :west t) ; Tenth pulled line (5 empty)
                    (make-instance 'pulled :x 3  :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 11 :z 0 :north t :south t :east t :west t)
                    ;; Five empty
                    (make-instance 'pulled :x 12 :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 11 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 12 :z 0 :north t :south t :east t :west t) ; Eleventh pulled line (3 empty)
                    (make-instance 'pulled :x 3  :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 12 :z 0 :north t :south t :east t :west t)
                    ;; Three empty
                    (make-instance 'pulled :x 11 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 12 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 13 :z 0 :north t :south t :east t :west t) ; Third to last pulled line
                    (make-instance 'pulled :x 3  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 13 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 14 :z 0 :north t :south t :east t :west t) ; Second to last pulled line
                    (make-instance 'pulled :x 3  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 14 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 2  :y 15 :z 0 :north t :south t :east t :west t) ; Last pulled line
                    (make-instance 'pulled :x 3  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 4  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 5  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9  :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 11 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 12 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 13 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 14 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 15 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 16 :y 15 :z 0 :north t :south t :east t :west t)
                    (make-instance 'exit   :x 9  :y 0 :z 0)
                    (make-instance 'exit   :x 0  :y 9 :z 0)
                    (make-instance 'exit   :x 18 :y 9 :z 0)
                    (make-instance 'exit   :x 9  :y 18 :z 0)
                    (make-instance 'player :x 9  :y 9 :z 0))))
    (23 (list (list nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil nil nil nil nil
                    :south nil nil nil nil nil nil
                    :north nil nil nil nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil nil
                    :east nil nil nil nil nil
                    :south nil nil nil
                    :west nil nil nil
                    :east nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :west nil nil nil nil nil
                    :east nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil
                    :south nil
                    :north nil nil
                    :west nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil
                    :west nil nil nil nil nil nil nil nil nil
                    :south nil nil nil nil nil nil nil
                    :east nil nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :south nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil nil nil nil nil nil
                    :south nil nil nil nil nil nil nil
                    :east nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil nil nil nil nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil
                    :south nil nil
                    :north nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil
                    :west nil nil nil nil nil nil nil nil nil
                    :north nil nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil
                    :south nil nil nil
                    :north nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil
                    :west nil nil nil nil nil nil nil
                    :north nil nil nil
                    :east nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil
                    :south nil nil nil nil
                    :north nil nil nil nil nil
                    :west nil nil nil nil nil nil nil nil nil nil
                    :north nil nil
                    :east nil nil nil nil nil nil nil
                    :south nil nil nil
                    :east nil nil nil
                    :west nil nil nil nil nil
                    :north nil nil nil
                    :east nil nil nil
                    :south nil nil nil
                    :east nil nil nil nil
                    :south nil nil nil nil nil
                    :west nil nil nil nil)
              (list (make-instance 'wall   :x 0  :y 0 :z 0) ; Top row
                    (make-instance 'wall   :x 1  :y 0 :z 0)
                    (make-instance 'wall   :x 2  :y 0 :z 0)
                    (make-instance 'wall   :x 3  :y 0 :z 0)
                    (make-instance 'wall   :x 4  :y 0 :z 0)
                    (make-instance 'wall   :x 5  :y 0 :z 0)
                    (make-instance 'wall   :x 6  :y 0 :z 0)
                    (make-instance 'wall   :x 7  :y 0 :z 0)
                    (make-instance 'wall   :x 8  :y 0 :z 0)
                    (make-instance 'wall   :x 0  :y 1 :z 0) ; Second row
                    (make-instance 'player :x 1  :y 1 :z 0)
                    (make-instance 'wall   :x 8  :y 1 :z 0)
                    (make-instance 'wall   :x 9  :y 1 :z 0)
                    (make-instance 'wall   :x 10 :y 1 :z 0)
                    (make-instance 'wall   :x 11 :y 1 :z 0)
                    (make-instance 'wall   :x 12 :y 1 :z 0)
                    (make-instance 'wall   :x 13 :y 1 :z 0)
                    (make-instance 'wall   :x 14 :y 1 :z 0)
                    (make-instance 'wall   :x 15 :y 1 :z 0)
                    (make-instance 'wall   :x 0  :y 2 :z 0) ; Third row
                    (make-instance 'wall   :x 15 :y 2 :z 0)
                    (make-instance 'wall   :x 0  :y 3 :z 0) ; Fourth row
                    (make-instance 'pulled :x 14 :y 3 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 15 :y 3 :z 0)
                    (make-instance 'wall   :x 0  :y 4 :z 0) ; Fifth row
                    (make-instance 'wall   :x 3  :y 4 :z 0)
                    (make-instance 'wall   :x 4  :y 4 :z 0)
                    (make-instance 'pulled :x 5  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7  :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 8  :y 4 :z 0)
                    (make-instance 'wall   :x 9  :y 4 :z 0)
                    (make-instance 'pulled :x 10 :y 4 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 11  :y 4 :z 0)
                    (make-instance 'wall   :x 12  :y 4 :z 0)
                    (make-instance 'wall   :x 15  :y 4 :z 0)
                    (make-instance 'wall   :x 0   :y 5 :z 0) ; Sixth row
                    (make-instance 'wall   :x 3   :y 5 :z 0)
                    (make-instance 'wall   :x 4   :y 5 :z 0)
                    (make-instance 'pulled :x 5   :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6   :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 7   :y 5 :z 0)
                    (make-instance 'wall   :x 8   :y 5 :z 0)
                    (make-instance 'wall   :x 9   :y 5 :z 0)
                    (make-instance 'pulled :x 10  :y 5 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 11   :y 5 :z 0)
                    (make-instance 'wall   :x 12   :y 5 :z 0)
                    (make-instance 'wall   :x 15   :y 5 :z 0)
                    (make-instance 'wall   :x 0    :y 6 :z 0) ; Seventh row
                    (make-instance 'wall   :x 3    :y 6 :z 0)
                    (make-instance 'wall   :x 4    :y 6 :z 0)
                    (make-instance 'pulled :x 5    :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6    :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 7    :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 8    :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 9    :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 10   :y 6 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 11   :y 6 :z 0)
                    (make-instance 'wall   :x 12   :y 6 :z 0)
                    (make-instance 'wall   :x 15   :y 6 :z 0)
                    (make-instance 'wall   :x 0    :y 7 :z 0) ; Eight row
                    (make-instance 'wall   :x 3    :y 7 :z 0)
                    (make-instance 'wall   :x 4    :y 7 :z 0)
                    (make-instance 'pulled :x 5    :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6    :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'exit   :x 8    :y 7 :z 0)
                    (make-instance 'pulled :x 10   :y 7 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 11   :y 7 :z 0)
                    (make-instance 'wall   :x 12   :y 7 :z 0)
                    (make-instance 'wall   :x 15   :y 7 :z 0)
                    (make-instance 'wall   :x 0    :y 8 :z 0) ; Ninth row
                    (make-instance 'wall   :x 3    :y 8 :z 0)
                    (make-instance 'wall   :x 4    :y 8 :z 0)
                    (make-instance 'pulled :x 5    :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'pulled :x 6    :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 7    :y 8 :z 0)
                    (make-instance 'wall   :x 8    :y 8 :z 0)
                    (make-instance 'wall   :x 9    :y 8 :z 0)
                    (make-instance 'pulled :x 10   :y 8 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 11   :y 8 :z 0)
                    (make-instance 'wall   :x 12   :y 8 :z 0)
                    (make-instance 'wall   :x 15   :y 8 :z 0)
                    (make-instance 'wall   :x 0    :y 9 :z 0) ; Tenth row
                    (make-instance 'pulled :x 14   :y 9 :z 0 :north t :south t :east t :west t)
                    (make-instance 'wall   :x 15   :y 9 :z 0)
                    (make-instance 'wall   :x 0    :y 10 :z 0) ; Eleventh row
                    (make-instance 'wall   :x 1    :y 10 :z 0)
                    (make-instance 'wall   :x 15   :y 10 :z 0)
                    (make-instance 'wall   :x 1    :y 11 :z 0) ; Last row
                    (make-instance 'wall   :x 2    :y 11 :z 0)
                    (make-instance 'wall   :x 3    :y 11 :z 0)
                    (make-instance 'wall   :x 4    :y 11 :z 0)
                    (make-instance 'wall   :x 5    :y 11 :z 0)
                    (make-instance 'wall   :x 6    :y 11 :z 0)
                    (make-instance 'wall   :x 7    :y 11 :z 0)
                    (make-instance 'wall   :x 8    :y 11 :z 0)
                    (make-instance 'wall   :x 9    :y 11 :z 0)
                    (make-instance 'wall   :x 10   :y 11 :z 0)
                    (make-instance 'wall   :x 11   :y 11 :z 0)
                    (make-instance 'wall   :x 12   :y 11 :z 0)
                    (make-instance 'wall   :x 13   :y 11 :z 0)
                    (make-instance 'wall   :x 14   :y 11 :z 0)
                    (make-instance 'wall   :x 15   :y 11 :z 0))))))


M src/main.lisp => src/main.lisp +34 -21
@@ 25,9 25,9 @@
(defparameter *running* t)
(defparameter *level* nil)
(defparameter *created* nil)
(defparameter *next-level* 21)
(defparameter *next-level* nil)
(defparameter *level-width* 20)
(defparameter *level-height* 15)
(defparameter *level-height* 20)
(defparameter *frame-duration-default* 0.25) ; Not zeroed in test mode.
(defparameter *frame-duration* *frame-duration-default*) ; Zeroed in test mode.
(defparameter *test-run* nil)


@@ 81,6 81,9 @@ to see what happens."
This is similar to 'test' but runs much slower."
   :long "autoplay"
   :arg-parser #'autoplay-parser)
  (:name :log-input
   :description "Log and show user input after quitting game."
   :long "log-input")
  (:name :fullscreen
   :description "Run in fullscreen mode"
   :long "fullscreen"))


@@ 89,27 92,37 @@ This is similar to 'test' but runs much slower."
  (when (> *verbose* 0)
    (format t fmt args)))

(defun run ()
(defun run (options)
  (unless *errors*
    (init-visual-hash)
    (request-next-level)
    (loop while (and (runningp)
                     (or (not *test-run*)
                         (< *update-counter* *test-run-max-updates*)))
          do (setf *input* nil)
             (ui-render *level*)
             (let ((input (ui-input)))
               (when input
                 (setf *input* (cons input *input*))
                 (case input
                   (:back    (running nil))
                   (:restart (setf *next-level* *level-number*)))))
             (unless *next-level*
               (update *level*))
             (when *next-level*
               (load-next-level))
             (incf *update-counter*)
             (sleep *frame-duration*))))
    (let ((str (make-array 2048 :element-type 'character :fill-pointer 0 :adjustable t))
          (log-input (getf options :log-input)))
      (with-output-to-string (s str)
        (loop while (and (runningp)
                         (or (not *test-run*)
                             (< *update-counter* *test-run-max-updates*)))
              do (setf *input* nil)
                 (ui-render *level*)
                 (let ((input (ui-input)))
                   (when log-input
                     (format s (if (keywordp input) "~%~S " "~S " ) input))
                   (when input
                     (setf *input* (cons input *input*))
                     (case input
                       (:back    (running nil))
                       (:restart (setf *next-level* *level-number*)))))
                 (unless *next-level*
                   (update *level*))
                 (when *next-level*
                   (load-next-level)
                   (when log-input
                     (format s "~%----------LEVEL ~A----------~%" *level-number*)))
                 (incf *update-counter*)
                 (sleep *frame-duration*))
        (setf str (nstring-downcase str))
        (when log-input
          (format t "~%~A~%" str))))))

(defun usage ()
  (opts:describe


@@ 169,4 182,4 @@ This is similar to 'test' but runs much slower."
    (cond-option options
                 (:help (usage))
                 (:version (version))
                 (otherwise (run)))))
                 (otherwise (run options)))))

M src/textual.lisp => src/textual.lisp +8 -6
@@ 190,12 190,14 @@
        (setf *last-input* (ui-read-input)))))

(defun ui-input ()
  (if *test-run*
      (let ((input (car *fake-input*)))
        (setf *fake-input* (cdr *fake-input*))
        (setf *last-input* input)
        input)
      (ui-maybe-read-input)))
  (if *level*
      (if *test-run*
          (let ((input (car *fake-input*)))
            (setf *fake-input* (cdr *fake-input*))
            (setf *last-input* input)
            input)
          (ui-maybe-read-input))
      nil))

(defun x-axis (length)
  (let ((result ""))