;*************************** OBSERVER PROCEDURES ****************************** globals [aa Total-Free Reservation-Available?] patches-own [xcoord ycoord number] breeds [living working visiting1 visiting2 reserving] to track-vacant-all ; here we generate a list called "aa" which tracks the vacant spots on the east sides of roads wait-until [Reservation-Available? = true] if Reservation-Available? = true [ set Reservation-Available? false set aa make-list 0 0 let [:a (count-patches-with [pc = white and count-turtles-here = 0])] ask-patches [if pc = white and count-turtles-here = 0 [ let [:xpos xcor] let [:ypos ycor] let [:bb (list xcor ycor)] set aa insert 1 aa :bb ]] set Reservation-Available? true] end to setup set-random-seed 100 set Reservation-Available? true ct crt number-of-cars ask-turtles [setCounter 0 setshape cross setc red setspeed 1 setSpeedLimit 1 if (who <= (number-of-cars / 5)) [setbreed living] if (who > (number-of-cars / 5) and who <= (number-of-cars / 2)) [setbreed working] if (who > (number-of-cars / 2) and who <= (number-of-cars / 1.25)) [setbreed visiting1] if (who > (number-of-cars / 1.25)) [setbreed visiting2] if breed = living [setParkTime 48] if breed = working [setParkTime 32] if breed = visiting1 [setParkTime 2] if breed = visiting2 [setParkTime 8] loop [ifelse ((pc-at 0 0) = black and count-turtles-here = 1 ) [stop] [ ifelse (random 2) = 0 [seth 0] [ifelse (random 2) = 0 [seth 90][ifelse (random 2) = 0 [seth 180] [seth 270]]] fd (int random 25) ifelse (random 2) = 0 [seth 0] [ifelse (random 2) = 0 [seth 90][ifelse (random 2) = 0 [seth 180] [seth 270]]] fd (int random 25) ]]] starttrackingall startcountaverage end to clear-cars ct end to count-steps-to-find-parking output (average-of-turtles-with [color = yellow] [steps-to-find-parking]) end to stop-it stoptrackingall stopDrive&Park stopcountaverage end to count-average ; this is for statistical analysis: paste these number into excel and calculate the mean, median and standard deviation show (round average-of-turtles-with [color = yellow] [steps-to-find-parking]) wait 1 end ;*************************** TURTLE PROCEDURES ****************************** turtles-own [speed SpeedLimit ParkTime Parked? steps-to-find-parking Direction CoordX CoordY Counter Dist] to check-patches-after-park if (pc-ahead = 7) or (pc-ahead = 9) [ rt 90 check-patches-after-park ] end to choose-nearest-spot ; here extract each item in the "aa" list, then extract each item's x and y and check the patche's distance from the turtle ; use the turtles-own variable Distance which indicates the distance to the nearest free spot and a variable named ":item-find" indicating the number of the element in the aa list wait-until [Reservation-Available? = true] if Reservation-Available? = true [ set Reservation-Available? false let [:nullcheck (length aa)] if (:nullcheck > 0) [ setDist 2000 ; initialize a distance that is bigger than any on screen dist, so that a new dist will always be smaller let [:k 1] ; k is the counter to loop through every elemnt in the "number" list starts with 1 let [:aacopy (copy-list aa)] ; make a copy of the "aa", so if the real aa changes in length, their's remain the same until end of counting repeat (length :aacopy) [ ;check only for free spots, don't waste RAM let [:item-number (item :k :aacopy)] ; extract the first (eventually each) element from the aa list let [:item-numberX (item 1 :item-number)] ; extract the X value of aa item let [:item-numberY (item 2 :item-number)] ; extract the Y value of the aa item let [:xdist (:item-numberX - (round xcor))] let [:ydist (:item-numberY - (round ycor))] ifelse (heading = 0 and :item-numberY < ycor) or (heading = 90 and :item-numberX < xcor) or (heading = 180 and :item-numberY > ycor) or (heading = 270 and :item-numberX > xcor)[ let [:distnew ((abs :xdist) + (abs :ydist) + 45)]] ; if the destination spot is in the opposite direction, the add 1/2 (average) block loop (22 + 8) to the dist [let [:distnew ((abs :xdist) + (abs :ydist))]] ; you're always comparing distnew to the initial dist, of course you'll just end up choosing the last one... if (:distnew < Dist ) [let [:kchosen :k] setDist :distnew] if :k <= (length :aacopy) [ set :k (:k + 1)]] set :item-number (item :kchosen :aacopy) ; extract the memorized smallest distance element from the :aacopy list set :item-numberX (item 1 :item-number) ; extract the X value set :item-numberY (item 2 :item-number) ; extract the Y value set :xdist (:item-numberX - (round xcor)) set :ydist (:item-numberY - (round ycor)) ifelse (heading = 0 and :item-numberY < ycor) or (heading = 90 and :item-numberX < xcor) or (heading = 180 and :item-numberY > ycor) or (heading = 270 and :item-numberX > xcor)[ set Dist ((abs :xdist) + (abs :ydist) + 45)] ; if the destination spot is in the opposite direction, the add 1/2 (average) block loop (22 + 8) to the dist [set Dist ((abs :xdist) + (abs :ydist))] set CoordX (:item-numberX) set CoordY (:item-numberY) setDirection (towards-nowrap CoordX CoordY) ask-patch-at :xdist :ydist [sprout [setbreed reserving setc green setshape cross]] let [:bb (list CoordX CoordY)] set aa (remove-element :bb aa)] set Reservation-Available? true ] end to park ; has to be done so that agent will look for parking until found if breed not= reserving[ if (Parked? = false)[ setc yellow ; the idea here is that if an agent has found a destination from the aa list, then it will keep driving there until it parks, if not, it will roam randomly once and then try the aa list again choose-nearest-spot loop[ ; First check if there is a parking spt next to you. here is how the actual parking move happens ; first, parking at your own side of the road and then parking at the opposite side of the road, parking on horisontal streets is also allowed. let [:roundx (round xcor) :roundy (round ycor)] ifelse ((pc-at 0 0) = 0 and (pc-at 1 0) = 9 and (count-turtles-at 1 0) = 0) or ((pc-at 0 0) = 0 and (pc-at (-1) 0) = 9 and (count-turtles-at (-1) 0) = 0 ) or ((pc-at 0 0) = 0 and (pc-at -2 0) = 9 and (count-turtles-at -2 0) = 0 ) or ((pc-at 0 0) = 0 and (pc-at 2 0) = 9 and (count-turtles-at 2 0) = 0 ) or ((pc-at 0 0) = 0 and (pc-at 0 1) = 9 and (count-turtles-at 0 1) = 0 ) or ((pc-at 0 0) = 0 and (pc-at 0 (-1)) = 9 and (count-turtles-at 0 (-1)) = 0 ) or ((pc-at 0 0) = 0 and (pc-at 0 -2) = 9 and (count-turtles-at 0 -2) = 0 ) or ((pc-at 0 0) = 0 and (pc-at 0 2) = 9 and (count-turtles-at 0 2) = 0 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 1 0) = 9 and (count-reserving-at 1 0) = 1) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at (-1) 0) = 9 and (count-reserving-at (-1) 0) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at -2 0) = 9 and (count-reserving-at -2 0) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 2 0) = 9 and (count-reserving-at 2 0) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 1) = 9 and (count-reserving-at 0 1) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 (-1)) = 9 and (count-reserving-at 0 (-1)) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 -2) = 9 and (count-reserving-at 0 -2) = 1 ) or ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 2) = 9 and (count-reserving-at 0 2) = 1 )[ if ((pc-at 0 0) = 0 and (pc-at 1 0) = 9 and (count-turtles-at 1 0) = 0) [ seth 90 fd 1 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at (-1) 0) = 9 and (count-turtles-at (-1) 0) = 0) [seth 270 fd 1 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at -2 0) = 9 and (count-turtles-at -2 0) = 0) [seth 270 fd 2 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at 2 0) = 9 and (count-turtles-at 2 0) = 0) [seth 90 fd 2 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at 0 1) = 9 and (count-turtles-at 0 1) = 0) [seth 0 fd 1 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at 0 (-1)) = 9 and (count-turtles-at 0 (-1)) = 0) [seth 180 fd 1 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at 0 -2) = 9 and (count-turtles-at 0 -2) = 0 ) [seth 180 fd 2 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((pc-at 0 0) = 0 and (pc-at 0 2) = 9 and (count-turtles-at 0 2) = 0 ) [seth 0 fd 2 kill one-of-reserving-at (CoordX - (round xcor)) (CoordY - (round ycor)) set CoordX 0 set CoordY 0 setDirection 0 setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 1 0) = 9 and (count-reserving-at 1 0) = 1) [seth 90 fd 1 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at (-1) 0) = 9 and (count-reserving-at (-1) 0) = 1) [seth 270 fd 1 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at -2 0) = 9 and (count-reserving-at -2 0) = 1)[seth 270 fd 2 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 2 0) = 9 and (count-reserving-at 2 0) = 1) [seth 90 fd 2 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 1) = 9 and (count-reserving-at 0 1) = 1) [seth 0 fd 1 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 (-1)) = 9 and (count-reserving-at 0 (-1)) = 1) [seth 180 fd 1 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 -2) = 9 and (count-reserving-at 0 -2) = 1)[seth 180 fd 2 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red] if ((((:roundy + 4) > CoordY) and ((:roundy - 4) < CoordY)) and (((:roundx + 4) > CoordX) and ((:roundx - 4) < CoordX)) and (pc-at 0 0) = 0 and (pc-at 0 2) = 9 and (count-reserving-at 0 2) = 1) [seth 0 fd 2 set CoordX 0 set CoordY 0 setDirection 0 kill one-of-reserving-here setParked? true set steps-to-find-parking 0 setc red]] [if (pc-at 0 0) not= white [ ifelse (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3 set steps-to-find-parking (steps-to-find-parking + 3)] [ifelse (random 2) = 0 [rt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 2)][fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)]]] [check-patches-after-park fd speed set steps-to-find-parking (steps-to-find-parking + speed)] if (CoordX = 0 and CoordY = 0)[choose-nearest-spot]]] ;here we augment the parking counter and check if the counter is full, in which case a car leaves. When leaving, a car must also step 1 step away from the spot in order not to park again. if (breed not= reserving and Parked? = true and (pc-at 0 0) = white) [ ifelse Counter > ParkTime [ if ((pc-at (-2) 0) = black and (pc-at (-1) 0) = black and (pc-at 0 0) = white) [kill one-of-reserving-here seth 270 fd 1 seth 0 setCounter 0 stop] if ((pc-at 2 0) = black and (pc-at 1 0) = black and (pc-at 0 0) = white) [kill one-of-reserving-here seth 90 fd 1 seth 180 setCounter 0 stop] if ((pc-at 0 (-2)) = black and (pc-at 0 (-1)) = black and (pc-at 0 0) = white) [kill one-of-reserving-here seth 180 fd 1 seth 270 setCounter 0 stop] if ((pc-at 0 2) = black and (pc-at 0 1) = black and (pc-at 0 0) = white) [kill one-of-reserving-here seth 0 fd 1 seth 90 setCounter 0 stop]] [set Counter (Counter + 1)]] ; Now, check if you are on an intersection. Here are the rules to guide a car towards a chosen spot, assuming it can also park on the opposite side of the road. ifelse (CoordX not= 0 and CoordY not= 0)[ ; for heading = 0, supposing that you can also park on the opposite side of the road if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and ((heading = 0) and (xcor < CoordX and ycor < CoordY))[ ifelse (CoordX < (xcor + 3))[fd 2 set steps-to-find-parking (steps-to-find-parking + 2)] [rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and ((heading = 0) and (xcor < CoordX and ycor > CoordY))[ rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and ((heading = 0) and (xcor > CoordX and ycor > CoordY))[ fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and ((heading = 0) and (xcor > CoordX and ycor < CoordY))[ ifelse (CoordX > (xcor - 3)) [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)][fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)]] ; for heading = 90, supposing that you can also park on the opposite side of the road if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 90 and (xcor < CoordX and ycor < CoordY))[ ifelse (CoordX < (xcor + 3)) [fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)][fd 2 set steps-to-find-parking (steps-to-find-parking + 2)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 90 and (xcor < CoordX and ycor > CoordY))[ ifelse (CoordX < (xcor + 3)) [rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 90 and (xcor > CoordX and ycor > CoordY))[ rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 90 and (xcor > CoordX and ycor < CoordY))[ fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)] ; for heading = 180, supposing that you can also park on the opposite side of the road if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 180 and (xcor < CoordX and ycor < CoordY))[ fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 180 and (xcor < CoordX and ycor > CoordY))[ ifelse (CoordX < (xcor + 3)) [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)] [fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 180 and (xcor > CoordX and ycor > CoordY))[ ifelse (CoordX > (xcor - 3)) [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)] [rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 180 and (xcor > CoordX and ycor < CoordY))[ rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] ; for heading = 270, supposing that you can also park on the opposite side of the road if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 270 and (xcor < CoordX and ycor < CoordY))[ rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 270 and (xcor < CoordX and ycor > CoordY))[ fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 270 and (xcor > CoordX and ycor > CoordY))[ ifelse (CoordX > (xcor - 3)) [fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)] [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)]] if ((pc-at 0 0) = 2 and (pc-ahead)= 2) and (heading = 270 and (xcor > CoordX and ycor < CoordY))[ ifelse (CoordX > (xcor - 3)) [rt 90 fd 1 set steps-to-find-parking (steps-to-find-parking + 1)] [fd 2 set steps-to-find-parking (steps-to-find-parking + 2)]]] [if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3 set steps-to-find-parking (steps-to-find-parking + 3)] [ifelse (random 2) = 0 [rt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 2)][fd 1 lt 90 fd 2 set steps-to-find-parking (steps-to-find-parking + 3)]]]] ; if Reserved? was false on the previous step, try again and then enter the park proc again. ; here set the car to break or accelerate according to other cars ifelse (count-turtles-towards heading 1) > 0 ;if there is a turtle 1 space ahead, decelerate [setspeed speed-of one-of-turtles-towards heading 1 decelerate] [ifelse lookahead = 2 ;if lookahead=2, check 2 spaces ahead also [ifelse (count-turtles-at heading 1) > 0 [setspeed speed-of one-of-turtles-towards heading 2 decelerate] [accelerate]] ;else accelerate [accelerate]] if speed < 0.01 [setspeed 0.01] ;also adjust speed based on SpeedLimit and radar if speed > SpeedLimit [setspeed SpeedLimit] ]]] end to drive ; each egnt will park and then drive for a certain time if (pc-at 1 0) = 7 or (pc-at 1 0) = 9 [ seth 0 setParked? false park repeat (parking-interval * 10) [ ; these are turtles driving up if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3] [ifelse (random 2) = 0 [rt 90 fd 2][fd 1 lt 90 fd 2]]] check-patches-after-park ifelse (count-turtles-at 0 1) > 0 ;if there is a turtle 1 space ahead, decelerate [setspeed speed-of one-of-turtles-at 0 1 decelerate] [ifelse lookahead = 2 ;if lookahead=2, check 2 spaces ahead also [ifelse (count-turtles-at 0 1) > 0 [setspeed speed-of one-of-turtles-at 0 2 decelerate] [accelerate]] ;else accelerate [accelerate]] if speed < 0.01 [setspeed 0.01] ;also adjust speed based on SpeedLimit and radar if speed > SpeedLimit [setspeed SpeedLimit] fd speed ] ] if (pc-at (-1) 0) = 7 or (pc-at (-1) 0) = 9 [ seth 180 setParked? false park repeat (parking-interval * 10) [ ; these are turtles driving up if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3] [ifelse (random 2) = 0 [rt 90 fd 2][fd 1 lt 90 fd 2]]] check-patches-after-park ifelse (count-turtles-at 0 (-1)) > 0 ;if there is a turtle 1 space ahead, decelerate [setspeed speed-of one-of-turtles-at 0 (-1) decelerate] [ifelse lookahead = 2 ;if lookahead=2, check 2 spaces ahead also [ifelse (count-turtles-at 0 (-1)) > 0 [setspeed speed-of one-of-turtles-at 0 (-2) decelerate] [accelerate]] ;else accelerate [accelerate]] if speed < 0.01 [setspeed 0.01] ;also adjust speed based on SpeedLimit and radar if speed > SpeedLimit [setspeed SpeedLimit] fd speed ] ] if (pc-at 0 1) = 7 or (pc-at 0 1) = 9 [ seth 270 setParked? false park repeat (parking-interval * 10) [ ; these are turtles driving up if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3] [ifelse (random 2) = 0 [rt 90 fd 2][fd 1 lt 90 fd 2]]] check-patches-after-park ifelse (count-turtles-at (-1) 0) > 0 ;if there is a turtle 1 space ahead, decelerate [setspeed speed-of one-of-turtles-at (-1) 0 decelerate] [ifelse lookahead = 2 ;if lookahead=2, check 2 spaces ahead also [ifelse (count-turtles-at (-1) 0) > 0 [setspeed speed-of one-of-turtles-at (-2) 0 decelerate] [accelerate]] ;else accelerate [accelerate]] if speed < 0.01 [setspeed 0.01] ;also adjust speed based on SpeedLimit and radar if speed > SpeedLimit [setspeed SpeedLimit] fd speed ] ] if (pc-at 0 (-1)) = 7 or (pc-at 0 (-1)) = 9 [ seth 90 setParked? false park repeat (parking-interval * 10) [ ; these are turtles driving up if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3] [ifelse (random 2) = 0 [rt 90 fd 2][fd 1 lt 90 fd 2]]] check-patches-after-park ifelse (count-turtles-at 1 0) > 0 ;if there is a turtle 1 space ahead, decelerate [setspeed speed-of one-of-turtles-at 1 0 decelerate] [ifelse lookahead = 2 ;if lookahead=2, check 2 spaces ahead also [ifelse (count-turtles-at 2 0) > 0 [setspeed speed-of one-of-turtles-at 2 0 decelerate] [accelerate]] ;else accelerate [accelerate]] if speed < 0.01 [setspeed 0.01] ;also adjust speed based on SpeedLimit and radar if speed > SpeedLimit [setspeed SpeedLimit] fd speed ] ] if (pc-ahead = 2 and (pc-at 0 0) = 2) [ifelse (random 2) = 0 [leap 3] [ifelse (random 2) = 0 [rt 90 fd 2][fd 1 lt 90 fd 2]]] check-patches-after-park end to accelerate setspeed (speed + (speedup / 1000)) end to decelerate setspeed speed - (slowdown / 1000) end