Examples/FollowThatTurtleHideAndSeek.turtle.ps1
<# .SYNOPSIS Hide and Seek .DESCRIPTION Simple behavior modelling with Turtle. .NOTES Imagine we have eight turtles playing hide and seek Four turtles are seeking. Four turtles are hiding. Each hiding turtle starts in the center. Each seeking turtle will chase a hiding turtle. Each hiding turtle will run away at an angle (by default 90 degrees). #> param( [double] $SquareSize = 200, [double] $HiderSpeed = 2, [double] $SeekerSpeedRatio = ((1 + [Math]::Sqrt(5))/2), [double] $EvadeAngle = 90 ) if ($PSScriptRoot) { Push-Location $PSScriptRoot} $midpoint = ($squareSize/2), ($squareSize/2) $seekerSpeed = $HiderSpeed * $SeekerSpeedRatio # (1 + (Get-Random -Min 10 -Max 50)/50) # (Get-Random -Min 1 -Max 5) $stepCount = $squareSize/2 * (1 + ([Math]::Abs($attackerSpeed - $evaderSpeed))) $hideAndSeek = turtle square $squareSize stroke '#4488ff' turtles ([Ordered]@{ s1 = turtle teleport 0 0 stroke '#4488ff' # stroke 'red' pathclass 'red-stroke' fill red s2 = turtle teleport $squareSize 0 stroke '#4488ff' # stroke 'yellow' pathclass 'yellow-stroke' fill yellow s3 = turtle teleport $squareSize $squareSize stroke '#4488ff' # stroke 'green' pathclass 'green-stroke' fill green s4 = turtle teleport 0 $squareSize stroke '#4488ff' # stroke 'blue' PathClass 'blue-stroke' fill blue h1 = turtle teleport $midpoint stroke '#4488ff' # stroke 'red' fill 'red' h2 = turtle teleport $midpoint stroke '#4488ff' # stroke 'yellow' fill 'yellow' h3 = turtle teleport $midpoint stroke '#4488ff' # stroke 'green' fill 'green' h4 = turtle teleport $midpoint stroke '#4488ff' # stroke 'blue' fill 'blue' }) # Since all attackers and evaders start with equal distances, # when we have caught one we have caught them all. :caughtEm foreach ($n in 1..$stepCount) { # Get the seeker turtles $seekers = $hideAndSeek.Turtles[@($hideAndSeek.Turtles.Keys -match '^s')] # Get the hiding turtles $hiders = $hideAndSeek.Turtles[@($hideAndSeek.Turtles.Keys -match '^h')] for ($hiderNumber = 0; $hiderNumber -lt $hiders.Length; $hiderNumber++) { $thisTurtle = $hiders[$hiderNumber] $runningAwayFrom = $seekers[$hiderNumber % $seekers.Length] $null = $thisTurtle.Rotate( $thisTurtle.Towards($runningAwayFrom) + $evadeAngle # (Get-Random -Minimum 80 -Maximum 100) ).Forward($HiderSpeed) } for ($seekerNumber = 0; $seekerNumber -lt $seekers.Length; $seekerNumber++) { $thisTurtle = $seekers[$seekerNumber] $runningTowards = $hiders[$seekerNumber % $hiders.Length] $null = $thisTurtle.Rotate( $thisTurtle.Towards($runningTowards) # + (Get-Random -Minimum -10 -Maximum 10) ).Forward($seekerSpeed) } for ($seekerNumber = 0; $seekerNumber -lt $seekers.Length; $seekerNumber++) { $thisTurtle = $seekers[$seekerNumber] $runningTowards = $hiders[$seekerNumber % $hiders.Length] if ($thisTurtle.Distance($runningTowards) -le 1) { break caughtEm } } } $hideAndSeek | turtle save ./FollowThatTurtleHideAndSeek.svg $hideAndSeek.Stroke = 'transparent' $hideAndSeek | Save-Turtle ./FollowThatTurtleHideAndSeekPattern.svg Pattern if ($PSScriptRoot) { Pop-Location} |