From 9d23e66fe8332abc7a1bbd9022f3e58e1133b3fb Mon Sep 17 00:00:00 2001 From: rsiddharth Date: Fri, 3 Jul 2020 15:49:09 -0400 Subject: name directories like the realm repo. --- eight/orc.rkt | 943 ---------------------------------------------------------- 1 file changed, 943 deletions(-) delete mode 100644 eight/orc.rkt (limited to 'eight/orc.rkt') diff --git a/eight/orc.rkt b/eight/orc.rkt deleted file mode 100644 index f00d587..0000000 --- a/eight/orc.rkt +++ /dev/null @@ -1,943 +0,0 @@ -#lang racket - -#| - - From github.com/racket/realm - - With some trivial changes. - - Commit: 973041cb6a5c696b99b79a -|# - -#| - The Orc game - ------------- - - The Orc game is a turn-based battle game between monsters and the player. - - The player encounters a room full of monsters of all kinds, including - orcs, hydras, hydrars, slimes, and brigands. They are ready to attack. It is - the player's task to get rid of the monsters. - - When the game starts up, it is the player's turn, meaning she is given - permission to attack a (randomly chosen number) of times. The player uses - nine keys to play - -- With the four arrow keys the player navigates among the twelve monsters. - -- With "s", "f", "h", and "m" - -- the player can 's'tab a specific monster, - -- the player may 'f'lail at several monsters; - -- the player may 'h'eal herself. - -- the player may 'm'asturbate for a change. - -- the player may 'b'lock to gain armor. - When the player runs out of attacks, all live monsters attack the player. - After that, it is the player's turn again. - - Just in case, the player can end a turn prematurely with "e". - - Play - ---- - - Run and evaluate - (start-game) - This will pop up a window that displays the player's vitals, the orcs and - their basic state, and the game instructions. -|# - - -(require 2htdp/image 2htdp/universe) - -; -; -; -; ;;; ;;; ;;; ;; ;; -; ; ; ; ; ; ; -; ; ; ;; ;;; ;;; ; ; ; ;;;; ;; ;;; ; ;;; ; -; ; ; ;; ;; ;; ; ; ; ; ; ;; ; ; ;; -; ; ; ; ; ; ; ; ; ; ; ; ; ; -; ; ; ; ; ; ; ; ; ; ; ; ; ; -; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; -; ;;; ;;;;; ;;;; ; ; ;;;; ;;;;; ;;;;; ;;; ;; -; -; -; -; - -;; The OrcWorld as Data: -(struct orc-world (player lom attack# target) #:transparent #:mutable) -;; A OrcWorld is a (orc-world Player [listof Monster] Nat Nat) -;; The third field of the world refers to the number of attacks left. -;; The fourth field refers to the position of the next attack target. - -(struct player (health agility strength armor) #:transparent #:mutable) -;; A Player is a (player Nat Nat Nat Nat) -;; The player's fields correspond to hit points, strength, agility, armor. - -(struct monster (image [health #:mutable]) #:transparent) -(struct orc monster (club) #:transparent) -(struct hydra monster () #:transparent) -(struct hydrar monster () #:transparent) -(struct slime monster (sliminess) #:transparent) -(struct brigand monster () #:transparent) -;; A Monster is a (monster Image Nat) -;; (moster i h) is a monster at position i in the list with health h -;; Each monster is equipped with the index number, -;; which is used to identify the current target. -;; -;; An Orc is an (orc Nat Nat Nat) -;; A Slime is a (slime Nat Nat Nat) -;; A Brigrand is a (brigand Nat Nat) -;; A Hydra is a (hydra Nat Nat) -;; A Hydrar is a (hydrar Nat Nat) -;; -;; The four monster types all inherit the id and health fields from monster. -;; Two have additional attributes: -;; -- (orc i h c) means the orc's club has strength c -;; -- (slime i h a) means the slime can reduce the player's agility by a - -;; ----------------------------------------------------------------------------- -;; THE CONSTANTS IN THE WORLD - -;; player attributes -(define MAX-HEALTH 35) -(define MAX-AGILITY 35) -(define MAX-STRENGTH 35) -(define MAX-ARMOR 35) - -;; depending on other player attributes, -;; the game picks the number of attacks, flailing and stabbing damage -(define ATTACKS# 4) -(define STAB-DAMAGE 2) -(define FLAIL-DAMAGE 3) -(define MASTURBATE-DAMAGE 5) -(define HEALING 8) -(define BLOCK 8) - -;; monster attributes -(define MONSTER# 12) -(define PER-ROW 4) -(unless (zero? (remainder MONSTER# PER-ROW)) - (error 'constraint "PER-ROW must divide MONSTER# evenly into rows")) - -(define MONSTER-HEALTH0 9) -(define CLUB-STRENGTH 8) -(define SLIMINESS 5) - -(define HEALTH-DAMAGE -2) -(define AGILITY-DAMAGE -3) -(define STRENGTH-DAMAGE -4) - -;; string constants -(define STRENGTH "strength") -(define AGILITY "agility") -(define HEALTH "health") -(define ARMOR "armor") -(define LOSE "YOU LOSE") -(define WIN "YOU WIN") -(define DEAD "DEAD") -(define REMAINING "Remaining attacks ") -(define INSTRUCTIONS-2 "Select a monster using the arrow keys") -(define INSTRUCTIONS-1 - (string-append "Press S to stab a monster | Press F to Flail wildly " - "| Press H to Heal | Press M to Masturbate")) - -;; graphical constants -(define HEALTH-BAR-HEIGHT 12) -(define HEALTH-BAR-WIDTH 50) - -;; compute constants for image frames -(define ORC (bitmap "graphics/orc.png")) -(define HYDRA (bitmap "graphics/hydra.png")) -(define HYDRAR (bitmap "graphics/hydrar.png")) -(define SLIME (bitmap "graphics/slime.bmp")) -(define BRIGAND (bitmap "graphics/brigand.bmp")) - -(define PIC-LIST (list ORC HYDRA HYDRAR SLIME BRIGAND)) -(define w (apply max (map image-width PIC-LIST))) -(define h (apply max (map image-height PIC-LIST))) - -;; images: player, monsters, constant texts -(define PLAYER-IMAGE (bitmap "graphics/player.bmp")) - -(define FRAME (rectangle w h 'outline 'white)) -(define TARGET (circle (- (/ w 2) 2) 'outline 'blue)) - -(define ORC-IMAGE (overlay ORC FRAME)) -(define HYDRA-IMAGE (overlay HYDRA FRAME)) -(define HYDRAR-IMAGE (overlay HYDRAR FRAME)) -(define SLIME-IMAGE (overlay SLIME FRAME)) -(define BRIGAND-IMAGE (overlay BRIGAND FRAME)) - -(define V-SPACER (rectangle 0 10 "solid" "white")) -(define H-SPACER (rectangle 10 0 "solid" "white")) - -;; fonts & texts & colors -(define AGILITY-COLOR "blue") -(define HEALTH-COLOR "crimson") -(define STRENGTH-COLOR "forest green") -(define ARMOR-COLOR "goldenrod") -(define MONSTER-COLOR "crimson") -(define MESSAGE-COLOR "black") -(define ATTACK-COLOR "crimson") - -(define HEALTH-SIZE (- HEALTH-BAR-HEIGHT 4)) -(define DEAD-TEXT-SIZE (- HEALTH-BAR-HEIGHT 2)) -(define INSTRUCTION-TEXT-SIZE 16) -(define MESSAGES-SIZE 40) - -(define INSTRUCTION-TEXT - (above - (text INSTRUCTIONS-2 (- INSTRUCTION-TEXT-SIZE 2) "blue") - (text INSTRUCTIONS-1 (- INSTRUCTION-TEXT-SIZE 4) "blue"))) - -(define DEAD-TEXT (text DEAD DEAD-TEXT-SIZE "crimson")) - -; -; -; -; ;;; ;;; ; -; ;; ;; -; ;; ;; ;;;; ;;; ;; ;; -; ; ; ; ; ; ; ;; ; -; ; ; ; ;;;;; ; ; ; -; ; ; ; ; ; ; ; -; ; ; ; ;; ; ; ; -; ;;; ;;; ;;; ;; ;;;;; ;;; ;;; -; -; -; -; - -;; Start the game -(define (start-game) - (big-bang (initialize-orc-world) - (on-key player-acts-on-monsters) - (to-draw render-orc-battle) - (stop-when end-of-orc-battle? render-the-end))) - -;; -> OrcWorld -;; creates an orc-world ready for battling orcs -(define (initialize-orc-world) - (define player0 (initialize-player)) - (define lom0 (initialize-monsters)) - (orc-world player0 lom0 (random-number-of-attacks player0) 0)) - -;; OrcWorld Key-Event -> OrcWorld -;; act on key events by the player, if the player has attacks left -(define (player-acts-on-monsters w k) - (cond - [(zero? (orc-world-attack# w)) w] - - [(key=? "s" k) (stab w)] - [(key=? "h" k) (heal w)] - [(key=? "f" k) (flail w)] - [(key=? "m" k) (masturbate w)] - [(key=? "b" k) (block w)] - - [(key=? "right" k) (move-target w +1)] - [(key=? "left" k) (move-target w -1)] - [(key=? "down" k) (move-target w (+ PER-ROW))] - [(key=? "up" k) (move-target w (- PER-ROW))] - - [(key=? "e" k) (end-turn w)] -;; [(key=? "n" k) (initialize-orc-world)] - - [else w]) - (give-monster-turn-if-attack#=0 w) - w) - -;; OrcWorld -> Image -;; renders the orc world -(define (render-orc-battle w) - (render-orc-world w (orc-world-target w) (instructions w))) - -;; OrcWorld -> Boolean -;; is the battle over? i.e., the player lost or all monsters are dead -(define (end-of-orc-battle? w) - (or (win? w) (lose? w))) - -;; OrcWorld -> Image -;; render the final orc world -(define (render-the-end w) - (render-orc-world w #f (message (if (lose? w) LOSE WIN)))) - -;; ----------------------------------------------------------------------------- - -;; WORLD MANAGEMENT -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; -; -; -; ;;;;; ; -; ; ; -; ; ;; ;; ;;; ;;;;; -; ; ;; ; ; ; -; ; ; ; ; ; -; ; ; ; ; ; -; ; ; ; ; ; ; -; ;;;;; ;;; ;;; ;;;;; ;;; -; -; -; -; - -;; -> Player -;; create a player with maximal capabilities -(define (initialize-player) - (player MAX-HEALTH MAX-AGILITY MAX-STRENGTH 0)) - -;; -> [Listof Monster] -;; create a list of random monsters of length MONSTER-NUM, -(define (initialize-monsters) - ;; Nat -> Monster - ;; makes a random monster - (define (create-monster _) - (define health (random+ MONSTER-HEALTH0)) - (case (random 4) - [(0) (orc ORC-IMAGE health (random+ CLUB-STRENGTH))] - [(1) (hydra HYDRA-IMAGE health)] - [(2) (hydrar HYDRAR-IMAGE health)] - [(3) (slime SLIME-IMAGE health (random+ SLIMINESS))] - [(4) (brigand BRIGAND-IMAGE health)] - [else (error "can't happen")])) - (build-list MONSTER# create-monster)) - -;; Player -> Nat -;; compute a feasible number of attacks the player may execute -(define (random-number-of-attacks p) - (random-quotient (player-agility p) - ATTACKS#)) - -; -; -; -; ;;; ;;; ;;;;;; -; ; ; ; ; ; -; ; ; ;;;; ;;; ;;; ; ; ;;; ;;; ;;;; ;; ;; ;;;;; ;;;;; -; ; ; ; ; ; ; ;;; ; ; ; ; ;; ; ; ; ; -; ;;; ;;;;;; ; ; ; ; ; ; ;;;;;; ; ; ; ;;;; -; ; ; ; ; ; ; ; ; ; ; ; ; ; -; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; -; ;;; ;; ;;;;; ; ;;;;;; ;; ;;;;; ;;; ;;; ;;; ;;;;; -; ; -; ;;; -; -; - -;; ----------------------------------------------------------------------------- -;; player actions - -;; OrcWorld Nat -> Void -;; Effect: reduces the target by a given amount -;; > (move-target -;; (orc-world (player 5 5 5) (list (monster 0 2) (monster 1 3)) 1 0) -;; 1) -;; (orc-world (player 5 5 5) (list (monster 0 2) (monster 1 3)) 1 1) -(define (move-target w n) - (set-orc-world-target! w (modulo (+ n (orc-world-target w)) MONSTER#))) - -;; OrcWorld -> Void -;; Effect: ends the player's turn by setting the number of attacks to 0 -(define (end-turn w) - (set-orc-world-attack#! w 0)) - -;; OrcWorld -> Void -;; Effect: reduces the number of remaining attacks for this turn -;; and increases the player's health level -(define (heal w) - (decrease-attack# w) - (player-health+ (orc-world-player w) HEALING)) - -;; OrcWorld -> Void -(define (block w) - (decrease-attack# w) - (player-armor+ (orc-world-player w) BLOCK)) - -;; OrcWorld -> Void -;; Effect: reduces a targeted monster's health -(define (stab w) - (decrease-attack# w) - (define target (current-target w)) - (define damage - (random-quotient (player-strength (orc-world-player w)) - STAB-DAMAGE)) - (damage-monster target damage)) - -;; OrcWorld -> Void -;; Effect: damages a random number of live monsters, -;; determined by strength of the player -;; starting with the currently targeted monster -(define (flail w) - (decrease-attack# w) - (define target (current-target w)) - (define alive (filter monster-alive? (orc-world-lom w))) - (define pick# - (min - (random-quotient (player-strength (orc-world-player w)) - FLAIL-DAMAGE) - (length alive))) - (define getem (cons target (take alive pick#))) - (for-each (lambda (m) (damage-monster m 1)) getem)) - -;; OrcWorld -> Void - -;; Effect: reduces player agility by x and 2x damages a random number -;; of live monsters -(define (masturbate w) - (decrease-attack# w) - (define alive (filter monster-alive? (orc-world-lom w))) - (define x (random-quotient (player-strength (orc-world-player w)) - MASTURBATE-DAMAGE)) - (define pick# (min x (length alive))) - (define getem (take alive pick#)) - (player-agility+ (orc-world-player w) (- x)) - (for-each (lambda (m) (damage-monster m (* 2 x))) getem)) - -;; OrcWorld -> Void -;; Effect: decrease number of remaining attacks -(define (decrease-attack# w) - (set-orc-world-attack#! w (sub1 (orc-world-attack# w)))) - -;; Monster Nat -> Void -;; Effect: reduces the hit-strength of a monster -(define (damage-monster m delta) - (set-monster-health! m (interval- (monster-health m) delta))) - -;; World -> Monster -(define (current-target w) - (list-ref (orc-world-lom w) (orc-world-target w))) - -;; ----------------------------------------------------------------------------- -;; monster action - -;; OrcWorld -> Void -;; if it is the monsters turn, they attack -;; > (orc-world (player 4 4 4) empty 3 3) -;; (orc-world (player 4 4 4) empty 3 3) -(define (give-monster-turn-if-attack#=0 w) - (when (zero? (orc-world-attack# w)) - (define player (orc-world-player w)) - (all-monsters-attack-player player (orc-world-lom w)) - (set-orc-world-attack#! w (random-number-of-attacks player)))) - -;; Player [Listof Monster] -> Void -;; Each monster attacks the player -(define (all-monsters-attack-player player lom) - ;; Monster -> Void - (define (one-monster-attacks-player monster) - (define armor (player-armor player)) - (define block (cond - [(zero? armor) 0] - [else (random+ armor)])) - ;; block buffers the damage - (define (damage d) - (+ d block)) - ;; reduce player's armor by block - (player-armor+ player (* -1 block)) - (cond - [(orc? monster) - (player-health+ player (damage (random- (orc-club monster))))] - [(hydra? monster) - (player-health+ player (damage (random- (monster-health monster))))] - [(hydrar? monster) - (player-health+ player (random- (monster-health monster)))] - [(slime? monster) - (player-health+ player (damage -1)) - (player-agility+ player (damage (random- (slime-sliminess monster))))] - [(brigand? monster) - (case (random 3) - [(0) (player-health+ player (damage HEALTH-DAMAGE))] - [(1) (player-agility+ player (damage AGILITY-DAMAGE))] - [(2) (player-strength+ player (damage STRENGTH-DAMAGE))])])) - ;; -- IN -- - (for-each one-monster-attacks-player (filter monster-alive? lom))) - -;; ----------------------------------------------------------------------------- -;; actions on player - -;; [Player -> Nat] [Player Nat -> Void] Nat -> Player Nat -> Void -;; effect: change player's selector attribute by adding delta, but max out -(define (player-update! setter selector max-value) - (lambda (player delta) - (setter player - (interval+ (selector player) delta max-value)))) - -;; Player Nat -> Void -(define player-health+ - (player-update! set-player-health! player-health MAX-HEALTH)) - -;; Player Nat -> Void -(define player-agility+ - (player-update! set-player-agility! player-agility MAX-AGILITY)) - -;; Player Nat -> Void -(define player-strength+ - (player-update! set-player-strength! player-strength MAX-STRENGTH)) - -;; Player Nat -> Void -(define player-armor+ - (player-update! set-player-armor! player-armor MAX-ARMOR)) - -; -; -; -; ;;;;; ;; ; -; ; ; ; -; ; ; ;;;; ;; ;; ;;; ; ;;;; ;; ;;; ;;; ;; ;; ;;; ;; -; ; ; ; ; ;; ; ; ;; ; ; ;; ; ;; ; ; ;; -; ;;;; ;;;;;; ; ; ; ; ;;;;;; ; ; ; ; ; ; -; ; ; ; ; ; ; ; ; ; ; ; ; ; ; -; ; ; ; ; ; ; ;; ; ; ; ; ; ; ;; -; ;;; ; ;;;;; ;;; ;;; ;;; ;; ;;;;; ;;;;; ;;;;; ;;; ;;; ;;; ; -; ; -; ;;;; -; -; - -;; OrcWorld Boolean Image -> Image -;; draws all the monsters and the player, then adds message -(define (render-orc-world w with-target additional-text) - (define i-player (render-player (orc-world-player w))) - (define i-monster (render-monsters (orc-world-lom w) with-target)) - (above V-SPACER - (beside H-SPACER - i-player - H-SPACER H-SPACER H-SPACER - (above i-monster - V-SPACER V-SPACER V-SPACER - additional-text) - H-SPACER) - V-SPACER)) - -;; Player -> Image -;; render player with three status bars -(define (render-player p) - (above/align - "left" - (status-bar (player-strength p) MAX-STRENGTH STRENGTH-COLOR STRENGTH) - V-SPACER - (status-bar (player-agility p) MAX-AGILITY AGILITY-COLOR AGILITY) - V-SPACER - (status-bar (player-health p) MAX-HEALTH HEALTH-COLOR HEALTH) - V-SPACER - (status-bar (player-armor p) MAX-ARMOR ARMOR-COLOR ARMOR) - V-SPACER V-SPACER V-SPACER - PLAYER-IMAGE)) - -;; Nat Nat Color String -> Image -;; creates a labeled rectangle of width/max proportions -;; assume: (<= width max) -(define (status-bar v-current v-max color label) - (define w (* (/ v-current v-max) HEALTH-BAR-WIDTH)) - (define f (rectangle w HEALTH-BAR-HEIGHT 'solid color)) - (define b (rectangle HEALTH-BAR-WIDTH HEALTH-BAR-HEIGHT 'outline color)) - (define bar (overlay/align 'left 'top f b)) - (beside bar H-SPACER (text label HEALTH-SIZE color))) - -;; String -> Image -(define (message str) - (text str MESSAGES-SIZE MESSAGE-COLOR)) - -;; OrcWorld -> Image -(define (instructions w) - (define na (number->string (orc-world-attack# w))) - (define ra (string-append REMAINING na)) - (above (text ra INSTRUCTION-TEXT-SIZE ATTACK-COLOR) INSTRUCTION-TEXT)) - -;; [Listof Monster] [Opt Nat] -> Image -;; add all monsters on lom, including status bar -;; label the target unless it isn't called for -(define (render-monsters lom with-target) - ;; the currently targeted monster (if needed) - (define target - (if (number? with-target) - (list-ref lom with-target) - 'a-silly-symbol-that-cannot-be-eq-to-an-orc)) - - ;; Monster -> Image - (define (render-one-monster m) - (define image - (if (eq? m target) - (overlay TARGET (monster-image m)) - (monster-image m))) - (define health (monster-health m)) - (define health-bar - (if (= health 0) - (overlay DEAD-TEXT (status-bar 0 1 'white "")) - (status-bar health MONSTER-HEALTH0 MONSTER-COLOR ""))) - (above health-bar image)) - - (arrange (map render-one-monster lom))) - -;; [Listof Image] -> Image -;; break a list of images into rows of PER-ROW -(define (arrange lom) - (cond - [(empty? lom) empty-image] - [else (define row-image (apply beside (take lom PER-ROW))) - (above row-image (arrange (drop lom PER-ROW)))])) - - -; -; -; -; ;;;;;; ;; ;;; -; ; ; ; ; ; -; ; ; ;; ;; ;;; ; ; -; ;;; ;; ; ; ;; ; -; ; ; ; ; ; ; ; -; ; ; ; ; ; ; -; ; ; ; ; ; ;; -; ;;;;;; ;;; ;;; ;;; ;; ;; -; -; -; -; - -;; OrcWorld -> Boolean -;; Has the player won? -;; > (orc-world (player 1 1 1) (list (monster 0 0)) 0 0) -;; #t -(define (win? w) - (all-dead? (orc-world-lom w))) - -;; OrcWorld -> Boolean -;; Has the player lost? -;; > (lose? (orc-world (player 0 2 2) empty 0 0)) -;; #t -(define (lose? w) - (player-dead? (orc-world-player w))) - -;; Player -> Boolean -;; Is the player dead? -;; > (orc-world (player 1 0 1) empty 0 0) -;; #t -(define (player-dead? p) - (or (= (player-health p) 0) - (= (player-agility p) 0) - (= (player-strength p) 0))) - -;; [Listof Monster] -> Boolean -;; Are all the monsters in the list dead?s -;; > (all-dead? (orc-world (player 5 5 5) (list (monster 1 0)) 0 1)) -;; #t -(define (all-dead? lom) - (not (ormap monster-alive? lom))) - -;; Monster -> Boolean -;; Is the monster alive? -(define (monster-alive? m) - (> (monster-health m) 0)) - - -; -; -; -; ;; -; ; -; ; ; ;; ;; ;; ;; ;;;;; -; ; ; ; ; ; ; ; ; -; ; ; ; ; ;; ;;;; -; ;;; ; ; ;; ; -; ; ; ; ;; ; ; ; ; -; ;;; ;;; ;; ;; ;; ;; ;;;;; -; -; -; -; - -;; Nat Nat -> Nat -;; a random number between 1 and the (quotient x y) -(define (random-quotient x y) - (define div (quotient x y)) - (if (> 0 div) 0 (random+ (add1 div)))) - -;; Nat -> Nat -;; (random+ n) creates a random number in [1,n] -(define (random+ n) - (add1 (random n))) - -;; Nat -> Nat -;; (random+ n) creates a random number in [-n,-1] -(define (random- n) - (- (add1 (random n)))) - -;; Nat Nat [Nat] -> Nat -;; subtract n from m but stay in [0,max-value] -(define (interval- n m (max-value 100)) - (min (max 0 (- n m)) max-value)) - -;; Nat Nat [Nat] -> Nat -;; subtract n from m but stay in [0,max-value] -(define (interval+ n m (max-value 100)) - (interval- n (- m) max-value)) - -; -; -; -; ;;;;;; -; ; ; ; -; ; ;;;; ;;;;; ;;;;; ;;;;; -; ; ; ; ; ; ; ; ; -; ; ;;;;;; ;;;; ; ;;;; -; ; ; ; ; ; -; ; ; ; ; ; ; ; ; -; ;;; ;;;;; ;;;;; ;;; ;;;;; -; -; -; -; - -(module+ test - - (require rackunit rackunit/text-ui) - - ;; Test structs - (define WORLD0 (orc-world (initialize-player) empty 0 0)) - (define WORLD1 (struct-copy orc-world (initialize-orc-world) [attack# 5])) - (define (WORLD2) (struct-copy orc-world (initialize-orc-world) [attack# 0])) - ;; these are random worlds - (define AN-ORC (orc 'image 0 5)) - (define A-SLIME (slime 'image 1 6)) - (define A-HYDRA (hydra 'image 2)) - (define A-BRIGAND (brigand 'image 3)) - - ;; testing move-target - - (check-equal? (let ([w (orc-world 'dummy 'dummy 'dummy 0)]) - (move-target w +1) - w) - (orc-world 'dummy 'dummy 'dummy 1)) - (check-equal? (let ([w (orc-world 'dummy 'dummy 'dummy 0)]) - (move-target w -1) - w) - (orc-world 'dummy 'dummy 'dummy (- MONSTER# 1))) - (check-equal? (let ([w (orc-world 'dummy 'dummy 'dummy 0)]) - (move-target w (- PER-ROW)) - w) - (orc-world 'dummy 'dummy 'dummy (- MONSTER# PER-ROW))) - (check-equal? (let ([w (orc-world 'dummy 'dummy 'dummy 1)]) - (move-target w (+ PER-ROW)) - w) - (orc-world 'dummy 'dummy 'dummy (+ PER-ROW 1))) - (check-equal? (begin - (move-target WORLD1 0) - WORLD1) - WORLD1) - (check-equal? (let () - (define w (struct-copy orc-world WORLD1)) - (move-target w 4) - w) - (struct-copy orc-world WORLD1 [target (+ 4 (orc-world-target WORLD1))])) - (check-equal? (current-target WORLD1) - (first (orc-world-lom WORLD1))) - - ;; testing basic player manipulations - - (check-equal? (let ([p (player 1 0 0 0)]) - (player-health+ p 5) - p) - (player 6 0 0 0)) - (check-equal? (let ([p (player 0 1 0 0)]) - (player-agility+ p 5) - p) - (player 0 6 0 0)) - - (check-equal? (let ([p (player 0 0 1 0)]) - (player-strength+ p 5) - p) - (player 0 0 6 0)) - - (check-equal? (let ([p (player 5 5 5 0)]) - (all-monsters-attack-player p (list (orc 'image 1 1))) - p) - (player 4 5 5 0)) - - (check-equal? (let ([p (player 5 5 5 0)]) - (all-monsters-attack-player p (list (hydra 'image 1))) - p) - (player 4 5 5 0)) - - (check-equal? (let ([p (player 5 5 5 0)]) - (all-monsters-attack-player p (list (slime 'image 1 1))) - p) - (player 4 4 5 0)) - - (check member - (let ([p (player 5 5 5 0)]) - (all-monsters-attack-player p (list (brigand 'image 1))) - p) - (list (player 3 5 5 0) - (player 5 2 5 0) - (player 5 5 1 0))) - - ;; Properties - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;; Property: - ;; the output will always be in [1, (/ X Y)] - (define (prop:rand-frac-range i) - (test-begin - (for ([i (in-range i)]) - (define x (random 4294967087)) - (define y (random 4294967087)) - (check-true (<= 1 (random-quotient x y) (add1 (/ x y))))))) - - ;; Property: - ;; The number of the monsters in the list is equal to - ;; MONSTER-NUM - (define (prop:monster-init-length i) - (test-begin - (for ([i (in-range i)]) - (check-true (= MONSTER# - (length (initialize-monsters))))))) - - ;; Property: - ;; the player will have less points in at least one of its - ;; fields - (define (prop:monster-attack-player-dec i) - (test-begin - (for ([i (in-range i)]) - (define pl (player MAX-HEALTH MAX-AGILITY MAX-STRENGTH 0)) - (define mon (first (initialize-monsters))) - (begin - (all-monsters-attack-player pl (list mon)) - (check-true (or (< (player-health pl) MAX-HEALTH) - (< (player-agility pl) MAX-AGILITY) - (< (player-strength pl) MAX-STRENGTH))))))) - - ;; Property: - ;; If there are monster, then the player will - ;; have less points in at least one of its fields - (define (prop:monsters-attack-player-dec i) - (test-begin - (for ([i (in-range i)]) - (define pl (player MAX-HEALTH MAX-AGILITY MAX-STRENGTH 0)) - (define monsters (initialize-monsters)) - (define wor (orc-world pl monsters 0 0)) - (begin - (all-monsters-attack-player pl monsters) - (check-true (or (< (player-health pl) MAX-HEALTH) - (< (player-agility pl) MAX-AGILITY) - (< (player-strength pl) MAX-STRENGTH))))))) - - ;; Property: The health of the targeted monster, m, - ;; is less than what it was. and - ;; [(sub1 (monster-health m)), - ;; (- (monster-health m) - ;; (/ (player-strength (orc-world-player w)) 2))] - (define (prop:stab!-health i) - (test-begin - (for ([i (in-range i)]) - (begin (define mon (first(initialize-monsters))) - (define ht (monster-health mon)) - (define pl (random-player)) - (define w (orc-world pl (list mon) 2 0)) - (stab w) - (check-true (> ht (monster-health (first (orc-world-lom w))))))))) - - ;; random-player: -> Player - ;; creates a random player - (define (random-player) - (player (add1 (random MAX-HEALTH)) - (add1 (random MAX-AGILITY)) - (add1 (random MAX-STRENGTH)) - 0)) - - ;; testing initializers - (prop:monster-init-length 1000) - (check-true (monster? (first (initialize-monsters)))) - (check-true (> 10 (monster-health (first (initialize-monsters))))) - (check-equal? (length (initialize-monsters)) MONSTER#) - (check-equal? (length (orc-world-lom WORLD1)) MONSTER#) - (check-true (>= (let ([p (initialize-player)]) - (player-health p)) - (let ([p (initialize-player)]) - (all-monsters-attack-player p (list AN-ORC)) - (player-health p)))) - (check-true (> (player-health (initialize-player)) - (let ([p (initialize-player)]) - (all-monsters-attack-player p (list A-HYDRA)) - (player-health p)))) - (check-true (< (let ([p (initialize-player)]) - (all-monsters-attack-player p (list A-SLIME)) - (player-agility p)) - (let ([p (initialize-player)]) - (player-agility p)))) - (check-true (let ([p (initialize-player)]) - (all-monsters-attack-player p (list A-BRIGAND)) - (or (= (player-health p) - (- (player-health (initialize-player)) 2)) - (= (player-agility p) - (- (player-agility (initialize-player)) 3)) - (= (player-strength p) - (- (player-strength (initialize-player)) 4))))) - (check-equal? (length (orc-world-lom WORLD1)) MONSTER#) - (check-equal? (orc-world-player WORLD1) (orc-world-player WORLD1)) - - ;; testing the-monster's attacks - - (prop:monster-attack-player-dec 1000) - (prop:monsters-attack-player-dec 1000) - (check-true (or (> (player-health (orc-world-player (WORLD2))) - (player-health (orc-world-player - (let ([w (WORLD2)]) - (all-monsters-attack-player (orc-world-player w) (orc-world-lom w)) - w)))) - (> (player-strength (orc-world-player (WORLD2))) - (player-strength (orc-world-player - (let ([w (WORLD2)]) - (all-monsters-attack-player (orc-world-player w) (orc-world-lom w)) - w)))) - (> (player-agility (orc-world-player (WORLD2))) - (player-agility (orc-world-player - (let ([w (WORLD2)]) - (all-monsters-attack-player (orc-world-player w) (orc-world-lom w)) - w)))))) - - ;; testing the player's actions - - (prop:stab!-health 1000) - (test-begin (define o (orc 'image 0 5)) - (damage-monster o 5) - (check-equal? o (orc 'image 0 5))) - (test-begin (define o (orc 'image 0 5)) - (damage-monster o 0) - (check-equal? o (orc 'image 0 5))) - (check-equal? (player-health (orc-world-player - (let () - (define w (struct-copy orc-world WORLD1)) - (heal w) - w))) - (min MAX-HEALTH - (+ 8 (player-health (orc-world-player WORLD1))))) - - (check-equal? (length (orc-world-lom - (let () - (define w (struct-copy orc-world WORLD1)) - (stab w) - w))) - MONSTER#) - - ;; testing game predicates - - (check-false (lose? WORLD0)) - (check-true (lose? (orc-world (player 0 30 30 0) empty 0 0))) - (check-true (all-dead? (list (orc 'image 0 0) (hydra 'image 0)))) - (check-true (all-dead? (list AN-ORC))) - (check-true (win? (orc-world (initialize-player) (list (orc 'image 0 0)) 0 0))) - (check-true (win? (orc-world (initialize-player) (list AN-ORC) 0 0))) - (check-true (end-of-orc-battle? (orc-world (initialize-player) (list (orc 'image 0 0)) 0 0))) - (check-true (end-of-orc-battle? (orc-world (initialize-player) (list AN-ORC) 0 0))) - (check-true (end-of-orc-battle? (orc-world (player 0 30 30 0) empty 0 0))) - (check-true (player-dead? (player 0 2 5 0))) - (check-false (player-dead? (initialize-player))) - (check-false (not (monster-alive? A-HYDRA))) - (check-true (monster-alive? (monster 'image 1))) - (check-false (monster-alive? (orc 'image 0 0))) - - ;; testing utilities - - (prop:rand-frac-range 1000) - - "all tests run") -- cgit v1.2.3