-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* From the book "The Land of Lisp".
- Loading branch information
Showing
4 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
; Game engine functions | ||
|
||
;; Helpers | ||
(defun randval (n) | ||
(1+ (random (max 1 n)))) | ||
|
||
(defun pick-monster () | ||
(fresh-line) | ||
(princ "Monster #: ") | ||
(let ((x (read))) | ||
(if (not (and (integerp x) (>= x 1) (<= x *monsters-num*))) | ||
(progn (princ "That is not a valid monster number.") | ||
(pick-monster)) | ||
(let ((m (aref *monsters* (1- x)))) | ||
(if (monster-dead m) | ||
(progn (princ "That monster is alread dead.") | ||
(pick-monster)) | ||
m))))) | ||
|
||
(defun random-monster () | ||
(let ((m (aref *monsters* (random (length *monsters*))))) | ||
(if (monster-dead m) | ||
(random-monster) | ||
m))) | ||
|
||
;; Player management functions | ||
(defun init-player () | ||
(setf *player-health* 30) | ||
(setf *player-agility* 30) | ||
(setf *player-strength* 30)) | ||
|
||
(defun player-dead () | ||
(<= *player-health* 0)) | ||
|
||
(defun show-player () | ||
(fresh-line) | ||
(princ "You are a valiant kinght with a health of ") | ||
(princ *player-health*) | ||
(princ ", an agility of ") | ||
(princ *player-agility*) | ||
(princ ", and a strength of ") | ||
(princ *player-strength*)) | ||
|
||
(defun player-attack () | ||
(fresh-line) | ||
(princ "Attack style: [s]tab [d]ouble swing [r]oundhouse: ") | ||
(case (read) | ||
(s (player-stab-attack)) | ||
(d (player-double-swing-attack)) | ||
(otherwise (player-roundhouse-attack)))) | ||
|
||
(defun player-stab-attack () | ||
(monster-hit (pick-monster) (+ 2 (randval (ash *player-strength* -1))))) | ||
|
||
(defun player-double-swing-attack () | ||
(let ((x (randval (truncate (/ *player-strength* 6))))) | ||
(princ "Your double swing has a strength of ") | ||
(princ x) | ||
(fresh-line) | ||
(monster-hit (pick-monster) x) | ||
(unless (monsters-dead) | ||
(monster-hit (pick-monster) x)))) | ||
|
||
(defun player-roundhouse-attack () | ||
(dotimes (x (1+ (randval (truncate (/ *player-strength* 3))))) | ||
(unless (monsters-dead) | ||
(monster-hit (random-monster) 1)))) | ||
|
||
;; Monsters management functions | ||
(defun init-monsters () | ||
(setf *monsters* | ||
(map 'vector (lambda (x) | ||
(funcall (nth (random (length *monsters-builders*)) | ||
*monsters-builders*))) | ||
(make-array *monsters-num*)))) | ||
|
||
(defun monster-dead (m) | ||
(<= (monster-health m) 0)) | ||
|
||
(defun monsters-dead () | ||
(every #'monster-dead *monsters*)) | ||
|
||
(defun show-monsters () | ||
(fresh-line) | ||
(princ "Your foes:") | ||
(let ((x 0)) | ||
(map 'list | ||
(lambda (m) | ||
(fresh-line) | ||
(princ " ") | ||
(princ (incf x)) | ||
(princ ". ") | ||
(if (monster-dead m) | ||
(princ "** dead **") | ||
(progn (princ "(Health=") | ||
(princ (monster-health m)) | ||
(princ ") ") | ||
(monster-show m)))) | ||
*monsters*))) | ||
|
||
;; Main loop | ||
(defun game-loop () | ||
(unless (or (player-dead) (monsters-dead)) | ||
(show-player) | ||
(dotimes (k (1+ (truncate (/ (max 0 *player-agility*) 15)))) | ||
(unless (monsters-dead) | ||
(show-monsters) | ||
(player-attack))) | ||
(fresh-line) | ||
(map 'list (lambda (m) | ||
(or (monster-dead m) (monster-attack m))) | ||
*monsters*) | ||
(game-loop))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
; Game environment | ||
(defparameter *player-health* nil) | ||
(defparameter *player-agility* nil) | ||
(defparameter *player-strength* nil) | ||
|
||
(defparameter *monsters* nil) | ||
(defparameter *monsters-builders* nil) | ||
(defparameter *monsters-num* 12) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
; Orc Battle | ||
|
||
(load 'environment) | ||
(load 'structs) | ||
(load 'engine) | ||
|
||
; Main function | ||
(defun orc-battle () | ||
(init-monsters) | ||
(init-player) | ||
(game-loop) | ||
(when (player-dead) | ||
(princ "You have been killed. Game over.")) | ||
(when (monsters-dead) | ||
(princ "Congratulations! You have vanquished all of your foes. You win!"))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
; Monsters | ||
;; Generic | ||
(defstruct monster (health (randval 10))) | ||
|
||
(defmethod monster-hit (m x) | ||
(decf (monster-health m) x) | ||
(if (monster-dead m) | ||
(progn (princ "You killed the ") | ||
(princ (type-of m)) | ||
(princ "! ")) | ||
(progn (princ "You hit the ") | ||
(princ (type-of m)) | ||
(princ ", knocking off ") | ||
(princ x) | ||
(princ " health points.")))) | ||
|
||
(defmethod monster-show (m) | ||
(princ "A fierce ") | ||
(princ (type-of m))) | ||
|
||
(defmethod monster-attack (m)) | ||
|
||
;; Orc | ||
(defstruct (orc (:include monster)) (club-level (randval 8))) | ||
(push #'make-orc *monsters-builders*) | ||
|
||
(defmethod monster-show ((m orc)) | ||
(princ "A wicked orc with a level ") | ||
(princ (orc-club-level m)) | ||
(princ " club.")) | ||
|
||
(defmethod monster-attack ((m orc)) | ||
(let ((x (randval (orc-club-level m)))) | ||
(princ "An orc swings his club at you and knocks off ") | ||
(princ x) | ||
(princ " of your health points. ") | ||
(decf *player-health* x))) | ||
|
||
;; Hydra | ||
(defstruct (hydra (:include monster))) | ||
(push #'make-hydra *monsters-builders*) | ||
|
||
(defmethod monster-show ((m hydra)) | ||
(princ "A malicious hydra with ") | ||
(princ (monster-health m)) | ||
(princ " heads.")) | ||
|
||
(defmethod monster-hit ((m hydra) x) | ||
(decf (monster-health m) x) | ||
(if (monster-dead m) | ||
(princ "The corpse of the fully decapitated and decapacitated hydra falls to the floor!.") | ||
(progn (princ "You lop off ") | ||
(princ x) | ||
(princ " of the hydra's heads!")))) | ||
|
||
(defmethod monster-attack ((m hydra)) | ||
(let ((x (randval (ash (monster-health m) -1)))) | ||
(princ "A hydra attack you with ") | ||
(princ x) | ||
(princ " of its heads! It also grows back one more head! ") | ||
(incf (monster-health m)) | ||
(decf *player-health* x))) | ||
|
||
;; Slime Mold | ||
(defstruct (slime-mold (:include monster)) (sliminess (randval 5))) | ||
(push #'make-slime-mold *monsters-builders*) | ||
|
||
(defmethod monster-show ((m slime-mold)) | ||
(princ "A slime mold with sliminess of ") | ||
(princ (slime-mold-sliminess m))) | ||
|
||
(defmethod monster-attack ((m slime-mold)) | ||
(let ((x (randval (slime-mold-sliminess m)))) | ||
(princ "A slime mold wraps around your legs and decreases your agility by ") | ||
(princ x) | ||
(princ "! ") | ||
(decf *player-agility* x) | ||
(when (zerop (random 2)) | ||
(princ "It also squirts in your face, taking away a health point! ") | ||
(decf *player-health*)))) | ||
|
||
;; Cunning Brigand | ||
(defstruct (brigand (:include monster))) | ||
(push #'make-brigand *monsters-builders*) | ||
|
||
(defmethod monster-attack ((m brigand)) | ||
(let ((x (max *player-health* *player-agility* *player-strength*))) | ||
(cond ((= x *player-health*) | ||
(princ "A brigand hits you with his slingshot, taking off 2 health points! ") | ||
(decf *player-health* 2)) | ||
((= x *player-agility*) | ||
(princ "A brigand catches your leg with his whip, taking off 2 agility points! ") | ||
(decf *player-agility* 2)) | ||
((= x *player-strength*) | ||
(princ "A brigand cuts your arm with his whip, taking off 2 strength points! ") | ||
(decf *player-strength* 2))))) |