M EjemplosRacket/Juegos/GUIAdivinaElNumero/source.rkt => EjemplosRacket/Juegos/GUIAdivinaElNumero/source.rkt +2 -2
@@ 76,13 76,13 @@
;
;
-(define TEXT-SIZE 20)
+(define TEXT-SIZE 25)
(define HELP-TEXT
(text "↑ para números mayores, ↓ para menores"
TEXT-SIZE
"blue"))
(define HELP-TEXT2
- (text "Presiona = cuando tu número ha sido adivinado; q para salir."
+ (text "Presiona = cuando tu número ha sido adivinado\nq para salir."
TEXT-SIZE
"blue"))
(define WIDTH (+ (image-width HELP-TEXT2) 20))
A EjemplosRacket/Juegos/Snake/graphics/body.gif => EjemplosRacket/Juegos/Snake/graphics/body.gif +0 -0
A EjemplosRacket/Juegos/Snake/graphics/goo.gif => EjemplosRacket/Juegos/Snake/graphics/goo.gif +0 -0
A EjemplosRacket/Juegos/Snake/graphics/head.gif => EjemplosRacket/Juegos/Snake/graphics/head.gif +0 -0
A EjemplosRacket/Juegos/Snake/graphics/tail.gif => EjemplosRacket/Juegos/Snake/graphics/tail.gif +0 -0
A EjemplosRacket/Juegos/Snake/source.rkt => EjemplosRacket/Juegos/Snake/source.rkt +858 -0
@@ 0,0 1,858 @@
+#lang racket
+
+#|
+ The Snake game
+ --------------
+ The Snake game revolves around a room filled with pieces of radioactive goo
+ and a snake that can remove this goo.
+ When the snake eats the goo, it grows and new goo appears. Like all
+ radioactive material, goo decays over time. Eventually it expires, but
+ fortunately for the snake, a new piece of goo appears elsewhere.
+ The player is in control of a snake, and the objective is to grow the snake as
+ large as possible. She may change the direction of the snake by pressing one of
+ the four arrow keys. When the snake gets close to a piece of goo, it eats the
+ goo and grows a new segment. If the snake runs into itself or one of the four
+ walls, the game is over. The length of the snake is the player's score.
+ Play
+ ----
+
+ Run and evaluate
+ (start-snake)
+ This will pop up a window with instructions for interacting with the program.
+|#
+
+;
+;
+;
+;
+; ;;
+; ;;; ; ;
+; ; ;; ;
+; ; ; ;; ;;; ;;;; ; ;;; ;;;
+; ; ;; ; ; ; ; ; ; ;
+; ;;;; ; ; ; ; ; ; ;
+; ; ; ; ;;;;;; ;;; ;;;;;;;
+; ; ; ; ; ; ; ; ; ;
+; ;; ; ; ; ; ;; ; ; ; ;
+; ; ;;; ;;; ;;; ;;;; ;; ;; ;;;; ;;;;
+;
+;
+;
+;
+
+(require 2htdp/image 2htdp/universe)
+;; -----------------------------------------------------------------------------
+;; Data Definitions
+
+;; A Pit is a (pit Snake (Listof Goo))
+(struct pit (snake goos) #:transparent)
+
+;; A Snake is a (make-snake Direction (cons Seg [Listof Seg]))
+(struct snake (dir segs) #:transparent)
+;; The head of the snake is the first element in the list of segs.
+;; Each segment of a snake is located with:
+;; - x in (0,SIZE),
+;; - y in (0,SIZE).
+;; And is SEG-SIZE aligned (x and y are multiples of SEG-SIZE).
+
+;; A Seg is a (posn Number Number)
+
+;; A Goo is a (goo Posn Number)
+(struct goo (loc expire) #:transparent)
+;; The expire field is a Natural Number that represents the number
+;; of ticks until the goo expires. A goo is expired when this field is 1
+
+;; A Direction is one of "up" "down" "left" "right"
+
+;; A Posn is (posn number number)
+(struct posn (x y) #:transparent)
+;; Represents a two dimensional point.
+
+;; -----------------------------------------------------------------------------
+;; Constants
+
+;; Tick Rate
+(define TICK-RATE 1/10)
+
+;; Board Size Constants
+(define SIZE 30)
+
+;; Snake Constants
+(define SEG-SIZE 15)
+
+;; Goo Constants
+(define MAX-GOO 5)
+(define EXPIRATION-TIME 150)
+
+;; GRAPHICAL BOARD
+(define WIDTH-PX (* SEG-SIZE SIZE))
+(define HEIGHT-PX (* SEG-SIZE SIZE))
+
+;; Visual constants
+(define MT-SCENE (empty-scene WIDTH-PX HEIGHT-PX))
+(define GOO-IMG (bitmap "graphics/goo.gif"))
+(define SEG-IMG (bitmap "graphics/body.gif"))
+(define HEAD-IMG (bitmap "graphics/head.gif"))
+
+(define HEAD-LEFT-IMG HEAD-IMG)
+(define HEAD-DOWN-IMG (rotate 90 HEAD-LEFT-IMG))
+(define HEAD-RIGHT-IMG (flip-horizontal HEAD-LEFT-IMG))
+(define HEAD-UP-IMG (flip-vertical HEAD-DOWN-IMG))
+
+(define ENDGAME-TEXT-SIZE 15)
+
+
+;
+;
+;
+; ;
+; ;
+; ;;; ;;;
+; ;; ;;
+; ; ; ; ; ;;;; ;;; ;; ;;;
+; ; ; ; ; ; ; ; ;; ;
+; ; ; ; ; ; ; ; ;
+; ; ; ; ;;;;;; ; ; ;
+; ; ; ; ; ; ; ;
+; ; ; ; ;; ; ; ;
+; ;;; ;;; ;;;; ;; ;;;;;;; ;;; ;;;
+;
+;
+;
+;
+;; -----------------------------------------------------------------------------
+
+;; Start the Game
+(define (start-snake)
+ (big-bang (pit (snake "right" (list (posn 1 1)))
+ (list (fresh-goo)
+ (fresh-goo)
+ (fresh-goo)
+ (fresh-goo)
+ (fresh-goo)
+ (fresh-goo)))
+ (on-tick next-pit TICK-RATE)
+ (on-key direct-snake)
+ (to-draw render-pit)
+ (stop-when dead? render-end)))
+
+;; Pit -> Pit
+;; Take one step: eat or slither
+(define (next-pit w)
+ (define snake (pit-snake w))
+ (define goos (pit-goos w))
+ (define goo-to-eat (can-eat snake goos))
+ (if goo-to-eat
+ (pit (grow snake) (age-goo (eat goos goo-to-eat)))
+ (pit (slither snake) (age-goo goos))))
+
+;; Pit KeyEvent -> Pit
+;; Handle a key event
+(define (direct-snake w ke)
+ (cond [(dir? ke) (world-change-dir w ke)]
+ [else w]))
+
+;; Pit -> Scene
+;; Render the world as a scene
+(define (render-pit w)
+ (snake+scene (pit-snake w)
+ (goo-list+scene (pit-goos w) MT-SCENE)))
+
+;; Pit -> Boolean
+;; Is the snake dead?
+(define (dead? w)
+ (define snake (pit-snake w))
+ (or (self-colliding? snake) (wall-colliding? snake)))
+
+;; Pit -> Scene
+;; produces a gameover image
+(define (render-end w)
+ (overlay (text "Game over" ENDGAME-TEXT-SIZE "black")
+ (render-pit w)))
+
+;
+;
+;
+; ;;;; ;; ;; ;;;;;; ; ;;
+; ; ; ; ; ; ; ;
+; ; ; ;;;; ;;; ; ; ;;;; ; ;;; ;;; ; ; ;;;; ;;;;;
+; ; ; ; ; ;; ;; ; ; ; ; ;; ;; ; ; ; ;
+; ; ; ; ; ; ;;; ; ; ; ;;; ;;;;
+; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ;;; ;;;;; ;;;; ;;;; ;; ;;; ;;; ;;;;; ;;;; ;; ;;; ;;;;;
+;
+;
+;
+;
+
+;; -----------------------------------------------------------------------------
+;; Movement and Eating
+
+;; -----------------------------------------------------------------------------
+;; Eating and Growth
+
+;; Snake [Listof Goo] -> Goo or #f
+;; Can the snake eat any of the goos?
+;; > (can-eat (snake "right" `(,(posn 3 3))) `(,(goo (posn 3 3) 130)))
+;; (goo (posn 3 3) 130)
+(define (can-eat snake goos)
+ (cond [(empty? goos) #f]
+ [else (if (close? (snake-head snake) (first goos))
+ (first goos)
+ (can-eat snake (rest goos)))]))
+
+;; [Listof Goo] Goo -> [Listof Goo]
+;; Eat and replenish a goo.
+;; > (eat (list (goo (posn 5 5) 5)) (goo (posn 5 5) 5))
+;; (list (new-goo))
+(define (eat goos goo-to-eat)
+ (cons (fresh-goo) (remove goo-to-eat goos)))
+
+;; Seg Goo -> Boolean
+;; Is the segment close to the goo?
+;; > (close? (posn 1 2) (goo (posn 1 2) 4))
+;; #t
+(define (close? s g)
+ (posn=? s (goo-loc g)))
+
+;; Grow the snake one segment.
+;; Snake -> Snake
+;; > (grow snake0)
+;; (snake "right" `(,(posn 2 1) ,(posn 1 1)))
+(define (grow sn)
+ (snake (snake-dir sn) (cons (next-head sn) (snake-segs sn))))
+
+;; -----------------------------------------------------------------------------
+;; Movement
+
+;; Snake -> Snake
+;; Slither the snake forward one segment.
+;; > (slither snake0)
+;; (snake "right" (posn 2 1))
+(define (slither sn)
+ (snake (snake-dir sn)
+ (cons (next-head sn) (all-but-last (snake-segs sn)))))
+
+;; Snake -> Seg
+;; Compute the next head position of the snake.
+;; > (next-head snake0)
+;; (snake "right" (list (posn 2 1)))
+(define (next-head sn)
+ (define head (snake-head sn))
+ (define dir (snake-dir sn))
+ (cond [(string=? dir "up") (posn-move head 0 -1)]
+ [(string=? dir "down") (posn-move head 0 1)]
+ [(string=? dir "left") (posn-move head -1 0)]
+ [(string=? dir "right") (posn-move head 1 0)]))
+
+;; Posn Number Number -> Posn
+;; Move the position by dx, dy.
+;; > (posn-move (posn 1 1) 2 3)
+;; (posn 3 4)
+(define (posn-move p dx dy)
+ (posn (+ (posn-x p) dx)
+ (+ (posn-y p) dy)))
+
+;; (cons X [Listof X]) -> [Listof X]
+;; Returns a List that is does not contain the last element of the given list.
+;; > (all-but-last '(1 2 3 4))
+;; '(1 2 3)
+(define (all-but-last segs)
+ (cond [(empty? (rest segs)) empty]
+ [else (cons (first segs)
+ (all-but-last (rest segs)))]))
+
+;; -----------------------------------------------------------------------------
+;; Rotting Goo
+
+;; [Listof Goo] -> [Listof Goo]
+;; Renew and rot goos.
+(define (age-goo goos)
+ (rot (renew goos)))
+
+;; [Listof Goo] -> [Listof Goo]
+;; Renew any rotten goos.
+(define (renew goos)
+ (cond [(empty? goos) empty]
+ [(rotten? (first goos))
+ (cons (fresh-goo) (renew (rest goos)))]
+ [else
+ (cons (first goos) (renew (rest goos)))]))
+
+;; [Listof Goo] -> [Listof Goo]
+;; Rot all of the goos.
+(define (rot goos)
+ (cond [(empty? goos) empty]
+ [else (cons (decay (first goos))
+ (rot (rest goos)))]))
+
+;; Goo -> Boolean
+;; has the goo expired?
+;; > (rotten? (goo 1 2) 0)
+;; #t
+(define (rotten? g)
+ (zero? (goo-expire g)))
+
+;; Goo -> Goo
+;; decreases the expire field of goo by one
+;; > (decay (goo (posn 1 2) 2))
+;; (goo (posn 1 2) 1)
+(define (decay g)
+ (goo (goo-loc g) (sub1 (goo-expire g))))
+
+;; -> Goo
+;; Create random goo with fresh expiration.
+;; Property: The position of the goo is:
+;; - x in (0,WIDTH),
+;; - y in (0,HEIGHT).
+(define (fresh-goo)
+ (goo (posn (add1 (random (sub1 SIZE)))
+ (add1 (random (sub1 SIZE))))
+ EXPIRATION-TIME))
+
+;
+;
+;
+;
+;
+; ;;; ;;;;
+; ; ;
+; ; ; ;;; ;;; ;;; ;;;; ;
+; ; ; ; ; ; ; ; ;;
+; ;;;; ; ; ; ; ;
+; ; ; ;;;;;;; ; ; ;;;;;
+; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ;
+; ;;; ;; ;;;; ; ;;;;;;
+; ;
+; ;
+; ;;;;;
+;
+;; -----------------------------------------------------------------------------
+
+;; String -> Boolean
+;; Is the given value a direction?
+;; > (dir? "up")
+;; #t
+(define (dir? x)
+ (or (string=? x "up")
+ (string=? x "down")
+ (string=? x "left")
+ (string=? x "right")))
+
+;; Pit Direction-> Pit
+;; Change the direction (if not opposite current snake dir)
+;; > (world-change-dir world0 "up")
+;; (pit snake1 (list goo0))
+(define (world-change-dir w d)
+ (define the-snake (pit-snake w))
+ (cond [(and (opposite-dir? (snake-dir the-snake) d)
+ ;; consists of the head and at least one segment:
+ (cons? (rest (snake-segs the-snake))))
+ (stop-with w)]
+ [else
+ (pit (snake-change-dir the-snake d)
+ (pit-goos w))]))
+
+;; Direction Direction -> Boolean
+;; Are d1 and d2 opposites?
+;; > (opposite-dir? "up" "down")
+;; #t
+(define (opposite-dir? d1 d2)
+ (cond [(string=? d1 "up") (string=? d2 "down")]
+ [(string=? d1 "down") (string=? d2 "up")]
+ [(string=? d1 "left") (string=? d2 "right")]
+ [(string=? d1 "right") (string=? d2 "left")]))
+
+
+;
+;
+;
+;
+; ;;
+; ;;;;;; ;
+; ; ; ;
+; ; ; ;;; ;; ;;; ;;; ; ;;; ;; ;;;
+; ; ; ; ; ;; ; ; ;; ; ; ;;;
+; ;;;;; ; ; ; ; ; ; ; ; ;
+; ; ; ;;;;;;; ; ; ; ; ;;;;;;; ;
+; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ;; ; ; ;
+; ;;; ;; ;;;; ;;; ;;; ;;; ;; ;;;; ;;;;;
+;
+;
+;
+;
+;; -----------------------------------------------------------------------------
+
+;; Snake Scene -> Scene
+;; Draws the snake onto the scene
+;; > (snake+scene snake0 MT-SCENE)
+;; (place-image SEG-IMG 8 8 MT-SCENE)
+(define (snake+scene snake scene)
+ (define snake-body-scene
+ (img-list+scene (snake-body snake) SEG-IMG scene))
+ (define dir (snake-dir snake))
+ (img+scene (snake-head snake)
+ (cond [(string=? "up" dir) HEAD-UP-IMG]
+ [(string=? "down" dir) HEAD-DOWN-IMG]
+ [(string=? "left" dir) HEAD-LEFT-IMG]
+ [(string=? "right" dir) HEAD-RIGHT-IMG])
+ snake-body-scene))
+
+;; [Listof Goo] Scene -> Scene
+;; draws all of the goo to a scene
+;; > (goo-list+scene (list goo0) MT-SCENE)
+;; (place-image GOO-IMG 32 32 MT-SCENE)
+(define (goo-list+scene goos scene)
+ ;; [Listof Goo] -> [Listof Posn]
+ ;; gets the posns of all the goo
+ ;; > (get-posns-from-goo (list (goo (posn 2 2) 1) (goo (posn 3 3) 1))
+ ;; (list (posn 2 2) (posn 3 3))
+ (define (get-posns-from-goo goos)
+ (cond [(empty? goos) empty]
+ [else (cons (goo-loc (first goos))
+ (get-posns-from-goo (rest goos)))]))
+ (img-list+scene (get-posns-from-goo goos) GOO-IMG scene))
+
+;; [Listof Posn] Image Scene -> Scene
+;; Draws a the image to each posn in the list
+;; > (img-list+scene (list (posn 1 1)) GOO-IMG MT-SCENE)
+;; (place-image GOO-IMG 8 8
+;; (img-list+scene empty GOO-IMG MT-SCENE))
+(define (img-list+scene posns img scene)
+ (cond [(empty? posns) scene]
+ [else (img+scene (first posns)
+ img
+ (img-list+scene (rest posns) img scene))]))
+
+;; Posn Image Scene -> Scene
+;; Draws a the given image onto the scene at the posn.
+;; > (img+scene (posn 2 2) GOO-IMG MT-SCENE)
+;; (place-image GOO-IMG 32 32 MT-SCENE)
+(define (img+scene posn img scene)
+ (place-image img
+ (* (posn-x posn) SEG-SIZE)
+ (* (posn-y posn) SEG-SIZE)
+ scene))
+
+;
+;
+;
+;
+; ;;
+; ;;;;;;; ; ;;;; ;
+; ; ; ; ; ;;
+; ; ; ;; ;;; ;;; ; ; ;;;; ;; ; ; ;;;
+; ; ; ;; ; ; ;; ; ; ; ;; ;; ; ; ;
+; ;;;; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ;;;;; ;;;;;; ; ; ; ;;;;;;;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ;; ; ; ; ;; ; ; ; ; ;
+; ;;;;;;; ;;; ;;; ;;; ;; ;;;;; ;;;; ;; ;;; ;; ;; ;;;;
+;
+;
+;
+;
+;; -----------------------------------------------------------------------------
+
+;; Snake -> Boolean
+;; Determine if the snake is colliding with itself.
+;; > (self-colliding? (snake "up" (list (posn 1 1) (posn 2 1)
+;; (posn 2 2) (posn 1 2)
+;; (posn 1 1))))
+;; #t
+(define (self-colliding? sn)
+ (cons? (member (snake-head sn) (snake-body sn))))
+
+;; Snake -> Boolean
+;; Determine if the snake is colliding with any of the walls.
+;; > (wall-colliding? (snake "up" (list (posn 0 1))))
+;; #t
+(define (wall-colliding? sn)
+ (define x (posn-x (snake-head sn)))
+ (define y (posn-y (snake-head sn)))
+ (or (= 0 x) (= x SIZE)
+ (= 0 y) (= y SIZE)))
+
+
+
+;
+;
+;
+;
+;
+; ;;; ;;; ;;; ;;; ;;; ;;;;;;; ;;;;; ;;;;;;; ;;; ;;;;;; ;;; ;;;
+; ;; ; ; ; ; ; ; ; ;; ; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ;;;;; ;
+; ;;;;;; ; ; ; ; ; ; ; ; ;;;;;; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
+; ;;; ;;; ;;;; ;;; ;;; ;;;;;;; ;;;;;;;; ;;;;;;; ;;; ;;; ;;; ;; ;;;;;
+;
+;
+;
+;
+;; -----------------------------------------------------------------------------
+;; Posn Posn -> Boolean
+;; Are the two posns are equal?
+;; > (posn=? (posn 1 1) (posn 1 1))
+;; true
+(define (posn=? p1 p2)
+ (and (= (posn-x p1) (posn-x p2))
+ (= (posn-y p1) (posn-y p2))))
+
+;; Access the head position of the snake.
+;; snake-head : Snake -> Seg
+;; > (snake-head (snake "right" (list (posn 1 1) (posn 2 1)))
+;; (posn 1 1)
+(define (snake-head sn)
+ (first (snake-segs sn)))
+
+;; Snake -> [Listof Segs]
+;; returns the snake's body.
+;; That is everyting that isn't the snake's head.
+(define (snake-body sn)
+ (rest (snake-segs sn)))
+
+;; Snake Direction -> Snake
+(define (snake-change-dir sn d)
+ (snake d (snake-segs sn)))
+
+
+;
+;
+;
+;
+;
+; ;;;;;;; ;
+; ; ; ; ;
+; ; ; ; ;;; ;;;; ; ;;;;;;; ;;;; ;
+; ; ; ; ; ; ; ;; ; ; ;;
+; ; ; ; ; ; ;
+; ; ;;;;;;; ;;;;; ; ;;;;;
+; ; ; ; ; ;
+; ; ; ; ; ; ; ; ; ;
+; ;;;;; ;;;; ;;;;;; ;;;; ;;;;;;
+;
+;
+;
+;
+;; -----------------------------------------------------------------------------
+
+;; Initial Structures
+
+(define goo-list (build-list MAX-GOO (lambda (x) (fresh-goo))))
+(define snake0 (snake "right" (list (posn 1 1)))) ;; BUG? << -- moving this define into the test module blows up
+(define world0 (pit snake0 goo-list))
+
+(define left-snake0 (snake "left" (list (posn 1 1))))
+(define left-world0 (pit left-snake0 goo-list))
+
+;; Test Constants
+
+(define snake1 (snake "left" (list (posn 5 5))))
+(define snake2 (snake "up" (list (posn 2 2) (posn 2 3) (posn 2 4))))
+(define wall-snake (snake "right" (list (posn 0 1) (posn 1 1))))
+(define self-eating-snake (snake "up" (list
+ (posn 19 3)
+ (posn 19 4)
+ (posn 20 4)
+ (posn 21 4)
+ (posn 22 4)
+ (posn 22 3)
+ (posn 21 3)
+ (posn 20 3)
+ (posn 19 3)
+ (posn 18 3))))
+(define goo1 (goo (posn 5 5) 45))
+(define goo2 (goo (posn 4 8) 1))
+(define goo3 (goo (posn 6 9) 40))
+(define goo4 (goo (posn 1 1) 120))
+(define goo5 (goo (posn 1 9) 58))
+(define goo-list1 (list goo1 goo2 goo3 goo4 goo5))
+(define world1 (pit snake1 goo-list1))
+(define world2 (pit snake2 goo-list1))
+
+(define right-snake1 (snake "right" (list (posn 5 5))))
+(define right-world1 (pit right-snake1 goo-list1))
+
+(module+ test
+
+ (require rackunit rackunit/text-ui)
+
+ ;; test the major basic snake functions
+ (check-equal? (pit-snake (next-pit world2))
+ (snake "up" (list (posn 2 1) (posn 2 2) (posn 2 3))))
+ (check-equal? (pit-snake (next-pit world1))
+ (snake "left" (list (posn 4 5) (posn 5 5))))
+ (check-true (let ([f (pit-goos (next-pit world1))])
+ (= (length f) MAX-GOO)))
+ (check-equal? (pit-snake (next-pit (pit snake0 (list (goo (posn SIZE SIZE) 100)))))
+ (snake "right" (list (posn 2 1))))
+ (check-equal? (pit-snake (next-pit (pit snake0 (list (goo (posn 1 1) 130)))))
+ (snake "right" (list (posn 2 1) (posn 1 1))))
+
+ (check-equal? (direct-snake world0 "down")
+ (world-change-dir world0 "down"))
+ (check-equal? (direct-snake world0 "a")
+ world0)
+
+ (check-equal? (render-pit world0)
+ (snake+scene snake0
+ (goo-list+scene goo-list MT-SCENE)))
+ (check-equal? (render-pit world1)
+ (snake+scene snake1 (goo-list+scene goo-list1 MT-SCENE)))
+ (check-equal? (render-pit world2)
+ (snake+scene snake2 (goo-list+scene goo-list1 MT-SCENE)))
+
+ (check-true (dead? (pit wall-snake '())))
+ (check-true (dead? (pit self-eating-snake '())))
+ (check-false (dead? (pit snake1 '())))
+ (check-false (dead? (pit snake2 '())))
+ (check-false (dead? world0))
+
+ (check-equal? (render-end world1)
+ (overlay (text "Game over" 15 "black")
+ (render-pit world1)))
+ (check-equal? (render-end world2)
+ (overlay (text "Game over" 15 "black")
+ (render-pit world2)))
+
+ ;; Properties
+ ;; -----------------------------------------------------------------------------
+
+ ;; Property: each goo in the list has its 'expire' field decremented by 1
+ (define (prop:goo-rot-- i)
+ (test-begin
+ (for ([i (in-range i)])
+ (define goos (list-of-n-goo MAX-GOO))
+ (define goo-initial-expire (map goo-expire goos))
+ (check-equal? (map sub1 goo-initial-expire)
+ (map goo-expire (age-goo goos))))))
+
+ ;; Property: The position of the goo is:
+ ;; - x in (0,WIDTH-SEGS),
+ ;; - y in (0,HEIGHT-SEGS).
+ (define (prop:new-goo-range i)
+ (test-begin
+ (for ([i (in-range i)])
+ (define f (fresh-goo))
+ (check-true (and (< 0 (posn-x (goo-loc f)) SIZE)
+ (< 0 (posn-y (goo-loc f)) SIZE))))))
+
+ ;; Number -> [Listof Goo]
+ ;; creates a list of randomly selected goo that is n long.
+ (define (list-of-n-goo n)
+ (cond [(zero? n) empty]
+ [else (define rand (random 5))
+ (cons (list-ref goo-list1 rand) (list-of-n-goo (sub1 n)))]))
+
+ ;; testing pit-snake event handling
+
+ (check-equal? (pit-snake (world-change-dir (pit snake1 "foobar") "down"))
+ (snake "down" (list (posn 5 5))))
+ (check-equal? (pit-snake (world-change-dir (pit snake2 "left") "left"))
+ (snake "left" (list (posn 2 2) (posn 2 3) (posn 2 4))))
+
+ (prop:goo-rot-- 1000)
+
+ (check-equal? (grow snake0)
+ (snake "right" (list (posn 2 1) (posn 1 1))))
+ (check-equal? (grow snake1)
+ (snake "left" (list (posn 4 5) (posn 5 5))))
+ (check-equal? (grow snake0)
+ (snake "right" (list (posn 2 1)
+ (posn 1 1))))
+
+ (prop:new-goo-range 1000)
+
+ (check-equal? (can-eat (snake "right" `(,(posn 3 3))) `(,(goo (posn 3 3) 130)))
+ (goo (posn 3 3) 130))
+ (check-false (can-eat (snake "right" `(,(posn 3 3))) `(,(goo (posn 3 4) 130)
+ ,(goo (posn 2 2) 0))))
+ (check-equal? (can-eat snake0 (list (goo (posn 1 1) 1)))
+ (goo (posn 1 1) 1))
+ (check-false (can-eat snake0 (list (goo (posn 2 1) 1))))
+
+ (check-equal? (slither snake0) (snake "right" (list (posn 2 1))))
+ (check-equal? (slither (snake "right" (list (posn 4 4)
+ (posn 4 5)
+ (posn 4 6))))
+ (snake "right" (list (posn 5 4) (posn 4 4) (posn 4 5))))
+ (check-equal? (slither snake0)
+ (snake "right" (list (posn 2 1))))
+
+ (check-equal? (length (eat (list (goo (posn 1 1) 130)) (goo (posn 1 1) 130)))
+ 1)
+ (check-equal? (grow (snake "left" (list (posn 1 1))))
+ (snake "left" (list (posn 0 1) (posn 1 1))))
+
+ (check-equal? (next-head snake0) (posn 2 1))
+ (check-equal? (next-head (snake "left" (list (posn 1 1))))
+ (posn 0 1))
+ (check-equal? (next-head (snake "up" (list (posn 1 1))))
+ (posn 1 0))
+ (check-equal? (next-head (snake "down" (list (posn 1 1))))
+ (posn 1 2))
+ (check-equal? (next-head snake0) (posn 2 1))
+
+ (check-equal? (posn-move (posn 1 1) 2 3) (posn 3 4))
+ (check-equal? (posn-move (posn 3 4) 6 0) (posn 9 4))
+ (check-equal? (posn-move (posn 2 8) 0 5) (posn 2 13))
+ (check-equal? (posn-move (posn 2 3) 0 0) (posn 2 3))
+
+ (check-equal? (all-but-last '(1 2 3 4 5 6))
+ '(1 2 3 4 5))
+ (check-equal? (all-but-last (snake-segs snake2))
+ `(,(posn 2 2) ,(posn 2 3)))
+ (check-equal? (all-but-last (list 0)) empty)
+ (check-equal? (all-but-last (list 0 1 2)) (list 0 1))
+
+ ;; testing snake-key-handling
+
+ (check-true (dir? "up"))
+ (check-true (dir? "down"))
+ (check-true (dir? "left"))
+ (check-true (dir? "right"))
+ (check-false (dir? "f"))
+ (check-true (dir? "right"))
+
+ (check-equal? (world-change-dir world1 "left") world1)
+ (check-equal? (world-change-dir world1 "right") right-world1)
+ (check-equal? (world-change-dir world0 "left") left-world0)
+ (check-equal? (world-change-dir world0 "right")
+ (pit (snake "right" (snake-segs (pit-snake world0)))
+ (pit-goos world0)))
+ (check-equal? (world-change-dir world0 "down")
+ (pit (snake "down" (snake-segs (pit-snake world0)))
+ (pit-goos world0)))
+
+ (check-true (opposite-dir? "up" "down"))
+ (check-true (opposite-dir? "left" "right"))
+ (check-true (opposite-dir? "right" "left"))
+ (check-true (opposite-dir? "down" "up"))
+ (check-false (opposite-dir? "left" "down"))
+ (check-false (opposite-dir? "right" "down"))
+ (check-false (opposite-dir? "down" "left"))
+ (check-false (opposite-dir? "up" "right"))
+ (check-true (opposite-dir? "up" "down"))
+ (check-true (opposite-dir? "down" "up"))
+ (check-false (opposite-dir? "up" "up") false)
+ (check-equal? (opposite-dir? "right" "left") true)
+ (check-equal? (opposite-dir? "left" "right") true)
+
+ ;; testing snake rendering
+
+ (check-equal? (snake+scene snake1 MT-SCENE)
+ (place-image HEAD-LEFT-IMG (* 5 SEG-SIZE)
+ (* 5 SEG-SIZE) MT-SCENE))
+ (check-equal? (snake+scene snake2 MT-SCENE)
+ (img+scene (posn 2 2) HEAD-UP-IMG
+ (img+scene (posn 2 3) SEG-IMG
+ (img+scene (posn 2 4) SEG-IMG MT-SCENE))))
+ (check-equal? (snake+scene (snake "up" (list (posn 1 1))) MT-SCENE)
+ (img+scene (posn 1 1) HEAD-UP-IMG MT-SCENE))
+
+ (check-equal? (goo-list+scene (list goo1) MT-SCENE)
+ (place-image GOO-IMG (* 5 SEG-SIZE)
+ (* 5 SEG-SIZE) MT-SCENE))
+ (check-equal? (goo-list+scene goo-list1 MT-SCENE)
+ (img-list+scene (list (posn 5 5) (posn 4 8) (posn 6 9) (posn 1 1) (posn 1 9))
+ GOO-IMG MT-SCENE))
+
+ (check-equal? (img-list+scene (list (posn 3 3) (posn 4 4)) SEG-IMG MT-SCENE)
+ (place-image SEG-IMG (* 3 SEG-SIZE) (* 3 SEG-SIZE)
+ (place-image SEG-IMG (* 4 SEG-SIZE) (* 4 SEG-SIZE) MT-SCENE)))
+ (check-equal? (img-list+scene (list (posn 1 1) (posn 10 10)) SEG-IMG MT-SCENE)
+ (place-image SEG-IMG (* 1 SEG-SIZE) (* 1 SEG-SIZE)
+ (place-image SEG-IMG (* 10 SEG-SIZE) (* 10 SEG-SIZE) MT-SCENE)))
+ (check-equal? (img-list+scene (list (posn 1 1)) GOO-IMG MT-SCENE)
+ (place-image GOO-IMG SEG-SIZE SEG-SIZE
+ (img-list+scene empty GOO-IMG MT-SCENE)))
+
+ (check-equal? (img+scene (posn 4 3) SEG-IMG MT-SCENE)
+ (place-image SEG-IMG (* 4 SEG-SIZE) (* 3 SEG-SIZE) MT-SCENE))
+ (check-equal? (img+scene (posn 5 2) GOO-IMG MT-SCENE)
+ (place-image GOO-IMG (* 5 SEG-SIZE) (* 2 SEG-SIZE) MT-SCENE))
+ (check-equal? (img+scene (posn 1 1) SEG-IMG MT-SCENE)
+ (place-image SEG-IMG SEG-SIZE SEG-SIZE MT-SCENE))
+
+ ;; testing the endgame
+ (check-false (self-colliding? snake1))
+ (check-false (self-colliding? snake2))
+ (check-false (self-colliding? wall-snake))
+ (check-true (self-colliding? self-eating-snake))
+ (check-false (self-colliding? snake0))
+ (check-true (self-colliding? (snake (snake-dir snake0)
+ (cons (posn 1 1)
+ (snake-segs snake0)))))
+
+ (check-false (wall-colliding? snake1))
+ (check-false (wall-colliding? snake2))
+ (check-false (wall-colliding? self-eating-snake))
+ (check-true (wall-colliding? wall-snake))
+ (check-true
+ (wall-colliding? (snake "right" (list (posn (/ WIDTH-PX SEG-SIZE) 0)))))
+ (check-true
+ (wall-colliding? (snake "down" (list (posn 0 (/ HEIGHT-PX SEG-SIZE))))))
+ (check-true
+ (wall-colliding? (snake "up" (list (posn 1 0)))))
+ (check-equal? (wall-colliding? (snake "right"
+ (list (posn 0 1))))
+ true)
+ (check-equal? (wall-colliding? (snake "right"
+ (list (posn 1 0))))
+ true)
+ (check-equal? (wall-colliding? (snake "right"
+ (list (posn 1 1))))
+ false)
+ (check-true (wall-colliding? (snake "right" (list (posn 1 SIZE)))))
+
+
+ ;; testing utilities functions
+
+ (check-false (posn=? (posn 1 1) (posn 2 2)))
+ (check-false (posn=? (posn 1 2) (posn 2 1)))
+ (check-true (posn=? (posn 3 4) (posn 3 4)))
+ (check-true (posn=? (posn 2 2) (posn 2 2)))
+ (check-equal? (posn=? (posn 1 2) (posn 1 1)) false)
+ (check-equal? (posn=? (posn 1 2) (posn 1 2)) true)
+ (check-equal? (posn-move (posn 0 0) 2 3) (posn 2 3))
+
+ (check-equal? (snake-head snake1) (posn 5 5))
+ (check-equal? (snake-head snake2) (posn 2 2))
+ (check-equal? (snake-head snake0) (posn 1 1))
+
+ (check-equal? (snake-body snake1) empty)
+ (check-equal? (snake-body snake0) empty)
+ (check-equal? (snake-body snake2) (list (posn 2 3) (posn 2 4)))
+
+ (check-equal? (snake-change-dir snake0 "up")
+ (snake "up" (list (posn 1 1))))
+ (check-equal? (snake-change-dir snake1 "down")
+ (snake "down" (list (posn 5 5))))
+ (check-equal? (snake-change-dir snake2 "left")
+ (snake "left" (list (posn 2 2) (posn 2 3) (posn 2 4))))
+
+ (check-true (rotten? (goo (posn 1 2) 0)))
+ (check-true (rotten? (goo (posn 6 9) 0)))
+ (check-true (rotten? (goo (posn 23 2) 0)))
+
+ (check-false (rotten? (goo (posn 1 2) 2)))
+ (check-false (rotten? (goo (posn 3 45) 45334534)))
+ (check-false (rotten? (goo (posn 2 4) 9)))
+
+ (check-equal? (decay (goo (posn 1 2) 2))
+ (goo (posn 1 2) 1))
+ (check-equal? (decay (goo (posn 132 0) 2))
+ (goo (posn 132 0) 1))
+ (check-equal? (decay (goo (posn 1 2) 10))
+ (goo (posn 1 2) 9))
+ (check-equal? (decay (goo (posn 3 5) 8))
+ (goo (posn 3 5) 7))
+
+ "all tests run")
A EjemplosRacket/SICP/Capitulo1/.auctex-auto/Capitulo1.el => EjemplosRacket/SICP/Capitulo1/.auctex-auto/Capitulo1.el +41 -0
@@ 0,0 1,41 @@
+(TeX-add-style-hook
+ "Capitulo1"
+ (lambda ()
+ (TeX-add-to-alist 'LaTeX-provided-class-options
+ '(("article" "11pt")))
+ (TeX-add-to-alist 'LaTeX-provided-package-options
+ '(("inputenc" "utf8") ("fontenc" "T1") ("ulem" "normalem")))
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "href")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperref")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperimage")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperbaseurl")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "nolinkurl")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "url")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "path")
+ (add-to-list 'LaTeX-verbatim-macros-with-delims-local "path")
+ (TeX-run-style-hooks
+ "latex2e"
+ "article"
+ "art11"
+ "inputenc"
+ "fontenc"
+ "graphicx"
+ "longtable"
+ "wrapfig"
+ "rotating"
+ "ulem"
+ "amsmath"
+ "amssymb"
+ "capt-of"
+ "hyperref")
+ (LaTeX-add-labels
+ "sec:org4c82b8d"
+ "sec:org3c76fd6"
+ "sec:orgb15cd54"
+ "sec:org29991fc"
+ "sec:org9b56e2a"
+ "sec:org27f2481"
+ "sec:orgf5e0361"
+ "sec:orgc1d028d"))
+ :latex)
+
M EjemplosRacket/SICP/Capitulo1/Capitulo1.org => EjemplosRacket/SICP/Capitulo1/Capitulo1.org +3 -2
@@ 1,14 1,15 @@
#+TITLE: Capítulo 1
#+AUTHOR: Camilo Meza Gaete
+#+OPTIONS: toc:nil num:nil
* Definiciones
Las expresiones primitivas en el caso de LISP corresponden a átomos (que
representan los símbolos), listas (que contienen los símbolos), y la
-función λ (que es el constructor mímino de esos símbolos).
+función \(\lambda\) (que es el constructor mímino de esos símbolos).
Contiene definiciones de operaciones aritméticas, definición de
-procedimientos desde λ, números decimales, enteros, racionales y
+procedimientos desde \(\lambda\), números decimales, enteros, racionales y
símbolos de caracteres.
Un ejemplo de combinación de estos componentes primitivos:
A EjemplosRacket/SICP/Capitulo1/Capitulo1.tex => EjemplosRacket/SICP/Capitulo1/Capitulo1.tex +348 -0
@@ 0,0 1,348 @@
+% Created 2022-06-16 Thu 09:25
+% Intended LaTeX compiler: pdflatex
+\documentclass[11pt]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{graphicx}
+\usepackage{longtable}
+\usepackage{wrapfig}
+\usepackage{rotating}
+\usepackage[normalem]{ulem}
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{capt-of}
+\usepackage{hyperref}
+\author{Camilo Meza Gaete}
+\date{\today}
+\title{Capítulo 1}
+\hypersetup{
+ pdfauthor={Camilo Meza Gaete},
+ pdftitle={Capítulo 1},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 27.2 (Org mode 9.6)},
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+
+\section*{Definiciones}
+\label{sec:org0e88ee1}
+
+Las expresiones primitivas en el caso de LISP corresponden a átomos (que
+representan los símbolos), listas (que contienen los símbolos), y la
+función \(\lambda\) (que es el constructor mímino de esos símbolos).
+
+Contiene definiciones de operaciones aritméticas, definición de
+procedimientos desde \(\lambda\), números decimales, enteros, racionales y
+símbolos de caracteres.
+
+Un ejemplo de combinación de estos componentes primitivos:
+
+\begin{verbatim}
+(+ 148 998)
+\end{verbatim}
+
+La parte de la izquierda de la combinación es llamada operador, y hacia la
+derecha se dejan los operandos. de esta manera las combinaciones pueden tener
+distinta cantidad de argumentos y operandos según requiera la complejidad de
+la abstracción.
+
+\section*{Complicando las expresiones}
+\label{sec:org3367b46}
+
+Las combinaciones se pueden anidar y complicar tanto como sea necesario, dando
+origen a esto:
+
+\begin{verbatim}
+(+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))
+\end{verbatim}
+
+Que humanamente es algo más confuso, y para facilitar su lectura, se
+utiliza \emph{pretty-printing}:
+
+\begin{verbatim}
+(+ (* 3
+ (+ (* 2 4)
+ (+ 3 5)))
+ (+ (- 10 7)
+ 6))
+\end{verbatim}
+
+El intérprete es indiferente a estos cambios en el formato, son sólo para
+ayudar a las personas que leen el código fuente en que estas convenciones se
+implementan.
+
+Cuando recibe una combinación, el intérprete seguirá su ciclo:
+\begin{itemize}
+\item Leerá la combinación desde los paréntesis más internos a los más externos.
+\item Evaluará todas las expresiones siguiendo el mismo orden.
+\item Imprimirá una respuesta a la interfaz, realizando el cálculo de ser
+necesario.
+\end{itemize}
+
+A este ciclo se lo conoce por sus siglas en inglés \textbf{REPL} (Read-Evaluate-Print Loop).
+
+\section*{Nombrando elementos}
+\label{sec:org072f65c}
+
+Consiste en asociar un átomo a otro por medio de una expresión, se denomina
+\textbf{variable} a aquello que queremos nombrar y \textbf{valor} al objeto asignado.
+
+\begin{verbatim}
+(define radio 5)
+radio
+\end{verbatim}
+
+Un ejemplo de uso de definiciones para determinar el área de una
+circunferencia:
+
+\begin{verbatim}
+(define pi 3.14159)
+(define radio 10)
+(define area (* pi (* radio radio)))
+area
+\end{verbatim}
+
+Gracias al primitivo \textbf{define} podemos abstraer relaciones cada vez más complejas
+entre entidades en LISP.
+
+\section*{Evaluación y combinación}
+\label{sec:orga03e463}
+
+Como ya se dijo, el intérprete evalúa desde la parte más interior de las
+combinaciones y siguiendo la estructura de evaluar el procedimiento de la
+izquierda y aplicando los argumentos hacia la derecha.
+
+\begin{verbatim}
+(* (+ 2 (* 4 6))
+ (+ 5 3 5))
+\end{verbatim}
+
+En el ejemplo de arriba, primero el producto entre 4 y 6, luego las adiciones, y
+finalmente el producto entre 26 y 13.
+
+Esta regla general se llama \emph{aplicación} y se lleva a cabo en general; la única
+salvedad son las \textbf{formas especiales} (por ejemplo: la función \emph{define}). Estas
+formas especiales tienen sus propias reglas de aplicación, lo que permite tener
+una sintaxis más simple en general y pequeños añadidos que permiten la
+flexibilidad de LISP.
+
+\section*{Procedimientos compuestos}
+\label{sec:org5c8ed4d}
+Con estos conjuntos de ideas y posibilidades, llegamos al punto en que se logran
+definir procedimientos.
+
+Si pensamos en la instrucción general para determinar el cuadrado de un
+determinado número, se debe multiplicar el número por sí mismo. En LISP eso se
+expresa de la siguiente manera:
+
+\begin{verbatim}
+(define (cuadrado x)
+ (* x x))
+\end{verbatim}
+
+Primero se utiliza la forma especial \textbf{define}, luego se diseña la estructura de
+nuestra función con (\emph{nombre} \emph{argumentos}) y posteriormente un \emph{cuerpo}. Donde
+nombre es un símbolo que nos permite llamar al procedimiento, los argumentos son
+aquellos símbolos que acepta, y el cuerpo aquello que nuestro procedimiento hará
+con sus argumentos.
+
+Ahora lo podemos evaluar en un número natural conocido, de manera que se
+corrobore que el procedimiento hace aquello para lo que se diseñó.
+
+\begin{verbatim}
+(define (cuadrado x)
+ (* x x))
+(cuadrado 6)
+\end{verbatim}
+
+Como ya tenemos un procedimiento definido, lo podemos incluir en la definición
+de uno nuevo, por ejemplo la suma de cuadrados \(X^{2}+Y^{2}\).
+
+\begin{verbatim}
+(define (cuadrado x)
+ (* x x))
+(define (suma-de-cuadrados x y)
+ (+ (cuadrado x) (cuadrado y)))
+(suma-de-cuadrados 3 4)
+\end{verbatim}
+
+Y realizar un procedimiento complejo tal que:
+\begin{verbatim}
+(define (cuadrado x)
+ (* x x))
+(define (suma-de-cuadrados x y)
+ (+ (cuadrado x) (cuadrado y)))
+(define (f a)
+ (suma-de-cuadrados (+ a 3) (* a 4)))
+(f 5)
+\end{verbatim}
+
+\begin{verbatim}
+464
+\end{verbatim}
+
+
+Entonces, los procedimientos en conjunto se terminan comportando igual que los
+primitivos (podemos combinarlos y anidarlos sin un límite), gracias a nuestras
+reglas de evaluación.
+
+\section*{Modelo de sustitución}
+\label{sec:orgb6b8507}
+Imaginemos la secuencia de sustitución que realiza nuestro REPL de acuerdo a la
+\hyperref[procedimiento-compuesto]{definición de este código}:
+
+Cuando se invoca la combinación \textbf{(f 5)}, lo primero que se busca es la
+definición del símbolo f en el entorno.
+
+En nuestro ejemplo, \textbf{``f''} es un procedimiento que toma como argumento \textbf{``a''}, y
+cuyo cuerpo es \emph{``(suma-de-cuadrados (+ a 3) (* a 4))''}.
+
+Se reemplaza el parámetro \textbf{``a''} con el valor entregado al procedimiento f,
+quedando \emph{``(suma-de-cuadrados (+ 5 3) (* 5 4))''}.
+
+Para evaluar nuestro procedimiento llamado \textbf{suma-de-cuadrados} primero debemos
+evaluar sus argumentos. La suma (+ 5 3) nos entrega el valor 8 para el argumento
+``x'', mientras que el producto (* 5 4) nos entrega el valor 20 para el argumento
+``y''.
+
+Finalmente, debemos aplicar la definición de \textbf{suma-de-cuadrados} que se reduce a
+la evaluación de una combinación con dos operandos y un operador. En esa
+situación nos encontramos los siguientes problemas: Debemos evaluar el operador
+para obtener el procedimiento que se aplicará, y debemos evaluar los operandos
+para obtener los argumentos.
+
+El proceso que se ha descrito se conoce como el \emph{modelo de sustitución} para la
+aplicación de procedimientos. Si bien este modelo nos permite conocer el
+\textbf{significado} de la aplicación de procedimientos, se deben destacar dos puntos:
+
+\begin{itemize}
+\item Esto es sólo un ejemplo para abstraer el modo en que funciona la aplicación de
+procedimientos, no para explicar el funcionamiento del intérprete. Ya que la
+sustitución que se realiza es más bien el reemplazo de los argumentos por los
+parámetros formales del entorno local.
+\item Los modelos que se están presentando necesitarán cubrir una mayor complejidad,
+por que se deberán ir reemplazando a medida que se requiera.
+\end{itemize}
+
+\section*{Orden aplicativo u orden normal}
+\label{sec:org4b56fae}
+De acuerdo al orden de evaluación que se presentó en la sección \hyperref[sec:orga03e463]{Evaluación y combinación}, el intérprete evalúa primero el operador y los operandos para luego
+aplicar el procedimiento a los argumentos resultantes. Aunque esta \emph{no} es la
+única forma de realizar una evaluación.
+
+Un modelo alternativo de evaluación puede ser no evaluar los operandos \textbf{hasta}
+que se necesiten sus valores. En este caso se sustituyen las expresiones de
+operandos por parámetros hasta tener una expresión compuesta exclusivamente de
+operadores primitivos.
+
+Por ejemplo, al evaluar \textbf{(f 5)} tendríamos la siguiente expansión:
+
+\begin{verbatim}
+(suma-de-cuadrados (+ 5 3) (* 5 4))
+
+(+ (cuadrado (+ 5 3)) (cuadrado (* 5 4)) )
+
+(+ (* (+ 5 3) (+ 5 3)) (* (* 5 4) (* 5 4)) )
+\end{verbatim}
+
+Seguido de las reducciones:
+
+\begin{verbatim}
+(+ (* 8 8) (* 20 20) )
+
+(+ 64 400 )
+
+464
+\end{verbatim}
+
+Nos entrega el mismo resultado, siguiendo un procedimiento diferente. En
+particular la evaluación de los operandos ``x'' e ``y'' se realiza dos veces,
+correspondiente a la expresión \texttt{(* x x)} en la definición de la función
+\texttt{(cuadrado x)}.
+
+El método de orden de evaluación en que primero se expande la definición y luego
+se evalúa se llama \textbf{orden normal}, en contraste con el orden en que se evalúan
+los argumentos y después se aplica que se llama \textbf{orden aplicativo}.
+
+LISP usa evaluación de orden aplicativo pues así ahorra estar evaluando más de
+una vez la misma expresión, lo que le permite obtener algo de eficiencia en
+estos procedimientos. Además, la evaluación de orden normal se vuelve mucho más
+compleja de trabajar cuando se deja de usar el modelo de sustitución.
+
+\section*{Expresiones condicionales y predicados}
+\label{sec:org60759cd}
+Sin embargo hasta ahora no tenemos una forma de evaluar expresiones más
+complejas como, por ejemplo, el valor absoluto de un número. Esto está definido
+matemáticamente de la siguiente manera:
+
+\[|x| \begin{cases} x ,&\text{si } x>0 \\ 0 ,&\text{si } x=0 \\ -x ,&
+\text{si } x<0\end{cases}\]
+
+El análisis de estos casos se puede dar a través de una forma especial en LISP
+asociada a la función \texttt{cond} (que viene de \emph{condicional}). Y aplicando el
+ejemplo, sería así:
+
+\begin{verbatim}
+(define (abs x)
+ (cond ((> x 0) x)
+ ((= x 0) 0)
+ ((< x 0) (- x))))
+(abs -10)
+\end{verbatim}
+
+\begin{verbatim}
+10
+\end{verbatim}
+
+
+Así, tenemos expresiones condicionales que siguen el patrón detallado a
+continuación:
+
+\[(cond (\langle p_{n} \rangle \langle e_{n} \rangle))\]
+
+Donde el símbolo \emph{cond} invoca a la función que evaluará las cláusulas que le
+siguen; dichas cláusulas están compuestas por un \emph{predicado}, simbolizado por
+\(p_{n}\) en el patrón anterior. El valor del predicado es booleano: sólo puede
+ser interpretado como \texttt{verdadero} o \texttt{falso} (en scheme, estos valores se
+representan con las constantes \#t o \#f respectivamente).
+
+El proceso de evaluación es el siguiente: Se evaluará el primer predicado, si
+éste es \#f entonces se continuará con el que le sucede hasta que se encuentra un
+predicado cuyo valor es \#t. En este momento, el intérprete devolverá el valor de
+la expresión consecuente \(e_{n}\) que corresponda. De no haber predicados que
+cumplan con la condición de ser \#t entonces la condición \emph{cond} quedará
+indefinida.
+
+Una forma alternativa de definir valor absoluto sería:
+
+\begin{verbatim}
+(define (abs x)
+ (cond ((< x 0) (- x))
+ (else x)))
+
+(abs -45)
+\end{verbatim}
+
+Que equivaldría a la expresión ``Si X es menor que 0, devuelve el inverso aditivo
+de X; de otro modo, devuelve X''. En este caso, \texttt{else} es un símbolo especial que
+se puede usar para omitir el predicado de una condición, se considera siempre \#t
+por lo que devolverá el valor de la expresión consecuente que le suceda.
+
+Existe una tercera forma de escribir la definición de valor absoluto:
+
+\begin{verbatim}
+(define (abs x)
+ (if (< x 0)
+ (- x)
+ x))
+
+(abs -3)
+\end{verbatim}
+
+Donde if es un símbolo que llama a una función restringida de \emph{cond} donde sólo
+hay un predicado con su respectiva expresión consecuente y luego está la
+expresión consecuente de un \texttt{else}. Este condicional es útil cuando hay sólo dos
+casos en el análisis que evaluar.
+\end{document}
A LaTeX/Evaluaciones/InfoGeneral.tex => LaTeX/Evaluaciones/InfoGeneral.tex +35 -0
@@ 0,0 1,35 @@
+%=========================================================
+%------------ Encabezado ---------------------------------
+%=========================================================
+\pagestyle{headandfoot}%{head}%empty
+\firstpageheader{}{}{}
+\runningheader{\disciplina}{}{\evaluacion}
+\runningheadrule
+\firstpagefooter{\copyright Camilo Meza}{}{Página \thepage\ de \numpages}
+\runningfooter{\iflastpage{Otras plantillas en \href{https://}{Repositorio}}{\copyright Camilo Meza}}{}{Página \thepage\ de \numpages}
+\runningfootrule
+
+% ===============================================================
+%----- Información sobre la evaluación -------------------------
+\nombreColegio{Colegio Universal San Francisco de Asís}
+\logoInst{\includegraphics[scale=0.17]{Figs/ifbajequie.jpg}}
+\Campus{Talagante} % Si no se ocupa, se puede comentar.
+\nombreCurso{Nombre del curso} % Si no se ocupa, se puede comentar.
+\nomeDisciplina{nome da disciplina}
+\DatosPrueba{}
+\TerminoPrueba{}
+\Semestre{}
+\nombreProfesor{Nombre del profesor}
+\Alumno{}
+\matriculaAlumno{}
+% Si no se quiere una imagen de fondo, comentar la línea de abajo.
+\imagenFondo{\includegraphics[height=\paperheight]{Figs/Fundo/aranha2.jpeg}}
+
+% ===============================================================
+%Instrucciones para la evaluación, dejar en blanco si no se quiere colocar.
+\instUno{Su evaluación consta de \numquestions \ preguntas,\ \numpoints \ sumando \ puntos. \textbf{Se permite el uso de calculadora.}}
+\instDos{\textbf{El uso de teléfono celular durante la evaluación se interpreta como copia independiente de su uso, por lo que se retira la evaluación y se revisa hasta ese momento.}}
+\instTres{\textbf{Respuestas sin justificación o que no incluya los cálculos necesarios no recibirán el puntaje.}}
+\instCuatro{Si tiene dudas, levante la mano o realice la pregunta en voz alta.}
+\instCinco{}
+\instSeis{}