CS151L Fall 2013 Week 9: Sample Program 1: M&M Chomper extensions [bitmap] ;;You may NOT remove or change any of the global variables. ;;You MAY add new global (or local) variables. globals[steps mmCountAtStart eatenCount NORTH EAST SOUTH WEST] ;;================================================================ ================================= ;; This sets up the M&Ms you need to teach your turtle to eat in as few steps as possible. ;; There is no need for you to understand this code ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to setup1 let xx [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3] let yy [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21] let orangeLength (length xx) set xx sentence xx [4 4 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 10 10 10 11 11 11 12 12 13 13 14 14 15 15 16 16 17 18 19 20 21 22 23 24] set yy sentence yy [0 3 6 9 12 15 18 21 0 3 6 9 12 15 0 3 6 9 12 0 3 6 9 0 3 6 9 0 3 6 0 3 6 0 3 6 0 3 0 3 0 3 0 3 0 3 0 0 0 0 0 0 0 0] setupAll xx yy orangeLength ask turtles [ setxy 0 max-pycor if (not Show_MM_Background_in_setup) [pen-down] ] set eatenCount 0 end ;;================================================================ ================================= ;; This sets up the M&Ms you need to teach your turtle to eat in as few steps as possible. ;; There is no need for you to understand this code ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to setup2 let xx [1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 15 15 15 15 15 15 15 15 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17 18 18 18 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 20 20 20 20 20 20 20 20 20 20 21 21 21 21 21 21 21 21 21 21 22 22 22 22 22 22 22 22 22 22 22 22 23 23 23 23 23 23 23 24 24 24 24 24 24 24 24 24 24 25 25 25 25 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 28 28 28 28 28 28 29 29 29 29 29 29 29] let yy [7 8 9 10 11 12 13 5 6 7 13 14 15 4 5 15 16 8 9 10 11 12 3 4 16 17 12 13 14 2 3 17 18 14 15 9 10 11 1 2 18 19 7 8 9 11 12 13 0 1 19 17 6 7 13 0 19 17 5 6 8 9 10 11 12 0 19 17 4 5 15 7 8 12 13 0 19 17 15 6 7 13 9 10 0 19 20 17 15 6 13 9 0 20 17 15 6 13 12 0 20 17 15 14 6 12 0 20 19 17 16 14 6 12 0 19 18 16 14 6 12 11 20 0 18 16 14 13 6 11 20 0 18 16 15 13 6 11 20 0 18 17 15 13 6 11 20 19 0 17 15 13 6 11 9 8 19 0 17 15 13 7 6 11 10 9 19 0 17 15 5 4 13 12 8 7 19 0 17 15 14 6 5 12 11 10 9 8 19 1 0 17 16 7 6 19 18 2 1 16 12 11 9 8 7 18 17 3 2 11 10 9 17 16 4 3 14 13 12 16 15 5 4 12 11 10 9 8 15 14 13 7 6 5 13 12 11 10 9 8 7] let orangeLength (length xx) set xx sentence xx [4 4 4 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 20 20 21 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26] set yy sentence yy [6 7 8 5 6 4 5 15 16 3 4 16 14 2 3 14 15 2 2 4 2 4 8 2 4 8 2 4 8 2 4 8 2 4 8 2 4 8 2 4 8 2 4 8 2 4 2 4 2 3 2 4 3 14 13 15 5 4 13 15 14 6 5 8 7 6] setupAll xx yy orangeLength ask turtles [ setxy ((max-pxcor / 2) + 1) max-pycor if (not Show_MM_Background_in_setup) [pen-down] ] set eatenCount 0 end ;;================================================================ ================================= ;; This sets up the M&Ms you need to teach your turtle to eat in as few steps as possible. ;; There is no need for you to understand this code ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to setupExtra let xx [6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 5 6 11 15 19 24 25 4 5 15 25 26 3 4 5 15 25 26 27 2 3 15 27 28 1 2 15 28 29 1 2 3 7 15 23 27 28 29 1 2 7 15 23 28 29 1 2 7 23 28 29 1 2 3 7 23 27 28 29 1 2 7 23 28 29 1 2 7 15 23 28 29 1 2 3 7 15 23 27 28 29 1 2 7 15 23 28 29 1 2 7 23 28 29 2 3 4 7 8 22 23 26 27 28 3 4 8 9 15 21 22 26 27 4 5 9 10 15 20 21 25 26 5 6 7 10 11 15 19 20 23 24 25 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ] let yy [19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 18 18 18 18 18 18 18 17 17 17 17 17 16 16 16 16 16 16 16 15 15 15 15 15 14 14 14 14 14 13 13 13 13 13 13 13 13 13 12 12 12 12 12 12 12 11 11 11 11 11 11 10 10 10 10 10 10 10 10 9999998888888777777777666666655555544444444443 3333333322222222211111111111000000000000000000 0] let orangeLength (length xx) set xx sentence xx [10 11 19 20 9 10 11 19 20 21 8 9 10 11 19 20 21 22 7 8 9 10 11 19 20 21 22 23 14 15 16 14 15 16 14 15 16 10 11 12 13 14 15 16 17 18 19 20 10 11 12 13 14 15 16 17 18 19 20] set yy sentence yy [17 17 17 17 16 16 16 16 16 16 15 15 15 15 15 15 15 15 14 14 14 14 14 14 14 14 14 14 11 11 11 10 10 10 9 9 9 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 4] setupAll xx yy orangeLength ask turtles [ setxy ((max-pxcor / 2)) (max-pycor - 1) if (not Show_MM_Background_in_setup) [pen-down] ] set eatenCount 0 end ;;================================================================ ================================= ;; This sets up the M&Ms you need to teach your turtle to eat in as few steps as possible. ;; There is no need for you to understand this code ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to setupALL [xx yy orangeLength] clear-all reset-ticks set-patch-size 22 resize-world 0 30 0 21 ;;min-pxcor max-pxcor min-pycor max-pycor let image1 (bitmap:import "MandM_orange.png") let image2 (bitmap:import "MandM_black.png") set steps 0 set NORTH 0 set EAST 1 set SOUTH 2 set WEST 3 ask patches [ set pcolor white ] create-turtles 1 [ set shape "pacman1" set color white set pen-size 25 pen-up set heading 90 ] let i 0 repeat (length xx) [ let x (item i xx) let y (item i yy) if (Show_MM_Background_in_setup) [ ask patch x y [ set pcolor orange ] ] ifelse (i < orangeLength) [ bitmap:copy-to-drawing image1 (getPixelX x) (getPixelY y) ] [ bitmap:copy-to-drawing image2 (getPixelX x) (getPixelY y) ] set i (i + 1) ] set mmCountAtStart length xx show sentence "Total m&ms at start" mmCountAtStart end ;;================================================================ ================================= ;; getPixelX converts an x-axis patch coordinate to pixel coordinates. ;; The bitmap:copy-to-drawing procedure needs pixel coordinates ;; There is no need for you to understand this code. ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to-report getPixelX [ x ] report ((x - min-pxcor) * patch-size) end ;;================================================================ ================================= ;; getPixelY converts an y-axis patch coordinate to pixel coordinates. ;; The bitmap:copy-to-drawing procedure needs pixel coordinates ;; There is no need for you to understand this code. ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to-report getPixelY [ y ] report (patch-size * (max-pycor - min-pycor)) - ((y - min-pycor) * patch-size) end ;;================================================================ ================================= ;; moveMonster is the ONLY way you are allowed to move your turtle in this project. ;; ;; You must call moveMonster with one of 4 possible directions: ;; direction 0: North ;; direction 1: East ;; direction 2: South ;; direction 3: West ;; ;; !!!! DO NOT MODIFY THIS PROCEDURE !!!! ;;================================================================ ================================= to moveMonster [ direction ] if (steps = 0) [reset-timer] ask turtles [ set steps (steps + 1) ;; Animation if((steps mod 3) = 0) [ set shape "pacman0" ] if((steps mod 3) = 1) [ set shape "pacman1" ] if((steps mod 3) = 2) [ set shape "pacman2" ] ;;It would be faster to use: set heading (direction * 90) ;;However, this would allow direction to be numbers other than 0 through 3. ;;By using this series of if statements, the monster does not change direction if the angle is ;; not 0, 1, 2 or 3. if (direction = NORTH) [set heading 0] if (direction = EAST) [set heading 90] if (direction = SOUTH) [set heading 180] if (direction = WEST) [set heading 270] forward 1 let x 0 while [timer < (steps / 15)] [set x (x + 1)] ] tick end ;;================================================================ ================================= ;; solve1: This is the procedure you need to modify to improve the solver of setup1. ;; ;; This naive solution eats all the m&ms, but does so by walking through every patch in the world. ;; This solution takes 651 steps and is valued at zero points. ;; To get points on this lab you must: ;; 1) Eat all the m&ms. ;; 2) Do so in less steps than this naive solution. ;; 3) The fewer steps you make, the better your score. ;; ;; ;; !!!! YOUR WORK GOES IN THIS PROCEDURE !!!! ;;================================================================ ================================= to solve1 let rows ((max-pycor - min-pycor) + 1) let columns (max-pxcor - min-pxcor) repeat rows [ repeat columns [ moveMonster(EAST) ] moveMonster(SOUTH) ] end ;;================================================================ ================================= ;; solve2: This is the procedure you need to modify to improve the solver of setup2. ;; ;; This naive solution eats all the m&ms, but does so by walking through every patch in the world. ;; This solution takes 651 steps and is valued at zero points. ;; To get points on this lab you must: ;; 1) Eat all the m&ms. ;; 2) Do so in less steps than this naive solution. ;; 3) The fewer steps you make, the better your score. ;; ;; ;; !!!! YOUR WORK GOES IN THIS PROCEDURE !!!! ;;================================================================ ================================= to solve2 let rows ((max-pycor - min-pycor) + 1) let columns (max-pxcor - min-pxcor) repeat rows [ repeat columns [ moveMonster(EAST) ] moveMonster(SOUTH) ] end ;;================================================================ ================================= ;; solveAnySimpleConnectedPath: ;; This procedure solves any simple connected path. ;; A simple connected path is a path is a connected path where at each step there is only ;; one possible direction to go. ;; In a simple connected path, there are no loops and no dead ends. ;; Setup 2 is an example of a simple connected path. ;;================================================================ ================================= to solveAnySimpleConnectedPath if (not Show_MM_Background_in_setup) [ show "ERROR: Turn on Show M&M Background, then click setup" stop ] let direction NORTH let done false ask turtles [ let target one-of neighbors4 with [pcolor = orange] ifelse(target = nobody) [ set done true ] [ let myX xcor ;;save x and y coordinates of the turtle because inside target, xcor and ycor cannot be accesed let myY ycor ask target [ ;;pxcor and pycor are the coordinates of a patch that is colored orange if (pxcor > myX) [set direction EAST] if (pxcor < myX) [set direction WEST] if (pycor > myY) [set direction NORTH] if (pycor < myY) [set direction SOUTH] ] ] ] if (done) [stop] moveMonster direction ;;Mark the patch we moved into as eaten. ask turtles [ set pcolor white ] end ;;================================================================ ================================= ;; solveAnyConnectedPath: ;; This procedure solves any connected path. ;; A connected path is a path where all the m&ms are connected by one of the 4 possible more ;; directions. ;; Setup 1, 2 and extra are all simple connected paths. ;; ;; I call this the improved Hansel and Gretel method because ;; a) the bread crumbs cannot be eaten by birds and ;; b) there are 4 different colors of bread, so that if a path crosses itself, the turtle can still ;; find its way home. ;; ;; This can be made less complex if you turn off world wrap (see below for details). ;; You can tell the students it is fine to turn off world wrap. ;; ;; ;; ;;DISCUSSION QUESTIONS: ;; How efficient is this method - that is, on average, how often does the turtle revisit the same patches? ;; Can you find an upper bound to the number of revisits the turtle will make to any particular patch? ;; Of course, the turtle could get lucky pick the shortest possible path without any unnessary ;; backtracking. ;; However, is it possible for the turtle to ever get so unlukey that it revisits the same patch ;; 100s of times? ;;================================================================ ================================= to solveAnyConnectedPath if (not Show_MM_Background_in_setup) [ show "ERROR: Turn on Show M&M Background, then click setup" stop ] if (eatenCount >= mmCountAtStart) [stop] let direction NORTH ask turtles [ let myX xcor ;;save x and y coordinates of the turtle because inside target, xcor and ycor cannot be accesed let myY ycor let target one-of neighbors4 with [pcolor = orange] ifelse (target = nobody) [ ;;Backtrack whenever none of the 4 neighbors are uneaten. if (pcolor = yellow) [set direction SOUTH] if (pcolor = sky) [set direction WEST] if (pcolor = green) [set direction NORTH] if (pcolor = violet) [set direction EAST] ] [ ;; This is the case when there is an orange neighbor ask target [ ;;pxcor and pycor are the coordinates of a patch that is colored orange ;;This would be simpiler if world wrap was turned off. if (pxcor > myX) [ set direction EAST if (myX = min-pxcor) and (pxcor = max-pxcor) [set direction WEST] ] if (pxcor < myX) [ set direction WEST if (myX = max-pxcor) and (pxcor = min-pxcor) [set direction EAST] ] if (pycor > myY) [ set direction NORTH if (myY = min-pycor) and (pycor = max-pycor) [set direction SOUTH] ] if (pycor < myY) [ set direction SOUTH if (myY = max-pycor) and (pycor = min-pycor) [set direction NORTH] ] ] ] ] moveMonster direction ask turtles [ if (pcolor = orange) [ set eatenCount (eatenCount + 1) show (mmCountAtStart - eatenCount) ;;Set the path to a color based on which direction the turtle moved to enter that patch ;; This is later used so that the turtle can backtrack along its path without ;; woundering around in circles. ;; ;;Since this is only done when pcolor = orange, we only mark the direction ;; entered the FIRST TIME we visit a patch. if (direction = NORTH) [set pcolor yellow] if (direction = EAST) [set pcolor sky] if (direction = SOUTH) [set pcolor green] if (direction = WEST) [set pcolor violet] ] ] end