diff options
author | Darren Bane <dbane@tilde.institute> | 2020-05-02 13:27:08 -0400 |
---|---|---|
committer | Darren Bane <dbane@tilde.institute> | 2020-05-02 13:27:08 -0400 |
commit | 1e64fdf07c45e0380f759589b7669bb9bf88fea0 (patch) | |
tree | 6e1c1837a8fa7a9ae0d5ec8a1fc087ca24567426 /crpg.lisp | |
download | lsp-1e64fdf07c45e0380f759589b7669bb9bf88fea0.tar.gz |
Switched to using git, even though its only hobby programming
Diffstat (limited to 'crpg.lisp')
-rwxr-xr-x | crpg.lisp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/crpg.lisp b/crpg.lisp new file mode 100755 index 0000000..10f40d3 --- /dev/null +++ b/crpg.lisp @@ -0,0 +1,197 @@ +#!/usr/local/bin/clisp +(load "cscreen") +(require "cscreen") +(defpackage #:crpg + (:use #:common-lisp #:cscreen) + (:export + #:main)) +(in-package #:crpg) +(defclass <location> () ((row :initarg r :accessor row) + (col :initarg c :accessor col))) +(defmethod print-object ((obj <location>) 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)) +(defconstant +move-err+ "You cannot move in that direction!") +(defconstant +press-key+ "Press Enter to continue.") +(defconstant +exit+ (make-instance (find-class '<location>) + '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 <monster> () ((name :initarg n :reader name) + (attack :initarg a :reader attack) + (health :initarg h :accessor health))) +(defmethod print-object ((obj <monster>) stream) + (format stream "~A" (name obj))) +(defun create-monster (n a h) + (make-instance (find-class '<monster>) 'n n 'a a 'h h)) +(defconstant +monsters+ + (vector + (create-monster "blind bat" 2 1) + (create-monster "rat" 1 1) + (create-monster "snake" 3 1) + (create-monster "goblin" 2 3) + (create-monster "troll" 4 4) + (create-monster "bear" 5 5) + (create-monster "lion" 5 4) + (create-monster "sabretooth" 6 5) + (create-monster "elephant" 7 8) + (create-monster "dragon" 9 8))) +(defclass <item> () ((name :initarg n :reader name) + (class :initarg c :reader class) + (val :initarg v :reader val))) +(defun create-item (n c v) + (make-instance (find-class '<item>) 'n n 'c c 'v v)) +(defconstant +items+ + (vector + (create-item "apple" 'food 1) + (create-item "bread" 'food 2) + (create-item "chicken" 'food 3))) +(defgeneric copy (obj)) +(defmethod copy ((obj <monster>)) + (create-monster (name obj) (attack obj) (health obj))) +(defvar *curr-monster*) +(defvar *monster-gold*) +(defun my-print (x) + (format *standard-output* "~A~%" x)) +(defun print-help () + (cursor 14 1) + (my-print "Commands: n - north") + (my-print " s - south") + (my-print " e - east") + (my-print " w - west") + (my-print " a - attack") + (my-print " x - use exit") + (write-char #\newline) + (my-print " q - quit")) +(defgeneric move (loc dir)) +(defmethod move ((loc <location>) dir) + (case dir + ((n) (if (= (row loc) 1) + (my-print +move-err+) + (progn (setf (row loc) (- (row loc) 1)) + (my-print "You go north.")))) + ((s) (if (= (row loc) 10) + (my-print +move-err+) + (progn (setf (row loc) (+ (row loc) 1)) + (my-print "You go south.")))) + ((w) (if (= (col loc) 1) + (my-print +move-err+) + (progn (setf (col loc) (- (col loc) 1)) + (my-print "You go west.")))) + ((e) (if (= (col loc) 10) + (my-print +move-err+) + (progn (setf (col loc) (+ (col loc) 1)) + (my-print "You go east.")))) + (t (error "bad dir")))) +(defgeneric loc= (l r)) +(defmethod loc= ((l <location>) (r <location>)) + (and (= (row l) (row r)) (= (col l) (col r)))) +(defun handle-cmd (cmd) + (cond + ((string= cmd "n") + (move *curr-loc* 'n)) + ((string= cmd "s") + (move *curr-loc* 's)) + ((string= cmd "w") + (move *curr-loc* 'w)) + ((string= cmd "e") + (move *curr-loc* 'e)) + ((string= cmd "x") + (if (loc= *curr-loc* +exit+) + (if (< *gold* 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)) + do (cursor 10 1) (clrtoeol) + (cursor 11 1) (clrtoeol) + (cursor 12 1) (clrtoeol) + (cursor 10 1) + (let ((attack (+ *weapon* (random 9))) + (monster-attack (attack *curr-monster*))) + (cond + ((= attack monster-attack) + (my-print "No one wins this round.")) + ((> attack monster-attack) + (format *standard-output* "You deal the ~A a blow!~%" (name *curr-monster*)) + (setf (health *curr-monster*) (- (health *curr-monster*) 1))) + ((< attack monster-attack) + (my-print "You have been wounded!") + (setq *health* (- *health* 1)))) + (my-print +press-key+) + (read-line))) + (cursor 10 1) + (if (> *health* 0) + (progn (my-print "You won the fight!") + (format *standard-output* "You found ~A pieces of gold!~%" *monster-gold*) + (setq *gold* (+ *gold* *monster-gold*)) + (setq *curr-monster* nil) + (setf (aref *monster* (row *curr-loc*) (col *curr-loc*)) 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 "q") + (my-print "Bye!") + (throw 'quit nil)))) +(defun get-next-cmd () + (cursor 8 1) + (my-print "What now") + (let ((reply (read-line))) + (cursor 10 1) + (clrtoeol) + reply)) +(defun main-loop () + (loop + (cursor 1 1) + (format *standard-output* "Your position: ~A~%" *curr-loc*) + (cursor 1 25) + (format *standard-output* "Gold: ~A Health: ~A~%" *gold* *health*) + (cursor 2 1) + (if (loc= *curr-loc* +exit+) + (my-print "You are at the exit!") + (clrtoeol)) + (cursor 3 1) + (clrtoeol) + (let ((monster-type (aref *monster* (row *curr-loc*) (col *curr-loc*)))) + (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)))))) + (handle-cmd (get-next-cmd)))) +(defun init () + (page) + (setq *random-state* (make-random-state t)) + (do ((row 1 (+ row 1))) + ((>= row 10)) + (do ((col 1 (+ col 1))) + ((>= col 10)) + (let ((rnd (random 11))) + (if (/= rnd 0) + (setf (aref *monster* row col) (- rnd 1)))))) + + (do ((row 1 (+ row 1))) + )) +(defun main () + (init) + (print-help) + (catch 'quit (main-loop))) +(provide "crpg") +(crpg:main) |