!!!---tileworldzavala.nlogo
来自「NETLOGO」· NLOGO 代码 · 共 660 行 · 第 1/2 页
NLOGO
660 行
; Tileword; Rosa L. Zavala;;--------------------- breeds and globals declaration ----------------------breeds [robots tiles holes]tiles-own [time-to-live num-robots-working-on-me]holes-own [time-to-live]robots-own [destination-x destination-y closest-tile closest-hole change-heading can-move-tile] globals [holes-born holes-filled score highest-score];--------------------- buttons and misc --------------------------to startup setupendto setup ca set-default-shape robots "turtle" set-default-shape tiles "box" set-default-shape holes "circle" create-custom-robots num-robots [ setxy get-random-xcor get-random-ycor ]endto defaults set num-robots 20 set tile-birth-prob 0.50 set tile-lifetime 50 set hole-birth-prob 0.50 set hole-lifetime 50 set delay 0.0 set group-size 4 set watch false setupendto-report get-random-xcor report (random screen-size-x) - screen-edge-xendto-report get-random-ycor report (random screen-size-y) - screen-edge-yendto update locals [i] if (watch = false) [wait delay] if (random 1.0 < tile-birth-prob) [ create-custom-tiles 1 [ set heading 0 set time-to-live tile-lifetime setxy get-random-xcor get-random-ycor set color gray]] if (random 1.0 < hole-birth-prob) [ set holes-born holes-born + 1 create-custom-holes 1 [ set heading 0 set time-to-live hole-lifetime setxy get-random-xcor get-random-ycor set color white]] ask tiles [age] ask holes [age] ask tiles [set num-robots-working-on-me 0] ask robots [set can-move-tile false] ifelse (watch = true) [ set i 0 while [i < num-robots] [ ask turtle i [move] set i i + 1 ] ] [ ask robots [move] ] if (holes-born > 0)[ set score holes-filled * 100 / holes-born if (score > highest-score) [set highest-score score] plot score]end;-------------tiles and holes methods---------------to age if time-to-live <= 0 [die] set time-to-live time-to-live - 1end;reports one of 0,90,180,270; whichever is closest to hto-report rectify-heading [h] if (h < 0)[ set h (360 + h)] if (h <= 45) [report 0] if (h <= 135) [report 90] if (h <= 225) [report 180] if (h <= 315) [report 270] report 0end;---------------------------tiles methods----------------------; sets destination-of robot to be the location where robot should be; in order to push me towards hole.; NOTE: This method was changed in order to implement the "Square step" behaviorto set-robot-destination [robot hole] ask robot [set change-heading true] set heading rectify-heading (towards hole) set heading heading + 180 if (one-of (robots-at 0 1) = robot and ycor > ycor-of hole) [ set destination-x-of robot xcor-of robot set destination-y-of robot ycor-of robot ;ask robot [set heading 180] ;ask robot [set change-heading false] stop] if (one-of (robots-at 1 0) = robot and xcor > xcor-of hole) [ set destination-x-of robot xcor-of robot set destination-y-of robot ycor-of robot ;ask robot [set heading 270] ;ask robot [set change-heading false] stop] if (one-of (robots-at 0 -1) = robot and ycor < ycor-of hole) [ set destination-x-of robot xcor-of robot set destination-y-of robot ycor-of robot ;ask robot [set heading 0] ;ask robot [set change-heading false] stop] ifelse (one-of (robots-at -1 0) = robot and xcor < xcor-of hole) [ set destination-x-of robot xcor-of robot set destination-y-of robot ycor-of robot ;ask robot [set heading 90] ;ask robot [set change-heading false] stop] [set destination-x-of robot pxcor-of patch-at dx dy set destination-y-of robot pycor-of patch-at dx dy ask robot [set change-heading true]]endto can-move-you [robot hole]; Decides if the robot should move me or not and then sets his can-move-tile accordingly if (one-of (robots-at 0 1) = robot and ycor > ycor-of hole) [ask robot [set can-move-tile true] stop] if (one-of (robots-at 1 0) = robot and xcor > xcor-of hole) [ask robot [set can-move-tile true] stop] if (one-of (robots-at 0 -1) = robot and ycor < ycor-of hole) [ask robot [set can-move-tile true] stop] if (one-of (robots-at -1 0) = robot and xcor < xcor-of hole) [ask robot [set can-move-tile true] stop] if (one-of (robots-at 0 1) != nobody and one-of (robots-at 0 1)!= robot) [ ;if (closest-hole-of one-of (robots-at 0 1) != nobody) ;[ ; if (ycor-of one-of (robots-at 0 1) > ycor-of (closest-hole-of one-of (robots-at 0 1))) if (ycor-of one-of (robots-at 0 1) > ycor-of hole) [ask robot [set can-move-tile false] stop] ];] if (one-of (robots-at 1 0) != nobody and one-of (robots-at 1 0)!= robot) [ ;if (closest-hole-of one-of (robots-at 1 0) != nobody) ;[ ; if (xcor-of one-of (robots-at 1 0) > xcor-of (closest-hole-of one-of (robots-at 1 0))) if (xcor-of one-of (robots-at 1 0) > xcor-of hole) [ask robot [set can-move-tile false] stop] ];] if (one-of (robots-at 0 -1) != nobody and one-of (robots-at 0 -1)!= robot) [ ;if (closest-hole-of one-of (robots-at 0 -1) != nobody) ;[ ; if (ycor-of one-of (robots-at 0 -1) < ycor-of (closest-hole-of one-of (robots-at 0 -1))) if (ycor-of one-of (robots-at 0 -1) < ycor-of hole) [ask robot [set can-move-tile false] stop] ];] if (one-of (robots-at -1 0) != nobody and one-of (robots-at -1 0)!= robot) [ ;if (closest-hole-of one-of (robots-at -1 0) != nobody) ;[ ; if (xcor-of one-of (robots-at -1 0) < xcor-of (closest-hole-of one-of (robots-at -1 0))) if (xcor-of one-of (robots-at -1 0) < xcor-of hole) [ask robot [set can-move-tile false] stop] ];] ask robot [set can-move-tile true]end;---------------------------robots methods-----------------------to-report rectify-heading-robot [h robot]; NOTE: This method was changed in order to implement the "Square step" behavior if (h < 0)[ set h (360 + h)] if (h < 45) [report 0] if (h = 45) [ set heading 0 ifelse (any tiles-at dx dy) [report 90] [report 0] ] if (h < 135) [report 90] if (h = 135) [ set heading 90 ifelse (any tiles-at dx dy) [report 180] [report 90] ] if (h < 225) [report 180] if (h = 225) [ set heading 180 ifelse (any tiles-at dx dy) [report 270] [report 180] ] if (h < 315) [report 270] if (h = 315) [ set heading 270 ifelse (any tiles-at dx dy) [report 0] [report 270] ] report 0end; This is the movement strategy. It's a variation of the greedy strategy.; It tries to push the closest tile to the closest hole to that tile. ; This strategy improves the greedy by avoiding to end up; with all of the robots getting in each others' way. To do so, sometimes (according to some rules and heuristics) ; the robot decides not to go for the tile ...to move locals [aux] if (watch = true) [wait delay] set closest-tile min-one-of tiles [distance myself] ifelse (closest-tile = nobody) [set closest-hole min-one-of holes [distance myself] ] [set aux closest-tile set closest-hole min-one-of holes [distance aux] ] ;for "distance version": ;choose-closest-tile-and-hole2 if (closest-tile != nobody) [ ifelse (closest-hole != nobody) [ set aux closest-hole ask closest-tile [can-move-you myself aux] ifelse (can-move-tile = true and num-robots-working-on-me-of closest-tile < group-size) [ ask closest-tile [set-robot-destination myself aux] ask closest-tile [set num-robots-working-on-me num-robots-working-on-me + 1] if (xcor = destination-x and ycor = destination-y) [ ;Im already at the desired location, so push the tile if (change-heading) [set heading rectify-heading (towards closest-tile)] move-one heading stop ] ] [ ;the group is complete or I cannot move tile (actually I can but it's better not to do that) set heading rectify-heading (towards closest-tile + 180) move-one heading stop ] ] [;there are no holes in the field, this typically only happens at the beginning of the run. set destination-x xcor-of closest-tile set destination-y ycor-of closest-tile ] ;I am not next to the tile, so set my heading towards the best position next to it. set heading rectify-heading (towardsxy destination-x destination-y) ;If my move will cause a tile to move then change direction by +- 90. ;This will, hopefully, allow me to move around the target to push it back. ; Hint: don't waste your time trying to improve this bit. There is much more to be gained from coordination. if (any tiles-at dx dy)[ ifelse (random 1.0 < 0.5)[ set heading heading + 90] [ set heading heading - 90] ] move-one heading ]endto choose-closest-tile-and-hole2 ; this method is not used. It was implemented as a method that considers distances and time ; remaining of holes and tiles but it didn't improve performance locals [distance-robot-tile distance-tile-hole x y aux aux2] set closest-tile min-one-of tiles [distance myself] if (closest-tile = nobody) [set closest-hole min-one-of holes [distance myself] stop] set aux closest-tile set closest-hole min-one-of holes [distance aux] if ((closest-hole != nobody) and (closest-tile != nobody)) [ set x xcor
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?