📄 ---pestilence(1).nlogo
字号:
;; Written by: Joe Glessner (jglessner@usip.edu) under the direction of Dr. James Johnson ;; University of the Sciences in Philadelphia;; 2004globals [ numTrav rand-infect isset time continue interval xcoord ycoord radius dead file ] turtles-own[ weak recover ]to startup ask patches[set pcolor white] import-ppm "Welcome.ppm" end;;--------------------------------------------------------------------------------------------------------to Setup ca ;;random-seed 311 disp-back setup-turtles set time 0 file-close end;;--------------------------------------------------------------------------------------------------------to Go set continue true init-recover loop[ ifelse continue and count turtles > 0[ ask turtles [ change-dir move infect reproduce age ] set time time + 1 do-plots ] [ stop] ]end;;--------------------------------------------------------------------------------------------------------to Halt set continue falseend;;--------------------------------------------------------------------------------------------------------to import-ppm [pathname] ;; USER-CHOOSE-FILE returns false if the user cancels, so this ;; check is here to handle that case if not is-string? pathname [ stop ] carefully [ file-open pathname import-ppm-contents ] [] file-closeendto import-ppm-contents ;; check magic number if read-pgm-entry != "P3" [ user-message "This is not a valid ASCII format PGM file (magic number is not P3)" stop ] ;; get width, height, and white value let width read-from-string read-pgm-entry let height read-from-string read-pgm-entry let max-value read-from-string read-pgm-entry ;; read the actual pixel values let x 0 let y 0 while [y < height] [ set x 0 while [x < width][ let value1 (read-from-string read-pgm-entry / max-value) let value2 (read-from-string read-pgm-entry / max-value) let value3 (read-from-string read-pgm-entry / max-value) ;; convert from image coordinates to patch coordinates ;; (in patch coordinates, the origin is in the center, ;; not the top left, and y coordinates increase going up, ;; not going down) let px x - screen-edge-x let py screen-edge-y - y ;; make sure we're not out of bounds if (abs px <= screen-edge-x) and (abs py <= screen-edge-y) [ ;; actually color the patch ask patch px py [ set pcolor (rgb value1 value2 value3) ;scale-color white value 0 max-value ] ] set x x + 1 ] set y y + 1 ]end;; reads the next entry in a pgm file ;; - an error occurs if there are no more entries;; - entries are separated by arbitrary whitespace ;; - characters on a line after "#" are commentsto-report read-pgm-entry ;; get next character let c file-read-characters 1 ;; ignore leading whitespace while [whitespace-char? c] [ set c file-read-characters 1 ] ;; skip comments if c = "#" [ ;; first skip the comment itself while [c != "\n" and c != "\r"] [ set c file-read-characters 1 ] ;; then skip linefeeds and/or newlines at end of comment while [c = "\n" or c = "\r"] [ set c file-read-characters 1 ] ] ;; read the entry let str "" while [not whitespace-char? c] [ set str str + c set c file-read-characters 1 ] report strend;; reports true if c is a single whitespace characterto-report whitespace-char? [c] report c = " " or c = "\t" or ;; tab c = "\n" or ;; newline c = "\r" ;; linefeedend ;;(C) 2004 Uri Wilensky.;;==============================================================to init-recover ask turtles[ if recover = true [set color blue + (color - red) set size size + .001 set weak false set recover false] ]end;;--------------------------------------------------------------------------------------------------------to disp-back locals[width] ask patches [set pcolor white] if not(Background = 1) [ ifelse (substring Background 1 2) = "A" [set width 10] [ifelse (substring Background 1 2) = "B" [set width 5] [ifelse (substring Background 2 3) = "A" [set width 10] [set width 5] ] ] if (substring Background 0 1 = "2") [ ask patches [ if (pxcor = 0) and (abs(pycor) < screen-edge-x - (width * 2)) [set pcolor black] if (abs(pycor) = screen-edge-x - (width * 2)) and (abs(pxcor) < screen-edge-x - (width * 2)) [set pcolor black] ] ] if ((substring Background 0 1) = "3") [ ask patches [ if (abs(pxcor) + abs(pycor) = screen-edge-x - width) and (abs(pycor) > width) [set pcolor black] ] ] if (substring Background 0 1 = "4") [ ask patches [ if (abs(pxcor) = abs(pycor)) and (abs(pxcor) < screen-edge-x - width) [set pcolor black] ] ] if (substring Background 0 1 = "5") [ ask patches [ if (pxcor = 0) and ((abs(pycor) < screen-edge-x - 40) or (abs(pycor) > screen-edge-x - (40 - width))) [set pcolor black] if (abs(pxcor) = abs(pycor)) and (abs(pxcor) < screen-edge-x - width) [set pcolor black] ] ] if (substring Background 0 1 = "6") [ ask patches [ if (abs(pxcor) + abs(pycor) = 70) and (abs(pycor) > (width / 2) and not(abs(pxcor) > 20 and abs(pxcor) < (20 + width))) or ((abs(pxcor) + abs(pycor) = 90) and (abs(pycor) < (90 - width)) and not((abs(pxcor) > 70 and abs(pxcor) < (70 + width)) or (abs(pxcor) > 28 and abs(pxcor) < (30 + width)))) or (abs(pxcor) = abs(pycor) and abs(pycor) < 36) or (abs(pxcor) = abs(pycor) and abs(pycor) > 45 + width) [set pcolor black] ] ] if (substring Background 0 1 = "7") [ ask patches [ if (abs(pxcor) = 50 and not(abs(pycor) < (width / 2)) and abs(pycor) < screen-edge-x - width) or (pxcor = 0 and pxcor < screen-edge-x - width and not(abs(pycor) > 10 and abs(pycor) < 15)) or (abs(pycor) = 10 and abs(pxcor) < screen-edge-x - width) or (abs(pycor) = 32 and not(abs(pxcor) < (50 + width) and abs(pxcor) > (50 - width))) or (abs(pycor) = 55 and abs(pxcor) < screen-edge-x - width and not(abs(pxcor) < width)) or (abs(pycor) = 80 and not(abs(pxcor) < (50 + width) and abs(pxcor) > (50 - width))) [set pcolor black] ] ] if (substring Background 0 1 = "8") [ ask patches [ if (abs(pxcor) = 0 and pycor < screen-edge-x - width) or (abs(pxcor) < 10 and abs(pxcor) > 10 and pycor = 80) or (abs(pxcor) = 10 and pycor > (75 + width)) or (abs(pxcor) < 20 and abs(pxcor) > 0 and pycor = 70) or (abs(pxcor) = 20 and pycor < screen-edge-x - width and pycor > 69) or (abs(pxcor) < 30 and abs(pxcor) > width and pycor = 60) or (abs(pxcor) = 30 and pycor > 59) or (abs(pxcor) < 40 and abs(pxcor) > 0 and pycor = 50) or (abs(pxcor) = 40 and pycor < screen-edge-x - width and pycor > 49) or (abs(pxcor) = 50 and pycor > 39) or (abs(pxcor) < 50 and abs(pxcor) > width and pycor = 40) or (abs(pxcor) < 60 and abs(pxcor) > 0 and pycor = 30) or (abs(pxcor) = 60 and pycor > 29 and pycor < screen-edge-x - width) or (abs(pxcor) = 70 and pycor > 19) or (abs(pxcor) < 70 and abs(pxcor) > width and pycor = 20) or (abs(pxcor) < 80 and abs(pxcor) > 0 and pycor = 10) or (abs(pxcor) = 80 and pycor > 9 and pycor < screen-edge-x - width) or (abs(pxcor) = screen-edge-x - 10 and pycor > 1) or (abs(pxcor) < screen-edge-x - 10 and abs(pxcor) > width and pycor = 2) [set pcolor black] ] ] if (substring Background 0 1 = "9") [ set xcoord width set ycoord 85 + width repeat 16 - width [back-diag] set xcoord 1 set ycoord 70 repeat 32 - width [back-diag] set xcoord width set ycoord 50 + width repeat 51 - width [back-diag] set xcoord 1 set ycoord 30 repeat 73 - width [back-diag] set xcoord width set ycoord 6 + width repeat 95 - width [back-diag] set xcoord 17 set ycoord 2 repeat 82 - width [back-diag] set xcoord 35 + width set ycoord width repeat 66 - width [back-diag] set xcoord 58 set ycoord 2 repeat 44 - width [back-diag] set xcoord 75 + width set ycoord width repeat 26 - width [back-diag] ask patches [ if (pycor = 1 and abs(pxcor) < screen-edge-x - 8) or (pxcor = 0 and pycor < screen-edge-x - 8) [set pcolor black] ] ] if (substring Background 0 2 = "10")[ ask patches [ if (abs(pxcor) = 0 and pycor < screen-edge-x - width) or (abs(pxcor) < 10 and abs(pxcor) > 10 and abs(pycor) = 80) or (abs(pxcor) = 10 and abs(pycor) > (75 + width)) or (abs(pxcor) < 20 and abs(pxcor) > 0 and abs(pycor) = 70) or (abs(pxcor) = 20 and abs(pycor) < screen-edge-x - width and abs(pycor) > 69) or (abs(pxcor) < 30 and abs(pxcor) > width and abs(pycor) = 60) or (abs(pxcor) = 30 and abs(pycor) > 59) or (abs(pxcor) < 40 and abs(pxcor) > 0 and abs(pycor) = 50) or (abs(pxcor) = 40 and abs(pycor) < screen-edge-x - width and abs(pycor) > 49) or (abs(pxcor) = 50 and abs(pycor) > 39) or (abs(pxcor) < 50 and abs(pxcor) > width and abs(pycor) = 40) or (abs(pxcor) < 60 and abs(pxcor) > 0 and abs(pycor) = 30) or (abs(pxcor) = 60 and abs(pycor) > 29 and abs pycor < screen-edge-x - width) or (abs(pxcor) = 70 and abs(pycor) > 19) or (abs(pxcor) < 70 and abs(pxcor) > width and abs(pycor) = 20) or (abs(pxcor) < 80 and abs(pxcor) > 0 and abs(pycor) = 10) or (abs(pxcor) = 80 and abs(pycor) > 9 and abs pycor < screen-edge-x - width) or (abs(pxcor) = screen-edge-x - 10 and abs(pycor) > (width / 2)) [set pcolor black] ] ] ]end;;--------------------------------------------------------------------------------------------------------to back-diag ask patch xcoord ycoord [set pcolor black] ask patch (- xcoord) ycoord [set pcolor black] set xcoord xcoord + 1 set ycoord ycoord + 1end ;;--------------------------------------------------------------------------------------------------------to setup-turtles crt Travelers_Left + Travelers_Right + Meanderers_Left + Meanderers_Right set numTrav (Travelers_Left + Travelers_Right) ask turtles[set weak false set size 5] init-infect separate-moveend;;--------------------------------------------------------------------------------------------------------to check-approp loop[ ifelse ((pcolor-of (patch-ahead 1) = black) or (pcolor-of (patch-left-and-ahead (heading - (90 * (quad))) 1) = black and pcolor-of (patch-right-and-ahead (90 - (heading - (90 * (quad)))) 1) = black)) or pxcor-of (patch-ahead 1) = (- pxcor-of (patch-here)) or pycor-of (patch-ahead 1) = (- pycor-of (patch-here)) or ((isset = 0) and (Background = 1) and (pxcor-of (patch-ahead 1) = 0)) [change-dir] [stop] ]end;;--------------------------------------------------------------------------------------------------------to change-dir set heading (random 360)end;;--------------------------------------------------------------------------------------------------------to-report quad if heading >= 0 and heading < 90 [report 0] if heading >= 90 and heading < 180 [report 1] if heading >= 180 and heading < 270 [report 2] if heading >= 270 and heading < 360 [report 3]end;;--------------------------------------------------------------------------------------------------------to init-infectask turtles [set color ((.001 * (random Healthy_Lifespan)) + blue) if color >= (blue + (.001 * Procreation_Age)) [set color color + 3] if who >= numTrav [set shape "circle"] ] repeat ((Travelers_Left + Meanderers_Left) * (%_Infected_Left / 100)) [set rand-infect (random (Travelers_Left + Meanderers_Left)) if rand-infect >= Travelers_Left [set rand-infect (rand-infect + Travelers_Right)] check-already-infect-l become-infected ] repeat ((Travelers_Right + Meanderers_Right) * (%_Infected_Right / 100)) [set rand-infect (random (Travelers_Right + Meanderers_Right)) ifelse rand-infect < (Travelers_Right) [set rand-infect (rand-infect + Travelers_Left)] [set rand-infect (rand-infect + Travelers_Left + Meanderers_Left)] check-already-infect-r become-infected ]end ;;--------------------------------------------------------------------------------------------------------to become-infected ifelse color-of turtle rand-infect < 106 [if (color-of turtle rand-infect - blue) < (.001 * Susceptible_Below) or (color-of turtle rand-infect - blue) > (.001 * Susceptible_Above) [set weak-of turtle rand-infect true]] [if (color-of turtle rand-infect - blue) < 3 + (.001 * Susceptible_Below) or (color-of turtle rand-infect - blue) > 3 + (.001 * Susceptible_Above) [set weak-of turtle rand-infect true]] set color-of turtle rand-infect (((color-of turtle rand-infect) - blue) + red) set size-of turtle rand-infect (size-of turtle rand-infect + (.001 * (random Susceptible_Infection_Lifespan))) if random 100 < Deadly_Mutations [set color-of turtle rand-infect (color-of turtle rand-infect + .010)] ifelse random 100 < Percent_Recovery [set recover-of turtle rand-infect true] [set recover-of turtle rand-infect false] end ;;--------------------------------------------------------------------------------------------------------to check-already-infect-lloop[ ifelse (shade-of? red (color-of turtle rand-infect)) [set rand-infect (random (Travelers_Left + Meanderers_Left)) if rand-infect >= Travelers_Left [set rand-infect (rand-infect + Travelers_Right)]] [stop] ]end;;--------------------------------------------------------------------------------------------------------to check-already-infect-rloop[ ifelse (shade-of? red (color-of turtle rand-infect)) [set rand-infect (random (Travelers_Right + Meanderers_Right)) ifelse rand-infect < (Travelers_Right) [set rand-infect (rand-infect + Travelers_Left)] [set rand-infect (rand-infect + Travelers_Left + Meanderers_Left)]] [stop] ]end;;--------------------------------------------------------------------------------------------------------to separate-move ask turtles [ set isset 0 ifelse who < Travelers_Left or (who < (Travelers_Left + Travelers_Right + Meanderers_Left) and who >= (Travelers_Left + Travelers_Right)) [if Left_Quadrant = "Top Outside" [set heading -90 fd 75 set heading 0 fd 75] if Left_Quadrant = "Top Center" [set heading -90 fd 25 set heading 0 fd 75] if Left_Quadrant = "High Outside" [set heading -90 fd 75 set heading 0 fd 25] if Left_Quadrant = "High Center" [set heading -90 fd 25 set heading 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -