Forest fire

define w = `tput cols`.to_i
define h = `tput lines`.to_i
define r = "\033[H"

define red = "\033[31m"
define green = "\033[32m"
define yellow = "\033[33m"

define chars = [' ', green+'*', yellow+'&', red+'&']

define tree_prob = 0.05
define burn_prob = 0.0002

enum |Empty, Tree, Heating, Burning|

define dirs = [
    %n(-1 -1), %n(-1 0), %n(-1 1), %n(0 -1),
    %n(0   1), %n(1 -1), %n(1  0), %n(1  1),
]

var forest = h.of { w.of { 1.rand < tree_prob ? Tree : Empty } }

var range_h = h.range
var range_w = w.range

func iterate {
    var new = h.of{ w.of(0) }
    for i in range_h {
        for j in range_w {
            given (new[i][j] = forest[i][j]) {
              when (Tree) {
                1.rand < burn_prob && (new[i][j] = Heating; next)
                dirs.each { |pair|
                    var y = pair[0]+i
                    range_h.contains(y) || next
                    var x = pair[1]+j
                    range_w.contains(x) || next
                    forest[y][x] == Heating && (new[i][j] = Heating; break)
                }
              }
              when (Heating)            { new[i][j] = Burning }
              when (Burning)            { new[i][j] = Empty   }
              case (1.rand < tree_prob) { new[i][j] = Tree    }
            }
        }
    }
    forest = new
}

STDOUT.autoflush(true)

func init_forest {
    print r
    forest.each { |row|
        print chars[row]
        print "\033[E\033[1G"
    }
    iterate()
}

loop { init_forest() }

OO version:

Last updated

Was this helpful?