78 lines
1.6 KiB
Tcl
78 lines
1.6 KiB
Tcl
package require Tcl 8.5
|
|
|
|
# Build a grid
|
|
proc makeGrid {w h {treeProbability 0.5}} {
|
|
global grid gridW gridH
|
|
set gridW $w
|
|
set gridH $h
|
|
set grid [lrepeat $h [lrepeat $w " "]]
|
|
for {set x 0} {$x < $w} {incr x} {
|
|
for {set y 0} {$y < $h} {incr y} {
|
|
if {rand() < $treeProbability} {
|
|
lset grid $y $x "#"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Evolve the grid (builds a copy, then overwrites)
|
|
proc evolveGrid {{fireProbability 0.01} {plantProbability 0.05}} {
|
|
global grid gridW gridH
|
|
set newGrid {}
|
|
for {set y 0} {$y < $gridH} {incr y} {
|
|
set row {}
|
|
for {set x 0} {$x < $gridW} {incr x} {
|
|
switch -exact -- [set s [lindex $grid $y $x]] {
|
|
" " {
|
|
if {rand() < $plantProbability} {
|
|
set s "#"
|
|
}
|
|
}
|
|
"#" {
|
|
if {[burningNeighbour? $x $y] || rand() < $fireProbability} {
|
|
set s "o"
|
|
}
|
|
}
|
|
"o" {
|
|
set s " "
|
|
}
|
|
}
|
|
lappend row $s
|
|
}
|
|
lappend newGrid $row
|
|
}
|
|
set grid $newGrid
|
|
}
|
|
|
|
# We supply the neighbourhood model as an optional parameter (not used...)
|
|
proc burningNeighbour? {
|
|
x y
|
|
{neighbourhoodModel {-1 -1 -1 0 -1 1 0 -1 0 1 1 -1 1 0 1 1}}
|
|
} {
|
|
global grid gridW gridH
|
|
foreach {dx dy} $neighbourhoodModel {
|
|
set i [expr {$x + $dx}]
|
|
if {$i < 0 || $i >= $gridW} continue
|
|
set j [expr {$y + $dy}]
|
|
if {$j < 0 || $j >= $gridH} continue
|
|
if {[lindex $grid $j $i] eq "o"} {
|
|
return 1
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc printGrid {} {
|
|
global grid
|
|
foreach row $grid {
|
|
puts [join $row ""]
|
|
}
|
|
}
|
|
|
|
# Simple main loop; press Return for the next step or send an EOF to stop
|
|
makeGrid 70 8
|
|
while 1 {
|
|
evolveGrid
|
|
printGrid
|
|
if {[gets stdin line] < 0} break
|
|
}
|