Rubble Trouble!
Model was written in NetLogo 6.3.0
•
Viewed 208 times
•
Downloaded 45 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
; extensions [ sound ] globals [ pixel keypress the-ship the-reticule click num-rocks active-reticule score credits reset-pressed rock-color setup-finished rock-info ] patches-own [ rr gg bb ] breed [ rocks rock ] breed [ ships ship ] breed [ bullets bullet ] breed [ fragments fragment ] breed [ messengers messenger ] breed [ reticules reticule ] breed [ letters letter ] breed [ clocks clock ] breed [ HS-effects hs-effect ] clocks-own [ current-time elapsed-time start-time cumulative-time pause-until clock-on ] letters-own [ base-size base-color base-xcor base-heading ] reticules-own [ timeout ] hs-effects-own [ effect-direction ] ships-own [ vx vy vv ax ay av gun-temp gun-limit gun-cooldown max-temp bullet-speed; bullet-burnout max-burnout ] rocks-own [ rock-type vx vy vv av exploding ] bullets-own [ vx vy vv bullet-burnout bullet-speed max-burnout seeker? target-rock ] fragments-own [ vv vx vy av burnout max-burnout kind ] messengers-own [ text ;; the message to ;display caret ;; position within the text cursor ;; patch offset of the caret window ;; the set of patches under the message window# ;; the line on which to ;display the message show-cursor? ;; show the simulated blinking curtor ] to ? [ thing ] ( ifelse ( is-list? thing ) [ output-print " [ " foreach thing [ ?? -> ? ?? ] output-print " ] " ] [ output-print thing ] ) end to-report plus-or-minus [ value ] report value * ( random 2 * 2 - 1 ) end to x_set-line-thickness [ width ] ;; __set-line-thickness width end to setup-rock let rock-start-size 1.5 ^ 5 let rock-start-av .1 + random-float 0.75 let rock-start-v .1 + random-float .1 set rock-info [ [ "rock-1" 0 1 22 ] [ "rock-2" 0 1 22 ] [ "rock-3" 0 1 22 ] [ "rock-4" 0 1 22 ] [ "rock-5" 1 2 12 ] ] create-rocks 1 [ home x_set-line-thickness pixel * 2 let side plus-or-minus 1 let startx side * ( max-pxcor - random ( world-width / 4 ) ) let starty random-ycor setxy startx starty let endx side * ( max-pxcor - random ( world-width / 4 ) ) set heading towardsxy endx plus-or-minus max-pycor set vx dx * rock-start-v set vy dy * rock-start-v set av rock-start-av set color white set rock-type item ( roulette rock-info 3 ) rock-info set shape item 0 rock-type set size rock-start-size / item 2 rock-type ] end to-report roulette [ $layout $bias-index ] ;; the layout are the values being selected from ;; the canoes are widths of each pocket the tendency of each value to be selected let canoes map [ $bias -> item $bias-index $bias ] $layout let total sum canoes let fall random-float total let pocket 0 ;; intial value of canoe = inside the first pocket let canoe item pocket canoes while [ fall > canoe ] [ set pocket pocket + 1 set canoe canoe + item pocket canoes ] report pocket end to rock-explode ;; sound:play-note-later delay instrument keynumber velocity duration sfx "explode-rock" size set heading atan vx vy set vv sqrt ( vx * vx + vy * vy ) if ( size > 4 ) [ set size size * 2 / 3 if vv < .9 [ set vv vv * 1.1 ] let a -1 repeat (1 + random 2) [ hatch 1 [ rt 90 * a set a a + 2 set vx dx * vv set vy dy * vv jump size / 2 set shape one-of [ "rock-1" "rock-2" "rock-2" ] x_set-line-thickness pixel * 2 ] ] ] fragment-setup white 0 size die end to fragment-setup [ hue direction radius ] let xx xcor let yy ycor let $extra max list 0 (count fragments - 100) ask n-of $extra fragments [ die ] hatch-fragments ifelse-value ( direction = 0 ) [ 5 ] [ 1 ] [ set color hue set heading random 360 x_set-line-thickness pixel * 2 set vv .1 + random-float .2 set vx dx * vv set vy dy * vv set max-burnout 40 ifelse direction != 0 [ jump 2 rt 180 set size 2 set av 0 ] [ jump ( .5 * random-float radius ) rt 90 set size ( size + random-float 2 ) set av 20 * ( random 2 * 2 - 1 ) ] ] end to game-clear ;; setup a game clear-drawing clear-patches clear-turtles clear-links set num-rocks 0 end to ship-setup create-ships 1 [ set color magenta + 2 set heading 0 set shape "_ship-000" x_set-line-thickness pixel * 2 set size 2 set bullet-speed 1 set bullet-burnout max-pxcor / bullet-speed set max-burnout bullet-burnout set gun-limit 5 set gun-temp 0 set max-temp 4 / bullet-speed ;; floor ( 30 / 2 / pixel ) set the-ship self ] inspect the-ship end to reticule-setup ask patch min-pxcor min-pycor [ sprout-reticules 1 [ hide-turtle setxy max-pxcor max-pycor set heading 0 set shape "reticule" set color red x_set-line-thickness pixel * 3 set size 2 set active-reticule self set timeout 0 ] ] end to reticules-go if self != active-reticule [ if timeout = 0 [ set timeout timer + 2 ] ifelse timer < timeout [ set color scale-color red ( timeout - timer ) -3 8 ] [ die ] ] end to ship-explode sfx "ship-explode" 0 die end to-report ship-fire ;; SETUP-bullet let fire! false ask the-ship [ if gun-temp <= 0 and count bullets < gun-limit [ sfx "pew" 0 hatch-bullets 1 [ x_set-line-thickness pixel * 4 set size max list .5 ( pixel * 3 ) set color white set vx dx * ( bullet-speed ) set vy dy * ( bullet-speed ) jump .5 set fire! true set seeker? false let vary random 100 ( ifelse ( vary > 90 ) ;; hunter missle [ set seeker? true set size .5 set shape "missle" set target-rock one-of rocks set color yellow set bullet-burnout 200 ] ( vary > 80 ) ;; triple shot [ hatch 1 [ rt 90 jump .5 lt 90 ] hatch 1 [ lt 90 jump .5 rt 90 ] ] ( vary > 70 ) ;; to left, right, and center [ hatch 1 [ rt 90 ] hatch 1 [ lt 90 ] ] ( vary > 60 ) ;; four-way shot [ hatch 1 [ rt 90 ] hatch 1 [ lt 90 ] hatch 1 [ rt 180 jump 1 ] ] ( vary > 55 ) ;; circle of pebbles [ let a heading setxy [ xcor ] of myself [ ycor ] of myself repeat ( 360 / 5 ) [ hatch 1 [ rt a jump .5 ] set a a + 5 ] jump .5 ] ;; no specialization [ ] ) ] set gun-temp max-temp ] ] report fire! end to rock-go ; if count rocks < 5 and any? ships ; [ ; let hh towards one-of ships ; set vx .5 * sin hh ; set vy .5 * cos hh ; ] set vv ( vx * vx + vy * vy ) ifelse ( vv > 1 ) [ rock-explode ] [ let trail-color red + 10 * int min list 120 ( 10 * size ) setxy ( xcor + vx ) ( ycor + vy ) rt av ask patches in-radius (round (.3 * size)) [set pcolor trail-color ] set color rock-color if ( any? ships in-radius ( size / 2 + .5 ) ) [ ask ships [ ship-explode ] ] if ( true ) [ let close min-one-of ( other rocks ) [ distance myself ] let overlap -1 * boundary-distance close if ( overlap > 2 * pixel ) [ if ( overlap > 4 * pixel ) [ ;; too close! force them away face close rt 180 jump overlap / 2 ask close [ face myself rt 180 jump overlap / 2 ] ] collide-with close ] ] ] end to collide-with [ other-particle ] ;; particle procedure let recovery .99 ;;; PHASE 1: initial setup ;; for convenience, grab some quantities from other-particle let h ifelse-value ( vx != 0 or vy != 0 ) [ atan vx vy ] [ 0 ] let mass size ^ 3 let speed sqrt ( vx * vx + vy * vy ) let mass2 [ size ^ 3 ] of other-particle let speed2 [ sqrt ( vx * vx + vy * vy ) ] of other-particle let h2 [ ifelse-value ( vx != 0 or vy != 0 ) [ atan vx vy ] [ 0 ] ] of other-particle ;;modified so that theta is heading toward other particle let theta towards other-particle ;;; PHASE 2: convert velocities to theta-based vector representation ;; now convert my velocity from speed/heading representation to components ;; along theta and perpendicular to theta let v1t ( speed * cos ( theta - h ) ) let v1l ( speed * sin ( theta - h ) ) ;; do the same for other-particle let v2t ( speed2 * cos ( theta - h2 ) ) let v2l ( speed2 * sin ( theta - h2 ) ) ;;; PHASE 3: manipulate vectors to implement collision ;; compute the velocity of the system's center of mass along theta let vcm ( ( ( mass * v1t ) + ( mass2 * v2t ) ) / ( mass + mass2 ) ) ;; now compute the new velocity for each particle along direction theta. ;; velocity perpendicular to theta is unaffected by a collision along theta, ;; so the next two lines actually implement the collision itself, in the ;; sense that the effects of the collision are exactly the following changes ;; in particle velocity. set v1t ( 2 * vcm - v1t ) set v2t ( 2 * vcm - v2t ) let d distance other-particle - ( size + [ size ] of other-particle ) / 2 ;;; PHASE 4: convert back to normal speed/heading ;; now convert my velocity vector into my new speed and heading set speed recovery * sqrt ( ( v1t * v1t ) + ( v1l * v1l ) ) ;; if the magnitude of the velocity vector is 0, atan is undefined. but ;; speed will be 0, so heading is irrelevant anyway. therefore, in that ;; case we'll just leave it unmodified. if v1l != 0 or v1t != 0 [ let new-h ( theta - ( atan v1l v1t ) ) set vx sin new-h * speed set vy cos new-h * speed setxy xcor + vx ycor + vy ] ;; and do the same for other-particle set speed2 recovery * sqrt ( ( v2t ^ 2 ) + ( v2l ^ 2 ) ) if v2l != 0 or v2t != 0 [ let new-h ( theta - ( atan v2l v2t ) ) ask other-particle [ set vx sin new-h * speed2 set vy cos new-h * speed2 setxy xcor + vx ycor + vy ] ] end to fragment-go setxy xcor + vx ycor + vy rt av if random 10 = 1 [ set av av * 2 set size size / 2 set burnout burnout * 1.5 rt 90 hatch 1 [ rt 180 ] ] set max-burnout max-burnout - 1 ifelse max-burnout > 0 [ if max-burnout < 10 [ set color max-burnout ] ] [ die ] end to-report boundary-distance [ obj ] if not is-turtle? obj [ report world-width ] report ( distance obj - ( size / 2 ) - [ size / 2 ] of obj ) end to ship-go set xcor xcor + vx set ycor ycor + vy ;; ask patches in-radius size [ set pcolor 9.9 ] if gun-temp > 0 [ set gun-temp gun-temp - 1 ] let crowd rocks in-radius 20 if any? crowd [ let close min-one-of crowd [ boundary-distance myself ] let dc abs boundary-distance close if dc <= 2 and dc >= 1 [ fragment-setup turquoise 1 1 ] if ( dc < .5 ) [ ship-teleport ] ] end to bullet-go if seeker? and is-rock? target-rock [ lt .05 * subtract-headings heading towards target-rock ] jump bullet-speed let hits rocks with [ distance myself < size / 2 ] if any? hits [ ask hits [ rock-explode ] set bullet-burnout -1 ] set bullet-burnout bullet-burnout - 1 if bullet-burnout <= 0 [ die ] end to ship-spin-ws ask the-ship [ set shape "_ship-001" lt 15 ] end to ship-spin-cw ask the-ship [ set shape "_ship-100" rt 15 ] end to ship-thrust ask the-ship [ ;; get components of thrust vector let am pixel / 2 set ax am * sin heading set ay am * cos heading ;; add to current velocity vector components let nvx vx + ax let nvy vy + ay ;; calculate new velocity magnitude let maxvm 1.00 let nvm sqrt ( nvx * nvx + nvy * nvy ) let svm ifelse-value ( nvm <= maxvm ) [ 1 ] [ nvm / maxvm ] set vx nvx / svm set vy nvy / svm ;; output-print " xcor ycor heading ax ay am vx vy vm" ;; foreach ( list xcor ycor heading ax ay am vx vy vm ) [ n -> output-type fixed n output-type " " ] output-print "" set shape "_ship-010" ] end to-report fixed [ n ] let m ifelse-value n < 0 [ "-" ] [ " " ] let ns ( word " " ( int n ) "." int ( 100 * ( ( abs n ) - ( abs int n ) ) ) "0" ) set ns reverse substring reverse ns 0 7 report ns end to ship-nothing ask the-ship [ set shape "_ship-000" ] end to message-go ;; draw character, if appropriate ;; at end of message, die let font-size 36 let pix 1 / patch-size let char-width ceiling (font-size / patch-size / 1.5) let char-height font-size / patch-size * 2 ifelse ( caret >= length text ) [ die ] [ let new-x pxcor if ( pxcor >= cursor ) [ let c item caret text if c = "W" or c = "m" or c = "M" [ set new-x new-x + 1 if new-x > max-pxcor - 1 [ set new-x min-pxcor ] set xcor new-x set cursor new-x ] if c = "i" or c = "l" [ set new-x new-x - 1 set xcor new-x set cursor new-x ] set plabel c set caret caret + 1 set cursor cursor + char-width ] ;; advance cursor set new-x new-x + 1 if new-x > max-pxcor - 1 [ set new-x min-pxcor ] set xcor new-x ] end to message-setup [ $window# $text ] let this nobody let font-size 36 let pix 1 / patch-size let char-width ceiling (font-size / patch-size / 1.5) let line-height ceiling(font-size / patch-size * 1.4) ;; get or create the indicated message line ifelse ( any? messengers with [ window# = $window# ] ) [ ;; use existing messenger set this one-of messengers with [ window# = $window# ] ] [ ;; make a new messenger ;; since we can't be sure what is making the message, ;; ask a patch to do it, so we can use SPROUT with certainty. ask patch min-pxcor min-pycor [ sprout-messengers 1 [ set this self ] ] ] ;; now work with the messenger ask this [ set shape "cursor" set size 8 set color black set text $text set window# $window# set show-cursor? false setxy ( min-pxcor + ceiling (char-width / 2) ) ( max-pycor - line-height * window# ) let min-py pycor - ( line-height / 2 ) + 1 let max-py pycor + ( line-height / 2 ) - 1 set window patches with [ pycor >= min-py and pycor <= max-py ] ask window [ set plabel "" set pcolor white set plabel-color black ] set caret 0 set cursor pxcor set hidden? true ;; not show-cursor? ] end to write-message let expiration timer + 10 while [ any? messengers and timer < expiration ] [ repeat 5 [ ask messengers [ message-go ]] tick ] ask messengers [ die ] end to mouse-mode if ( mouse-inside? ) [ let diff [ -1 * subtract-headings towardsxy mouse-xcor mouse-ycor heading ] of the-ship let turn 0 ( ifelse ( diff > 0 ) [ set turn 1 ] ( diff < 0 ) [ set turn -1 ] ;; otherwise [ set turn 0 ] ) ask the-ship [ lt diff / 2 ] ] ifelse ( mouse-down? ) [ ifelse click = 0 [ let void ship-fire set click 1 ] [ ship-thrust ] ] [ set click 0 ] end to auto-pilot ask the-ship [ let diff 0 let close rocks in-radius 20 ifelse ( any? close ) [ set close min-one-of close [ distance myself ] ;if ( not member? close link-neighbors ) ; [ ask my-links [ die ] ; create-link-with close ; ] let dd [ distance myself ] of close let rockspeed [ sqrt ( vx * vx + vy * vy ) ] of close let bullspeed bullet-speed let bx dx * bullspeed let by dy * bullspeed let frx [ xcor + vx * dd / bullspeed ] of close let fry [ ycor + vy * dd / bullspeed ] of close let frh towardsxy frx fry let fdist distancexy frx fry let fhdiff subtract-headings frh heading ;; let dist boundary-distance close ifelse ( abs fhdiff > 2 ) [ ifelse ( fhdiff < 0 ) [ lt 5 ] [ rt 5 ] ] [ ifelse ( fdist > 2 * ( bullet-speed * bullet-burnout ) ) [ ship-thrust ] [ if ship-fire [ if not any? reticules [ reticule-setup ] ask active-reticule [ set timeout timer + 2 setxy frx fry show-turtle ; create-link-with close ; [ set thickness 2 * pixel ; set color violet ; ] hatch 1 [ hide-turtle set active-reticule self set timeout 0 ] ] ] ] ] ] [ let rnd random 100 ( ifelse ( rnd < 5 ) [ ship-spin-ws ] ( rnd >= 40 and rnd < 55 ) [ ship-thrust ] ( rnd >= 90 and rnd < 95 ) [ ship-spin-cw ] [ let void ship-fire ] ) ] ] end to GET-input if ( any? ships ) [ ship-nothing ifelse ( full-auto? ) [ auto-pilot ] [ if ( mouse-mode? ) [ mouse-mode ] ( ifelse ( keypress = "fire" ) [ let void ship-fire ] ( keypress = "ws" ) [ ship-spin-ws ] ( keypress = "cw" ) [ ship-spin-cw ] ( keypress = "t" ) [ ship-thrust ] [ ship-nothing ] ) set keypress "" ] ] end to shapes-setup set-default-shape ships "_ship-000" set-default-shape rocks "rock-1" set-default-shape bullets "bullet" set-default-shape fragments "fragment" set-default-shape messengers "cursor" end to startup clear-all reset-ticks message-setup 1 "Please press RUN" write-message tick end to globals-setup set pixel 1 / patch-size set active-reticule nobody end to rocks-setup if num-rocks = false or num-rocks < 5 [ set num-rocks 5 ] repeat num-rocks [ setup-rock ] let retry-limit 50 let too-many-rocks true while [ too-many-rocks and retry-limit > 0 ] [ set too-many-rocks false ASK ROCKS [ LET too-close OTHER ROCKS IN-RADIUS (SIZE * 2) LET is-too-close? ANY? too-close SET too-many-rocks too-many-rocks OR is-too-close? IF is-too-close? [ RT RANDOM 360 JUMP 1 ] SET retry-limit retry-limit - 1 ] ] end to ship-teleport let max-jumps 100 let crowd rocks in-radius 20 hatch-HS-effects 1 [ set size 3 set color violet set effect-direction 1 set shape "circle" ] while [ max-jumps > 0 and any? crowd with [ boundary-distance myself < 2 ] ] [ fragment-setup green 0 1 setxy random-xcor random-ycor set vx 0 set vy 0 set crowd rocks in-radius 10 set max-jumps max-jumps - 1 ;display ] hatch-HS-effects 1 [ set color red set size 20 set effect-direction -1 set shape "circle" ] fragment-setup lime 1 2 end to clock-setup create-clocks 1 [ set shape "clock" set start-time 0 set current-time 0 set elapsed-time 0 set cumulative-time 0 set pause-until 0 set clock-on false set size 3 setxy 0 max-pycor - size / 2 - pixel ] end to game-setup set score 0 globals-setup shapes-setup game-clear rocks-setup logo-display directions-display write-message clock-setup stop-inspecting-dead-agents set setup-finished true reset-ticks end to new-game set score 0 game-clear rocks-setup ship-setup set setup-finished true end to directions-display message-setup 5 "THE MISSION:" write-message message-setup 6 "DESTROY RUBBLE." write-message message-setup 7 "-PRESS START-" end to game-go ifelse ( setup-finished = 0 ) [ game-setup ] [ get-input ask ships [ ship-go ] ask bullets [ bullet-go ] set rock-color white ;; ifelse-value ( random 100 < 10 ) [ 1 + random-float 1 + 2.9 * random 2 ] [ white ] ask rocks [ rock-go ] ask fragments [ fragment-go ] ask messengers [ message-go ] ask reticules [ reticules-go ] ask HS-effects [ ifelse ( size < 3 or size > 20 ) [ die ] [ set size size + effect-direction ] ] ;; ask aliens [ GO-alien ] ;; if ( not ( any? ships or any? messengers ) ) [ messenger-setup 1 "PRESS PLAY" ] if ( not ( any? rocks ) ) [ set num-rocks num-rocks * 1.25 rocks-setup ask ships [ home set vx 0 set vy 0 ] ] ask patches [ let hue ifelse-value (is-list? pcolor) [pcolor ][ extract-rgb pcolor ] set rr item 0 hue ^ 2 * .95 set gg item 1 hue ^ 2 * .95 set bb item 2 hue ^ 2 * .95 ] diffuse rr .2 diffuse gg .2 diffuse bb .2 ask patches [ set pcolor rgb sqrt rr sqrt gg sqrt bb ] ] tick end to logo-display clear-patches ask letters [ die ] tick ;; ask patches with [ ( pxcor + pycor ) mod 2 = 0 ] [ set pcolor ( 2.5 + black ) ] let logo0 "RUBBLE" let logo1 "TROUBLE" logo-animate logo0 0 logo-animate logo1 1 ;display end to logo-animate [ logo line ] let len length logo let letter-size ( world-width ) / ( len ) let start-x min-pxcor + ( world-width - 1 ) / 2 - ( ( len * letter-size ) / 2 ) + .5 * letter-size let line-height 1.5 let these-letters no-turtles foreach range len [ [ t ] -> create-letters 1 [ let c item t logo let pos-x letter-size * t setxy ( start-x + pos-x ) max-pxcor - letter-size * line * line-height if ( c = " " ) [ set c "space" ] set shape word "logo-" c set size letter-size set color base-color set heading 0 set base-xcor xcor set base-size size set base-color white set color base-color set base-heading heading setxy 0 min-pycor set size 0 set these-letters ( turtle-set these-letters self ) ] ] let top-y ( world-height - 1 ) - ( .5 * letter-size ) - line * letter-size * line-height ( foreach ( range 0 1.0 ( 2 / 30 ) ) [ [ ratio ] -> let y min-pycor + top-y * ratio let m2 ratio * letter-size ask these-letters [ set size m2 set ycor y set xcor base-xcor * ratio ] tick wait 1 / 30 ] ) set pixel 1 / patch-size let thick PIXEL * 16 let lcolor lime - 3.5 ask letters [ let mythick thick LET MYCOLOR LCOLOR repeat 4 [ hatch 1 [ set color MYCOLOR x_set-line-thickness mythick set mythick mythick / 2 SET MYCOLOR MYCOLOR + 2 ] ] DIE ] ; end to play-note [ $inst $key $vel $dur ] ;; sound:play-note $inst $key $vel $dur end to play-note-later [ $delay $inst $key $vel $dur ] ;; sound:play-note-later $delay $inst $key $vel $dur end to play-drum [ $inst $vel ] ;; sound:play-drum $inst $vel end to stop-music ;; sound:stop-music end to sfx [ fx option ] ( ifelse ( fx = "explode-rock" ) [ play-drum "CRASH CYMBAL 2" 12 play-note-later .10 "timpani" ( 45 - option * 4 ) 64 + option .3 play-note "timpani" ( 42 - option * 2 ) 64 + option .1 ] ( fx = "ship-explode" ) [ play-drum "CRASH CYMBAL 2" 127 play-note-later .20 "timpani" 42 100 .1 play-note-later .10 "timpani" 42 100 .1 play-note "timpani" 40 64 .1 ] ( fx = "pew" ) [ let fxarppegio-steps 5 let fxkeys map [ r -> 42 - r * 3 ] ( range fxarppegio-steps ) let fxvelocity 48 let fxduration .02 * fxarppegio-steps let fxdelay-step fxduration / fxarppegio-steps foreach ( range fxarppegio-steps ) [ [ i ] -> play-note-later ( i * fxdelay-step ) "SYNTH BRASS 1" ( item i fxkeys ) fxvelocity fxdelay-step ] ] [ stop-music ] ) end ;; The following code was publsihed by and released to the Public Domain by Uri Wilensky, ;; and was obtained from the NetLogo v 6.3 Model Library. ;; note that the 6.2.2 version used TAN 90, which is mathematically undefined, but ;; netlogo used to incorrectly report as a value ;; reports a two-item list of x and y coordinates, or an empty ;; list if no intersection is found to-report intersection [ t1 t2 ] let is-t1-vertical? ( [ heading ] of t1 = 0 or [ heading ] of t1 = 180 ) let is-t2-vertical? ( [ heading ] of t2 = 0 or [ heading ] of t2 = 180 ) ;; is t1 vertical? if so, swap the two turtles, and run again. ;; ( unless both are vertical, i.e. they are parallel--report an empty list ) ifelse ( is-t1-vertical? ) [ ifelse ( is-t2-vertical? ) [ report [ ] ] [ report intersection t2 t1 ] ;; report ends the procedure immediately ] [ let m1 [ tan ( 90 - heading ) ] of t1 ;; is t2 vertical? if so, handle specially ifelse ( is-t2-vertical? ) [ ;; represent t1 line in slope-intercept form ( y=mx+c ) let c1 [ ycor - xcor * m1 ] of t1 ;; t2 is vertical so we know x already let x [ xcor ] of t2 ;; solve for y let y m1 * x + c1 ;; check if intersection point lies on both segments ifelse [ not x-within? x ] of t1 or [ not y-within? y ] of t2 [ report [ ] ] [ report list x y ] ] [ let m2 [ tan ( 90 - heading ) ] of t2 ;; treat parallel/collinear lines as non-intersecting ifelse m1 = m2 [ report [ ] ] [ ;; now handle the normal case where neither turtle is vertical; ;; start by representing lines in slope-intercept form ( y=mx+c ) let c1 [ ycor - xcor * m1 ] of t1 let c2 [ ycor - xcor * m2 ] of t2 ;; now solve for x let x ( c2 - c1 ) / ( m1 - m2 ) ;; check if intersection point lies on both segments ifelse [ not x-within? x ] of t1 or [ not x-within? x ] of t2 [ report [ ] ] [ report list x ( m1 * x + c1 ) ] ] ] ] end to-report x-within? [ x ] ;; turtle procedure report abs ( xcor - x ) <= abs ( size / 2 * dx ) end to-report y-within? [ y ] ;; turtle procedure report abs ( ycor - y ) <= abs ( size / 2 * dy ) end ;; below only for when generating a new thumbnail image for the commons ;to setup ; clear-all ; startup ; new-game ; set num-rocks 15 ; rocks-setup ;end ;to go ; repeat 15 [ game-go wait 1 / 30 ] ;end
There are 8 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Rubble Trouble!.png | preview | Preview for 'Rubble Trouble!' | over 1 year ago, by James Steiner | Download |
This model does not have any ancestors.
This model does not have any descendants.