;; The first three lines of this file were inserted by DrScheme. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname |project 1 final|) (read-case-sensitive #t) (teachpacks ((lib "master.ss" "teachpack" "htdp") (lib "draw.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "master.ss" "teachpack" "htdp") (lib "draw.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))))) ;;Project 1 ;;Brandon Hoffmann ;;Joe Feely (start 500 500) ;; get-choice: string, list of strings -> integer ;; the function displays a simple menu form with the given message ;; and a drop-down menu with the list of choices. The menu ;; initially displays "Make a choice". Once a different item is chosen, ;; that item is returned. ;; When a "Close" button is pressed, the form disappears. (define (get-choice message list-of-choices) (local ( (define the-choices (make-choice (cons "Make a choice" list-of-choices))) (define w (create-window (list (list (make-message message)) (list the-choices) (list (make-button "Close" (lambda (e) (hide-window w))))))) (define (process-result n) (cond [(> n 200) (hide-window w)] ;; timeout after 200 sec [(= (choice-index the-choices) 0) (and (sleep-for-a-while 1) (process-result (+ n 1)))] [else true]) ) ) (cond [(process-result 0) (list-ref list-of-choices (- (choice-index the-choices) 1))]))) ;; get-answer: string number -> string ;; The function displays a simple text input with a question ;; and returns the answer typed in by the user ;; The second parameter (delay) is the number of seconds ;; the function waits after the typing of the first character ;; before it returns the answer. If the user takes longer ;; than that, a partial answer may be returned ;; 5 sec delay is reasonable for a one-word answer (define (get-answer question delay) (local ((define the-answer (make-text question)) (define w (create-window (list (list the-answer) (list (make-button "Close" (lambda (e) (hide-window w))))))) (define (process-result n) (cond [(> n 200) (hide-window w)] ;; timeout after 200 sec [(string=? (text-contents the-answer) "") (and (sleep-for-a-while 1) (process-result (+ n 1)))] [else true] ;; the user starts typing ))) (cond [(process-result 0) (cond [(sleep-for-a-while delay) (text-contents the-answer)]) ]) )) (define starting-weapons (list "Sword" "Axe" "Dagger" "Spear")) (define character-name (get-answer "What is your name great warrior?" 3)) (define y/n-choices (list "Yes" "No")) ;;draw-winner: number -> visual ;;The purpose of this Function is to draw a "Win" sign for when you ;;have succesfully completed the game. (define (draw-winner n) (cond [(= n 0) (and (draw-solid-rect (make-posn 50 50) 30 100 'black) (draw-solid-rect (make-posn 50 150) 150 30 'black) (draw-solid-rect (make-posn 110 100) 30 50 'black) (draw-solid-rect (make-posn 170 50) 30 100 'black) (draw-solid-rect (make-posn 250 50) 30 30 'black) (draw-solid-rect (make-posn 250 120) 30 60 'black) (draw-solid-rect (make-posn 330 80) 30 100 'black) (draw-solid-rect (make-posn 360 90) 60 30 'black) (draw-solid-rect (make-posn 400 90) 30 90 'black)) ] [else "Invalid."] ) ) ;;add-item: list, exp -> list ;;The purpose of this function is to add an item to a list. (define (add-item list item) (cond [(empty? list) (cons item empty)] [else (cons item list)] ) ) ;;remove-item: list, exp -> list ;;The purpose of this function is to remove the expression from the list. (define (remove-item list item) (cond [(empty? list) list] [(equal? (first list) item) (rest list)] [else (cons (first list) (remove-item (rest list) item))] ) ) ;;draw-clear-msg: structure, string, number -> visual ;;The purpose of this function is to draw out the letters imputted ;;at the location given and then clear them after the specified time. (define (draw-clear-msg position message sleep) (and (draw-solid-string position (string-append message)) (sleep-for-a-while sleep) (clear-solid-string position (string-append message)) ) ) ;;add-item-msg: structure, string, number -> visual ;;The purpose of this function is a specialized draw-clear-msg that ;;tells you that the imputted string has been added to your backpack (define (add-item-msg position item sleep) (and (draw-solid-string position (string-append "The " item " has been added to your backpack.")) (sleep-for-a-while sleep) (clear-solid-string position (string-append "The " item " has been added to your backpack.")) ) ) ;;draw-weapon: string -> visual ;;The purpose of this function is to draw the weapon that is imputted. (define (draw-weapon weapon) (cond [(equal? weapon "Axe") (and (draw-solid-rect (make-posn 230 160) 20 180 'red) (draw-solid-rect (make-posn 200 170) 80 50 'red)) ] [(equal? weapon "Sword") (and (draw-solid-rect (make-posn 225 350) 50 10 'red) (draw-solid-line (make-posn 240 180) (make-posn 250 160) 'red) (draw-solid-line (make-posn 260 180) (make-posn 250 160) 'red) (draw-solid-rect (make-posn 240 180) 20 200 'red)) ] [(equal? weapon "Dagger") (and (draw-solid-rect (make-posn 230 250) 40 10 'red) (draw-solid-line (make-posn 240 180) (make-posn 250 160) 'red) (draw-solid-line (make-posn 260 180) (make-posn 250 160) 'red) (draw-solid-rect (make-posn 240 180) 20 100 'red)) ] [else (and (draw-solid-line (make-posn 240 100) (make-posn 250 85) 'red) (draw-solid-line (make-posn 259 100) (make-posn 250 85) 'red) (draw-solid-rect (make-posn 240 100) 20 300 'red))] ) ) ;;clear-weapon: string -> visual ;;The purpose of this function is to clear the drawings from the previous function. (define (clear-weapon weapon) (cond [(equal? weapon "Axe") (and (clear-solid-rect (make-posn 230 160) 20 180 'red) (clear-solid-rect (make-posn 200 170) 80 50 'red)) ] [(equal? weapon "Sword") (and (clear-solid-rect (make-posn 225 350) 50 10 'red) (clear-solid-line (make-posn 240 180) (make-posn 250 160) 'red) (clear-solid-line (make-posn 260 180) (make-posn 250 160) 'red) (clear-solid-rect (make-posn 240 180) 20 200 'red)) ] [(equal? weapon "Dagger") (and (clear-solid-rect (make-posn 230 250) 40 10 'red) (clear-solid-line (make-posn 240 180) (make-posn 250 160) 'red) (clear-solid-line (make-posn 260 180) (make-posn 250 160) 'red) (clear-solid-rect (make-posn 240 180) 20 100 'red)) ] [else (and (draw-solid-line (make-posn 240 100) (make-posn 250 85) 'red) (draw-solid-line (make-posn 259 100) (make-posn 250 85) 'red) (draw-solid-rect (make-posn 240 100) 20 300 'red))] ) ) ;;enchant-weapon: string, list, number -> list ;;The purpose of this function is to remove a weapon from a list and then ;;replace it with an "Enchanted" of the same item. (define (enchant-weapon weapon backpack n) (cond [(= n 2) (enchant-weapon weapon (remove-item backpack weapon) 1)] [(and (= n 1) (equal? weapon "Sword")) (add-item backpack "Enchanted Sword")] [(and (= n 1) (equal? weapon "Axe")) (add-item backpack "Enchanted Axe")] [(and (= n 1) (equal? weapon "Spear")) (add-item backpack "Enchanted Spear")] [(and (= n 1) (equal? weapon "Dagger")) (add-item backpack "Enchanted Dagger")] ) ) ;;show-list: list -> list ;;The purpose of this function is to take a list and output it, it is used ;;to show the final contents of your backpack. (define (bag-contains list) (cond [(empty? list) (draw-solid-string (make-posn 35 450) (string-append "Game Over"))] [else (and (draw-clear-msg (make-posn 35 450) (first list) 3) (bag-contains (rest list)))] )) ;;daemon-battle: string, list -> visuals ;;The purpose of this function is to create the outcome of the final battle against the daemon. ;;The outcome is based on the players choice of weapon. (define (daemon-battle choice backpack) (cond [(equal? choice (first backpack)) (and (draw-clear-msg (make-posn 35 450) "YOU HAVE SLAIN THE MIGHTY DAEMON!!" 4) (draw-clear-msg (make-posn 35 450) "The Daemon dropped a Soulshard." 4) (add-item-msg (make-posn 35 450) "Soulshard" 4) (draw-clear-msg (make-posn 35 450) (string-append "You are now " character-name " the Immortal") 5) (draw-winner 0) (draw-clear-msg (make-posn 35 450) "Your backpack contains:" 4) (bag-contains (add-item backpack "Soulshard"))) ] [else (draw-solid-string (make-posn 35 450) (string-append "You are an idiot, Game Over"))] ) ) ;;road-to-daemon: list -> visuals ;;The purpose of this function is to create storyline on the canvas through drawing strings and then ;;move on to the daemon battle. (define (road-to-daemon backpack) (and (draw-clear-msg (make-posn 35 450) "You are now confused as to where this Daemon is." 4) (draw-clear-msg (make-posn 35 450) "You then remember you have a map." 4) (draw-clear-msg (make-posn 35 450) "The map just so happens to direct you straight to the Daemon." 4) (draw-clear-msg (make-posn 35 450) "You follow the map straight to the Daemon." 4) (draw-clear-msg (make-posn 35 450) "The map has been removed from your backpack." 4) (draw-clear-msg (make-posn 35 450) "The Daemon strikes! Are you ready to fight?" 4) (daemon-battle (get-choice "Which weapon would you like to use agains the Daemon?" (remove-item backpack "Map")) (remove-item backpack "Map")) )) ;;wizard-encounter: string, list -> visuals ;;The purpose of this function is to have the wizard you encounter tell you about the daemon ;;and then enchant one of your weapons. (define (wizard-encounter choice backpack) (and (clear-solid-string (make-posn 35 450) (string-append "He would like to enchant one of your weapons.")) (draw-solid-string (make-posn 35 450) (string-append "The wizard enchanted your " choice " so it is powerful enough to defeat the Daemon.")) (sleep-for-a-while 4) (clear-solid-string (make-posn 35 450) (string-append "The wizard enchanted your " choice " so it is powerful enough to defeat the Daemon.")) (draw-solid-string (make-posn 35 450) (string-append "This Enchanted " choice " is the only weapon that can defeat him!")) (sleep-for-a-while 4) (clear-solid-string (make-posn 35 450) (string-append"This Enchanted " choice " is the only weapon that can defeat him!")) (road-to-daemon (enchant-weapon choice backpack 2)) ) ) ;;continue: string, list -> visual ;;The purpose of this function is to see whether you want to continue, if you don't game over ;;but if you do it sends you back to the goblin encounter. (define (continue choice backpack) (cond [(equal? choice "Yes") (fight-goblin? (get-choice "You see the Goblin again, fight it again?" y/n-choices) backpack)] [(equal? choice "No") (draw-solid-string (make-posn 35 450) (string-append "Game Over!"))] ) ) ;;goblin-fight: string, list -> visual ;;This function simulates a fight against the goblin with random rolls, if you win the story ;;continues, but if you lose you go to the continue function. (define (goblin-fight weapon-choice backpack) (cond [(or (and (equal? weapon-choice "Axe") (>= (+ 2 (random 6)) (random 5))) (and (equal? weapon-choice "Sword") (>= (+ 3 (random 4)) (random 5))) (and (equal? weapon-choice "Spear") (>= (+ 1 (random 6)) (random 5))) (and (equal? weapon-choice "Dagger") (>= (+ 3 (random 2)) (random 5))) ) (and (draw-clear-msg (make-posn 35 450) "You Owned that Goblin." 4) (draw-clear-msg (make-posn 35 450) "The Goblin dropped a map." 4) (draw-clear-msg (make-posn 35 450) "The map has been added to your backpack." 4) (draw-clear-msg (make-posn 35 450) "As you journey forth you come across a Wizard." 4) (draw-clear-msg (make-posn 35 450) "The Wizard tells you of a Daemon that normal weapons cannot harm" 4) (draw-solid-string (make-posn 35 450) (string-append "He would like to enchant one of your weapons.")) (wizard-encounter (get-choice "Which weapon would you like him to enchant?" backpack) (add-item backpack "Map")) ) ] [else (and (draw-clear-msg (make-posn 35 450) "You have died!" 4) (sleep-for-a-while 2) (continue (get-choice "Continue?" y/n-choices) backpack) ) ] ) ) ;;fight-goblin?: string, list -> visuals ;;The purpose of this function is to ask you if you want to fight the goblin although if you ;;don't it tells you he is fast and sends you back to the same function. (define (fight-goblin? choice backpack) (cond [(equal? choice "No") (and (draw-clear-msg (make-posn 35 450) "That Goblin is fast." 4) (fight-goblin? (get-choice "You see the same Goblin, fight it this time?" y/n-choices) backpack) ) ] [(equal? choice "Yes") (goblin-fight (get-choice "Choose your weapon!" backpack) backpack)] ) ) ;;choose-weapons: list, string, number, list -> visuals ;;The purpose of this function is to allow you to pick your weapons for your journey. (define (choose-weapons weapons choice n backpack) (cond [(= n 3) (and (draw-weapon choice) (add-item-msg (make-posn 35 450) choice 4) (clear-weapon choice) (choose-weapons (remove-item weapons choice) (get-choice "Choose your second weapon!" (remove-item weapons choice)) 2 (add-item backpack choice)) ) ] [(= n 2) (and (draw-weapon choice) (add-item-msg (make-posn 35 450) choice 4) (clear-weapon choice) (choose-weapons (remove-item weapons choice) choice 1 backpack) ) ] [(= n 1) (and (draw-clear-msg (make-posn 35 450) "You passed on:" 3) (draw-weapon (first weapons)) (draw-solid-string (make-posn 35 450) (string-append "The " (first weapons))) (sleep-for-a-while 4) (clear-solid-string (make-posn 35 450) (string-append "The " (first weapons))) (clear-weapon (first weapons)) (draw-weapon (rest weapons)) (draw-solid-string (make-posn 35 450) (string-append "The " (first (remove-item weapons (first weapons))))) (sleep-for-a-while 4) (clear-solid-string (make-posn 35 450) (string-append "The " (first (remove-item weapons (first weapons))))) (clear-weapon (rest weapons)) (fight-goblin? (get-choice "You see a goblin do you want to fight?" y/n-choices) (add-item backpack choice)) )] ) ) (choose-weapons starting-weapons (get-choice "Choose your weapons!!" starting-weapons) 3 empty)