summaryrefslogtreecommitdiffstats
path: root/chapter5
diff options
context:
space:
mode:
Diffstat (limited to 'chapter5')
-rw-r--r--chapter5/guess.rkt75
-rw-r--r--chapter5/loco.rkt59
-rw-r--r--chapter5/resources/caroille.pngbin0 -> 886 bytes
-rw-r--r--chapter5/resources/caroille.svg125
-rw-r--r--chapter5/resources/ufo-fart.pngbin0 -> 868 bytes
-rw-r--r--chapter5/resources/ufo-fart.svg188
-rw-r--r--chapter5/resources/zarking-ufo.pngbin0 -> 1337 bytes
-rw-r--r--chapter5/resources/zarking-ufo.svg128
-rw-r--r--chapter5/ufo.rkt86
9 files changed, 661 insertions, 0 deletions
diff --git a/chapter5/guess.rkt b/chapter5/guess.rkt
new file mode 100644
index 0000000..f7a117a
--- /dev/null
+++ b/chapter5/guess.rkt
@@ -0,0 +1,75 @@
+#lang racket
+(require 2htdp/universe 2htdp/image)
+
+(struct interval (small big guesses))
+
+;;; constants
+(define TEXT-SIZE 12)
+(define HELP-TEXT
+ (text "↑ for larger numbers, ↓ for smaller ones"
+ TEXT-SIZE
+ "blue"))
+(define HELP-TEXT2
+ (text "Press = when your number is guessed; q to quit."
+ TEXT-SIZE
+ "blue"))
+(define COLOR "red")
+(define WIDTH (+ (image-width HELP-TEXT2) 10))
+(define HEIGHT 150)
+(define SIZE 72)
+(define TEXT-X 3)
+(define TEXT-UPPER-Y 10)
+(define TEXT-LOWER-Y 135)
+(define GUESSES-SIZE 12)
+(define GUESSES-COLOR "green")
+(define MT-SC
+ (place-image/align
+ HELP-TEXT TEXT-X TEXT-UPPER-Y "left" "top"
+ (place-image/align
+ HELP-TEXT2 TEXT-X TEXT-LOWER-Y "left" "bottom"
+ (empty-scene WIDTH HEIGHT))))
+
+;; main
+(define (start lower upper)
+ (big-bang (interval lower upper 0)
+ (on-key deal-with-guess)
+ (to-draw render)
+ (stop-when single? render-last-scene)))
+
+;; key events
+(define (deal-with-guess w key)
+ (cond [(key=? key "up") (bigger w)]
+ [(key=? key "down") (smaller w)]
+ [(key=? key "q") (stop-with w)]
+ [(key=? key "=") (stop-with w)]
+ [else w]))
+
+(define (smaller w)
+ (interval (interval-small w)
+ (max (interval-small w) (sub1 (guess w)))
+ (+ 1 (interval-guesses w))))
+
+(define (bigger w)
+ (interval (min (interval-big w) (add1 (guess w)))
+ (interval-big w)
+ (+ 1 (interval-guesses w))))
+
+(define (guess w)
+ (quotient (+ (interval-small w) (interval-big w)) 2))
+
+(define (render w)
+ (overlay (overlay/offset
+ (text (number->string (guess w)) SIZE COLOR) 0 40
+ (text (number->string (interval-guesses w))
+ GUESSES-SIZE GUESSES-COLOR))
+ MT-SC))
+
+(define (render-last-scene w)
+ (overlay (overlay/offset
+ (text "End" SIZE COLOR) 0 40
+ (text (number->string (interval-guesses w))
+ GUESSES-SIZE GUESSES-COLOR))
+ MT-SC))
+
+(define (single? w)
+ (= (interval-small w) (interval-big w)))
diff --git a/chapter5/loco.rkt b/chapter5/loco.rkt
new file mode 100644
index 0000000..977c976
--- /dev/null
+++ b/chapter5/loco.rkt
@@ -0,0 +1,59 @@
+#lang racket
+(require 2htdp/universe 2htdp/image)
+
+(define WIDTH 300)
+(define HEIGHT 300)
+(define CAROILLE (bitmap/file "resources/caroille.png"))
+(define CAROILLE-WIDTH (image-width CAROILLE))
+
+;;;
+;;; If the car is placed at X = 1/2 its width, its back will be
+;;; touching the left edge of the World.
+;;;
+;;; If the car is place at X = - 1/2 its width, its front will be touching
+;;; the left edge of the World.
+;;;
+(define CAROILLE-WIDTH-HALF (/ CAROILLE-WIDTH 2.0))
+
+;;; Structure to represent the X position of two cars in animation.
+(struct cars (one two))
+
+(define (caroille-past-right-edge? pos)
+ (> pos (- WIDTH CAROILLE-WIDTH-HALF)))
+
+(define (caroille-fully-past-right-edge? pos)
+ (>= pos (+ WIDTH CAROILLE-WIDTH-HALF)))
+
+(define (caroille-fully-past-left-edge? pos)
+ (>= pos CAROILLE-WIDTH-HALF))
+
+(define (caroille-fully-inside? pos)
+ (and (caroille-fully-past-left-edge? pos)
+ (not (caroille-past-right-edge? pos))))
+
+(define (move caroilles)
+ (let ((caroille-one (cars-one caroilles))
+ (caroille-two (cars-two caroilles)))
+ (cond
+ ;; Case set I - one of the cars is fully inside.
+ ((caroille-fully-inside? caroille-one)
+ (cars (+ 1 caroille-one) caroille-two))
+ ((caroille-fully-inside? caroille-two)
+ (cars caroille-one (+ 1 caroille-two)))
+ ;; Case set II - one of the cars disappeared into the right edge.
+ ((caroille-fully-past-right-edge? caroille-one)
+ (cars (- CAROILLE-WIDTH-HALF) (+ 1 caroille-two)))
+ ((caroille-fully-past-right-edge? caroille-two)
+ (cars (+ 1 caroille-one) (- CAROILLE-WIDTH-HALF)))
+ ;; Case else - Both cars are partially out.
+ (else (cars (+ 1 caroille-one) (+ 1 caroille-two))))))
+
+(define (draw-cars caroilles)
+ (place-image CAROILLE (cars-one caroilles) (/ HEIGHT 2)
+ (place-image CAROILLE (cars-two caroilles) (/ HEIGHT 2)
+ (empty-scene WIDTH HEIGHT))))
+
+(define (start)
+ (big-bang (cars CAROILLE-WIDTH-HALF (- CAROILLE-WIDTH-HALF))
+ (on-tick move)
+ (to-draw draw-cars)))
diff --git a/chapter5/resources/caroille.png b/chapter5/resources/caroille.png
new file mode 100644
index 0000000..052cc58
--- /dev/null
+++ b/chapter5/resources/caroille.png
Binary files differ
diff --git a/chapter5/resources/caroille.svg b/chapter5/resources/caroille.svg
new file mode 100644
index 0000000..eb4db63
--- /dev/null
+++ b/chapter5/resources/caroille.svg
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="80"
+ height="80"
+ viewBox="0 0 21.166666 21.166667"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="caroille.svg">
+ <title
+ id="title3715">caroille</title>
+ <defs
+ id="defs2">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="1.8428503 : 18.575596 : 1"
+ inkscape:vp_y="0 : 999.99999 : 0"
+ inkscape:vp_z="28.301183 : 18.575596 : 1"
+ inkscape:persp3d-origin="15.072016 : 14.165874 : 1"
+ id="perspective3723" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="72.620745"
+ inkscape:cy="61.452165"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ showguides="false"
+ inkscape:window-width="1280"
+ inkscape:window-height="800"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>caroille</dc:title>
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:date>2018-04-02</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>rsiddharth &lt;s@ricketyspace.net&gt;</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>car</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-275.83332)">
+ <g
+ id="g3759"
+ transform="matrix(1.6602564,0,0,1.6602564,-10.597836,-177.21015)"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <rect
+ ry="0.8018086"
+ style="stroke-width:0.26458332"
+ y="277.95703"
+ x="7.550364"
+ height="3.4745038"
+ width="10.423512"
+ id="rect3717" />
+ <circle
+ style="stroke-width:0.26458332"
+ r="1.1692964"
+ cy="281.3313"
+ cx="9.254199"
+ id="path3719" />
+ <circle
+ id="circle3721"
+ cx="15.969346"
+ cy="281.49835"
+ r="1.1692964"
+ style="stroke-width:0.26458332" />
+ <rect
+ ry="1.1693041"
+ style="stroke-width:0.24171647"
+ y="275.9859"
+ x="9.7219286"
+ height="2.7395124"
+ width="5.9133382"
+ id="rect3753" />
+ </g>
+ </g>
+</svg>
diff --git a/chapter5/resources/ufo-fart.png b/chapter5/resources/ufo-fart.png
new file mode 100644
index 0000000..13d1c4a
--- /dev/null
+++ b/chapter5/resources/ufo-fart.png
Binary files differ
diff --git a/chapter5/resources/ufo-fart.svg b/chapter5/resources/ufo-fart.svg
new file mode 100644
index 0000000..cf86021
--- /dev/null
+++ b/chapter5/resources/ufo-fart.svg
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="50"
+ height="50"
+ viewBox="0 0 13.229166 13.229167"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="ufo-gas.svg">
+ <title
+ id="title10">UFO Fart</title>
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.9195959"
+ inkscape:cx="19.4951"
+ inkscape:cy="22.795424"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1280"
+ inkscape:window-height="800"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>UFO Fart</dc:title>
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:date>2018-04-17</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>rsiddharth &lt;s@ricketyspace.net&gt;</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-283.77082)">
+ <g
+ id="g160">
+ <circle
+ style="fill:#ffffff;stroke-width:0.09590441"
+ r="0.071714237"
+ cy="288.4332"
+ cx="4.474267"
+ id="circle38" />
+ </g>
+ <g
+ id="g202"
+ inkscape:export-xdpi="76.796082"
+ inkscape:export-ydpi="76.796082">
+ <g
+ id="g180">
+ <circle
+ style="stroke-width:0.20158729"
+ r="0.53453904"
+ cy="285.58438"
+ cx="6.4067097"
+ id="circle20" />
+ <circle
+ style="fill:#ffffff;stroke-width:0.06017532"
+ r="0.044997171"
+ cy="285.91135"
+ cx="6.4122667"
+ id="circle22" />
+ </g>
+ <g
+ id="g132">
+ <circle
+ style="stroke-width:0.42837298"
+ r="1.1358955"
+ cy="294.70496"
+ cx="2.898797"
+ id="circle42" />
+ <circle
+ style="fill:#ffffff;stroke-width:0.12787254"
+ r="0.095618986"
+ cy="295.48981"
+ cx="2.5584671"
+ id="circle44" />
+ </g>
+ <circle
+ id="circle36"
+ cx="4.920023"
+ cy="287.93967"
+ r="0.85192156"
+ style="stroke-width:0.32127973"
+ transform="translate(0,9.1666667e-6)" />
+ <g
+ id="g176">
+ <circle
+ style="stroke-width:0.32127973"
+ r="0.85192156"
+ cy="287.83945"
+ cx="8.294301"
+ id="circle48" />
+ <circle
+ style="fill:#ffffff;stroke-width:0.09590441"
+ r="0.071714237"
+ cy="288.35379"
+ cx="8.6660032"
+ id="circle50" />
+ </g>
+ <g
+ id="g136">
+ <circle
+ id="path12"
+ cx="3.9511709"
+ cy="291.24713"
+ r="1.2528259"
+ style="stroke-width:0.47247022" />
+ <circle
+ id="path14"
+ cx="3.5711958"
+ cy="292.09247"
+ r="0.10546212"
+ style="fill:#ffffff;stroke-width:0.1410359" />
+ </g>
+ <g
+ id="g152">
+ <circle
+ style="stroke-width:0.47247022"
+ r="1.2528259"
+ cy="291.31396"
+ cx="9.7308741"
+ id="circle54" />
+ <circle
+ style="fill:#ffffff;stroke-width:0.1410359"
+ r="0.10546212"
+ cy="292.10916"
+ cx="10.269638"
+ id="circle56" />
+ </g>
+ <g
+ id="g156">
+ <circle
+ id="circle66"
+ cx="10.549387"
+ cy="294.57132"
+ r="1.1358955"
+ style="stroke-width:0.42837298" />
+ <circle
+ id="circle68"
+ cx="10.976822"
+ cy="295.35028"
+ r="0.095618986"
+ style="fill:#ffffff;stroke-width:0.12787254" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/chapter5/resources/zarking-ufo.png b/chapter5/resources/zarking-ufo.png
new file mode 100644
index 0000000..bd5eb43
--- /dev/null
+++ b/chapter5/resources/zarking-ufo.png
Binary files differ
diff --git a/chapter5/resources/zarking-ufo.svg b/chapter5/resources/zarking-ufo.svg
new file mode 100644
index 0000000..84b8844
--- /dev/null
+++ b/chapter5/resources/zarking-ufo.svg
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ viewBox="0 0 26.458333 26.458334"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3pre0 (0ab9bec, 2018-03-03)"
+ sodipodi:docname="zarking-ufo.svg">
+ <title
+ id="title4518">Zarking UFO</title>
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="52.159535"
+ inkscape:cy="240.12864"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1280"
+ inkscape:window-height="800"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Zarking UFO</dc:title>
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:date>2018-03-09</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>rsiddharth &lt;s@ricketyspace.net&gt;</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-270.54165)">
+ <path
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+ id="path4602"
+ sodipodi:type="arc"
+ sodipodi:cx="16.591591"
+ sodipodi:cy="284.83923"
+ sodipodi:rx="0.04593695"
+ sodipodi:ry="0.0083521726"
+ sodipodi:start="0"
+ sodipodi:end="3.1415927"
+ sodipodi:open="true"
+ d="m 16.637528,284.83923 a 0.04593695,0.00835217 0 0 1 -0.02297,0.007 0.04593695,0.00835217 0 0 1 -0.04594,0 0.04593695,0.00835217 0 0 1 -0.02297,-0.007" />
+ <g
+ id="g4627"
+ transform="matrix(5.4364839,0,0,5.4364839,-58.979175,-1255.7408)">
+ <path
+ transform="scale(1,-1)"
+ d="m 14.843864,-283.24774 a 1.4941016,1.4941016 0 0 1 -0.747051,1.29393 1.4941016,1.4941016 0 0 1 -1.494102,0 1.4941016,1.4941016 0 0 1 -0.747051,-1.29393"
+ sodipodi:open="true"
+ sodipodi:end="3.1415927"
+ sodipodi:start="0"
+ sodipodi:ry="1.4941016"
+ sodipodi:rx="1.4941016"
+ sodipodi:cy="-283.24774"
+ sodipodi:cx="13.349762"
+ sodipodi:type="arc"
+ id="path4593"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect4600"
+ d="m 11.32607,283.91839 c 1.383215,-10e-6 2.766429,0 4.149644,0 -0.187618,-0.20965 -0.375238,-0.4193 -0.562857,-0.62894 -1.014054,-0.009 -2.028106,-0.0197 -3.04216,-0.0296 -0.181543,0.21952 -0.363085,0.43904 -0.544627,0.65857 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
+ <path
+ d="m 14.445777,283.94208 a 1.0925874,0.37207031 0 0 1 -0.546294,0.32222 1.0925874,0.37207031 0 0 1 -1.092587,0 1.0925874,0.37207031 0 0 1 -0.546294,-0.32222"
+ sodipodi:open="true"
+ sodipodi:end="3.1415927"
+ sodipodi:start="0"
+ sodipodi:ry="0.37207031"
+ sodipodi:rx="1.0925874"
+ sodipodi:cy="283.94208"
+ sodipodi:cx="13.353189"
+ sodipodi:type="arc"
+ id="path4607"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4609"
+ d="m 12.522043,282.31051 c -0.03576,0.11467 -0.06681,0.23061 -0.09375,0.34765 0.02456,0.0134 0.01871,0.058 0.05273,0.0566 0.03764,-0.0375 0.0043,-0.11891 0.06641,-0.13672 l -0.002,-0.0176 c 0.01392,-0.0139 0.03466,0.003 0.04883,0.006 0.01317,-0.006 0.01975,-0.0378 -0.002,-0.0352 -0.01323,-0.0163 0.03655,-0.0357 -0.0039,-0.041 -0.02263,-0.0213 -0.0046,-0.0742 0.0293,-0.0625 0.01962,-0.008 0.0409,-0.0326 0.0078,-0.0449 -0.01308,-0.0169 -0.0161,-0.0415 -0.0059,-0.0605 l -0.04297,-0.0156 -0.04687,-0.006 z"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
+ </g>
+ </g>
+</svg>
diff --git a/chapter5/ufo.rkt b/chapter5/ufo.rkt
new file mode 100644
index 0000000..6f8136c
--- /dev/null
+++ b/chapter5/ufo.rkt
@@ -0,0 +1,86 @@
+#lang racket
+(require 2htdp/universe 2htdp/image)
+
+;;; world structure
+(struct ufo (x y fart))
+
+;;; constants
+(define WORLD-WIDTH 300)
+(define WORLD-HEIGHT 325)
+(define MOVE-LEN 3)
+(define UFO (bitmap/file "resources/zarking-ufo.png"))
+(define UFO-FART (bitmap/file "resources/ufo-fart.png"))
+(define UFO-WIDTH (image-width UFO))
+(define UFO-HEIGHT (image-height UFO))
+(define UFO-FART-HEIGHT (image-height UFO-FART))
+
+;;; ufo movement functions
+(define (ufo-move-up current-state)
+ (let ((x (ufo-x current-state))
+ (y-up (- (ufo-y current-state) MOVE-LEN))
+ (fart #t))
+ (cond [(>= y-up (+ (/ UFO-HEIGHT 2) (/ UFO-FART-HEIGHT 2)))
+ (ufo x y-up fart)]
+ [else current-state])))
+
+(define (ufo-move-down current-state)
+ (let ((x (ufo-x current-state))
+ (y-down (+ (ufo-y current-state) MOVE-LEN)))
+ (cond [(<= y-down (- (+ WORLD-HEIGHT (/ UFO-FART-HEIGHT 2))
+ (/ UFO-HEIGHT 2)))
+ (ufo x y-down #t)]
+ [else current-state])))
+
+
+(define (ufo-move-left current-state)
+ (let ((x-left (- (ufo-x current-state) MOVE-LEN))
+ (y (ufo-y current-state))
+ (fart #t))
+ (cond [(>= x-left (/ UFO-WIDTH 2))
+ (ufo x-left y fart)]
+ [else current-state])))
+
+(define (ufo-move-right current-state)
+ (let ((x-right (+ (ufo-x current-state) MOVE-LEN))
+ (y (ufo-y current-state))
+ (fart #t))
+ (cond [(<= x-right (- WORLD-WIDTH (/ UFO-WIDTH 2)))
+ (ufo x-right y fart)]
+ [else current-state])))
+
+
+;;; big bang functions
+(define (draw-a-ufo current-state)
+ (place-image (overlay/align/offset
+ "middle" "bottom" UFO 0 35
+ (if (ufo-fart current-state)
+ UFO-FART
+ (circle 0 "outline" "white")))
+ (ufo-x current-state)
+ (ufo-y current-state)
+ (empty-scene WORLD-WIDTH WORLD-HEIGHT)))
+
+(define (add-3-to-posy current-state)
+ (ufo (ufo-x current-state)
+ (+ (ufo-y current-state) 3)))
+
+(define (posy-is-300 current-state)
+ (>= (ufo-y current-state) 300))
+
+(define (move-ufo current-state key)
+ (cond [(key=? key "up") (ufo-move-up current-state)]
+ [(key=? key "down") (ufo-move-down current-state)]
+ [(key=? key "left") (ufo-move-left current-state)]
+ [(key=? key "right") (ufo-move-right current-state)]
+ [else current-state]))
+
+(define (ufo-stopped current-state key)
+ (let ((fart #f))
+ (ufo (ufo-x current-state) (ufo-y current-state) fart)))
+
+;;; the big bang
+(big-bang (ufo (/ WORLD-WIDTH 2) (/ WORLD-HEIGHT 2) #f)
+ (to-draw draw-a-ufo)
+ (on-key move-ufo)
+ (on-release ufo-stopped))
+