diff options
author | Darren Bane <dbane@tilde.institute> | 2020-05-02 19:59:21 -0400 |
---|---|---|
committer | Darren Bane <dbane@tilde.institute> | 2020-05-02 19:59:21 -0400 |
commit | bc19dfeb20194b1369bf9698b9eb11587fa5cd28 (patch) | |
tree | dca67cff2298407bc1c2e2c9b82a87ed90b91f37 | |
parent | 1e64fdf07c45e0380f759589b7669bb9bf88fea0 (diff) | |
download | lsp-bc19dfeb20194b1369bf9698b9eb11587fa5cd28.tar.gz |
Code complete, but needs to be tested
-rwxr-xr-x | crpg.lisp | 172 |
1 files changed, 118 insertions, 54 deletions
diff --git a/crpg.lisp b/crpg.lisp index 10f40d3..6f37799 100755 --- a/crpg.lisp +++ b/crpg.lisp @@ -6,29 +6,34 @@ (:export #:main)) (in-package #:crpg) -(defclass <location> () ((row :initarg r :accessor row) - (col :initarg c :accessor col))) -(defmethod print-object ((obj <location>) stream) +(defclass <coord> () ((row :initarg r :accessor row) + (col :initarg c :accessor col))) +(defmethod print-object ((obj <coord>) stream) (format stream "~A ~A" (row obj) (col obj))) - -;; TODO: <location-contents> class, or maybe rename the other one to <coord> -(defvar *monster* (make-array '(10 10))) -(defvar *item* (make-array '(10 10))) - -(defvar *curr-loc* (make-instance (find-class '<location>) 'r 5 'c 5)) +(defclass <location> () ((monster :initarg m :accessor monster) + (item :initarg i :accessor item))) +(defmethod initialize-instance :after ((self <location>) &key) + (setf (monster self) nil) + (setf (item self) nil)) +(defvar *map* (make-array '(10 10))) +(defvar *curr-coord* (make-instance (find-class '<coord>) 'r 5 'c 5)) (defconstant +move-err+ "You cannot move in that direction!") (defconstant +press-key+ "Press Enter to continue.") -(defconstant +exit+ (make-instance (find-class '<location>) +(defconstant +exit+ (make-instance (find-class '<coord>) 'r (+ (random 10) 1) 'c (+ (random 10) 1))) ;; (format *standard-output* "~A~%" +exit+) ;; (sleep 3) - -;; TODO: <player> class? -(defvar *gold* 0) -(defvar *health* 20) -(defvar *weapon* 1) - +(defclass <player> () ((gold :accessor gold) + (health :accessor health) + (weapon :accessor weapon))) +(defmethod initialize-instance :after ((self <player>) &key) + (setf (gold self) 0) + (setf (health self) 20) + (setf (weapon self) 1)) +(defmethod print-object ((obj <player>) stream) + (format stream "Gold: ~A Health: ~A Weapon: ~A~%" (gold obj) (health obj) (weapon obj))) +(defvar *the-player* (make-instance (find-class '<player>))) (defclass <monster> () ((name :initarg n :reader name) (attack :initarg a :reader attack) (health :initarg h :accessor health))) @@ -50,19 +55,29 @@ (create-monster "dragon" 9 8))) (defclass <item> () ((name :initarg n :reader name) (class :initarg c :reader class) - (val :initarg v :reader val))) + (value :initarg v :reader value))) +(defclass <food> (<item>) ()) +(defclass <weapon> (<item>) ()) +(defclass <trap> (<item>) ()) (defun create-item (n c v) - (make-instance (find-class '<item>) 'n n 'c c 'v v)) + (make-instance (find-class c) 'n n 'v v)) (defconstant +items+ (vector - (create-item "apple" 'food 1) - (create-item "bread" 'food 2) - (create-item "chicken" 'food 3))) + (create-item "apple" '<food> 1) + (create-item "bread" '<food> 2) + (create-item "chicken" '<food> 3) + (create-item "dagger" '<weapon> 2) + (create-item "sword" '<weapon> 3) + (create-item "halberd" '<weapon> 4) + (create-item "smoke" '<trap> 1) + (create-item "noose trap" '<trap> 2) + (create-item "pit trap" '<trap> 3))) (defgeneric copy (obj)) (defmethod copy ((obj <monster>)) (create-monster (name obj) (attack obj) (health obj))) (defvar *curr-monster*) (defvar *monster-gold*) +(defvar *curr-item*) (defun my-print (x) (format *standard-output* "~A~%" x)) (defun print-help () @@ -72,56 +87,65 @@ (my-print " e - east") (my-print " w - west") (my-print " a - attack") + (my-print " t - take item") (my-print " x - use exit") (write-char #\newline) - (my-print " q - quit")) -(defgeneric move (loc dir)) -(defmethod move ((loc <location>) dir) + (my-print " q - quit") + (cursor 14 40) + (format *standard-output* "+~A+~%" (make-string 10 :initial-element #\-)) + (cursor 15 40) + (format *standard-output* "|~A|~%" (make-string 10 :initial-element #\space)) + (cursor 16 40) + (format *standard-output* "+~A+~%" (make-string 10 :initial-element #\-)) + (cursor 17 44) + (my-print "ITEM")) +(defgeneric move (coord dir)) +(defmethod move ((coord <coord>) dir) (case dir - ((n) (if (= (row loc) 1) + ((n) (if (= (row coord) 1) (my-print +move-err+) - (progn (setf (row loc) (- (row loc) 1)) + (progn (setf (row coord) (- (row coord) 1)) (my-print "You go north.")))) - ((s) (if (= (row loc) 10) + ((s) (if (= (row coord) 10) (my-print +move-err+) - (progn (setf (row loc) (+ (row loc) 1)) + (progn (setf (row coord) (+ (row coord) 1)) (my-print "You go south.")))) - ((w) (if (= (col loc) 1) + ((w) (if (= (col coord) 1) (my-print +move-err+) - (progn (setf (col loc) (- (col loc) 1)) + (progn (setf (col coord) (- (col coord) 1)) (my-print "You go west.")))) - ((e) (if (= (col loc) 10) + ((e) (if (= (col coord) 10) (my-print +move-err+) - (progn (setf (col loc) (+ (col loc) 1)) + (progn (setf (col coord) (+ (col coord) 1)) (my-print "You go east.")))) (t (error "bad dir")))) -(defgeneric loc= (l r)) -(defmethod loc= ((l <location>) (r <location>)) +(defgeneric coord= (l r)) +(defmethod coord= ((l <coord>) (r <coord>)) (and (= (row l) (row r)) (= (col l) (col r)))) (defun handle-cmd (cmd) (cond ((string= cmd "n") - (move *curr-loc* 'n)) + (move *curr-coord* 'n)) ((string= cmd "s") - (move *curr-loc* 's)) + (move *curr-coord* 's)) ((string= cmd "w") - (move *curr-loc* 'w)) + (move *curr-coord* 'w)) ((string= cmd "e") - (move *curr-loc* 'e)) + (move *curr-coord* 'e)) ((string= cmd "x") - (if (loc= *curr-loc* +exit+) - (if (< *gold* 100) + (if (coord= *curr-coord* +exit+) + (if (< (gold *the-player*) 100) (my-print "You dont have enough gold!") (my-print "You have escaped! Well done!")))) ((string= cmd "a") (if (null *curr-monster*) (my-print "There's nothing to attack!") - (progn (loop while (and (> (health *curr-monster*) 0) (> *health* 0)) + (progn (loop while (and (> (health *curr-monster*) 0) (> (health *the-player*) 0)) do (cursor 10 1) (clrtoeol) (cursor 11 1) (clrtoeol) (cursor 12 1) (clrtoeol) (cursor 10 1) - (let ((attack (+ *weapon* (random 9))) + (let ((attack (+ (weapon *the-player*) (random 9))) (monster-attack (attack *curr-monster*))) (cond ((= attack monster-attack) @@ -131,21 +155,45 @@ (setf (health *curr-monster*) (- (health *curr-monster*) 1))) ((< attack monster-attack) (my-print "You have been wounded!") - (setq *health* (- *health* 1)))) + (setf (health *the-player*) (- (health *the-player*) 1)))) (my-print +press-key+) (read-line))) (cursor 10 1) - (if (> *health* 0) + (if (> (health *the-player*) 0) (progn (my-print "You won the fight!") (format *standard-output* "You found ~A pieces of gold!~%" *monster-gold*) - (setq *gold* (+ *gold* *monster-gold*)) + (setf (gold *the-player*) (+ (gold *the-player*) *monster-gold*)) (setq *curr-monster* nil) - (setf (aref *monster* (row *curr-loc*) (col *curr-loc*)) nil) + (setf (monster (aref *map* (row *curr-coord*) (col *curr-coord*))) nil) (my-print +press-key+) (read-line)) (progn (format *standard-output* "The ~A killed you!~%" (name *curr-monster*)) (my-print "Game over!") (throw 'quit nil)))))) + ((string= cmd "t") + (if (null *curr-item*) + (progn (cursor 10 1) + (my-print "Nothing to take!") + (my-print +press-key+) + (read-line)) + (progn (case (class-of *curr-item*) + ((find-class '<food>) + (cursor 10 1) + (format *standard-output* "You eat the ~A.~%" (name *curr-item*)) + (if (>= (health *the-player*) 20) + (my-print "You had no wounds, so the food is wasted.~%") + (progn (setf (health *the-player*) (+ (health *the-player*) (value *curr-item*))) + (format *standard-output* "You gain ~A health points ~%" (value *curr-item*))))) + ((find-class '<weapon>) + (cursor 10 1) + (if (>= (weapon *the-player*) (value *curr-item*)) + (my-print "You have a similar or better weapon.") + (progn (format *standard-output* "You pick up a ~A!") + (setf (weapon *the-player*) (value *curr-item*)) + (format *standard-output* "Your weapon rating is now ~A.~%" (weapon *the-player)))))) + (my-print +press-key+) + (read-line) + (setf (item (aref *map* (row *curr-coord*) (col *curr-coord))) nil)))) ((string= cmd "q") (my-print "Bye!") (throw 'quit nil)))) @@ -159,22 +207,38 @@ (defun main-loop () (loop (cursor 1 1) - (format *standard-output* "Your position: ~A~%" *curr-loc*) + (format *standard-output* "Your position: ~A~%" *curr-coord*) (cursor 1 25) - (format *standard-output* "Gold: ~A Health: ~A~%" *gold* *health*) + (format *standard-output* "~A~%" *the-player*) (cursor 2 1) - (if (loc= *curr-loc* +exit+) + (if (coord= *curr-coord* +exit+) (my-print "You are at the exit!") (clrtoeol)) (cursor 3 1) (clrtoeol) - (let ((monster-type (aref *monster* (row *curr-loc*) (col *curr-loc*)))) + (let ((monster-type (monster (aref *map* (row *curr-coord*) (col *curr-coord*))))) (if (null monster-type) (progn (setq *curr-monster* nil) (setq *monster-gold* 0)) (progn (setq *curr-monster* (copy (elt +monsters+ monster-type))) (format *standard-output* "Monster: ~A~%" *curr-monster*) (setq *monster-gold* (* monster-type (random 6)))))) + (let ((item-type (item (aref *map* (row *curr-coord*) (col *curr-coord*))))) + (if (null item-type) + (progn (cursor 15 41) + (my-print "nothing")) + (progn (setq *curr-item* (elt +items+ item-type)) + (cursor 15 41) + (my-print (name *curr-item*)) + (if (eq (class-of *curr-item*) (find-class '<trap>)) + (progn (cursor 10 1) + (format *standard-output* "The ~A damages you for ~A points!~%" (name *curr-item*) (value *curr-item*)) + (setf (health *the-player*) (- (health *the-player*) (value *curr-item*))) + (setf (item (aref *map* (row *curr-coord*) (col *curr-coord*))) nil) + (if (<= (health *the-player*) 0) + (progn (my-print "You die!") + (my-print "Game over!") + (throw 'quit nil)))))))) (handle-cmd (get-next-cmd)))) (defun init () (page) @@ -183,12 +247,12 @@ ((>= row 10)) (do ((col 1 (+ col 1))) ((>= col 10)) + (setf (aref *map* row col) (make-instance (find-class '<location>))) (let ((rnd (random 11))) (if (/= rnd 0) - (setf (aref *monster* row col) (- rnd 1)))))) - - (do ((row 1 (+ row 1))) - )) + (setf (monster (aref *map* row col)) (- rnd 1)))) + (if (< (random 1.0) 0.2) + (setf (item (aref *map* row col)) (random 9)))))) (defun main () (init) (print-help) |