Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,54 +1,54 @@
|
|||
import std.stdio, std.random, std.string, std.algorithm;
|
||||
|
||||
enum TREE_PROB = 0.55; // original tree probability
|
||||
enum F_PROB = 0.01; // auto combustion probability
|
||||
enum P_PROB = 0.01; // tree creation probability
|
||||
enum treeProb = 0.55; // Original tree probability.
|
||||
enum fProb = 0.01; // Auto combustion probability.
|
||||
enum cProb = 0.01; // Tree creation probability.
|
||||
|
||||
enum Cell : char { empty=' ', tree='T', fire='#' }
|
||||
alias Cell[][] World;
|
||||
alias World = Cell[][];
|
||||
|
||||
bool hasBurningNeighbours(in World world, in int r, in int c)
|
||||
pure nothrow {
|
||||
foreach (rowShift; -1 .. 2)
|
||||
foreach (colShift; -1 .. 2)
|
||||
if ((r + rowShift) >= 0 && (r + rowShift) < world.length &&
|
||||
(c + colShift) >= 0 && (c + colShift) < world[0].length &&
|
||||
world[r + rowShift][c + colShift] == Cell.fire)
|
||||
return true;
|
||||
return false;
|
||||
pure nothrow @safe @nogc {
|
||||
foreach (immutable rowShift; -1 .. 2)
|
||||
foreach (immutable colShift; -1 .. 2)
|
||||
if ((r + rowShift) >= 0 && (r + rowShift) < world.length &&
|
||||
(c + colShift) >= 0 && (c + colShift) < world[0].length &&
|
||||
world[r + rowShift][c + colShift] == Cell.fire)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void nextState(in World world, World nextWorld) {
|
||||
foreach (r, row; world)
|
||||
foreach (c, elem; row)
|
||||
final switch (elem) {
|
||||
case Cell.empty:
|
||||
nextWorld[r][c]= uniform(0.,1.)<P_PROB?Cell.tree:Cell.empty;
|
||||
break;
|
||||
void nextState(in World world, World nextWorld) /*nothrow*/ @safe /*@nogc*/ {
|
||||
foreach (immutable r, const row; world)
|
||||
foreach (immutable c, immutable elem; row)
|
||||
final switch (elem) with (Cell) {
|
||||
case empty:
|
||||
nextWorld[r][c]= (uniform01 < cProb) ? tree : empty;
|
||||
break;
|
||||
|
||||
case Cell.tree:
|
||||
if (world.hasBurningNeighbours(r, c))
|
||||
nextWorld[r][c] = Cell.fire;
|
||||
else
|
||||
nextWorld[r][c]=uniform(0.,1.)<F_PROB?Cell.fire:Cell.tree;
|
||||
break;
|
||||
case tree:
|
||||
if (world.hasBurningNeighbours(r, c))
|
||||
nextWorld[r][c] = fire;
|
||||
else
|
||||
nextWorld[r][c] = (uniform01 < fProb) ? fire : tree;
|
||||
break;
|
||||
|
||||
case Cell.fire:
|
||||
nextWorld[r][c] = Cell.empty;
|
||||
break;
|
||||
}
|
||||
case fire:
|
||||
nextWorld[r][c] = empty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto world = new World(8, 65);
|
||||
foreach (row; world)
|
||||
foreach (ref el; row)
|
||||
el = uniform(0.0, 1.0) < TREE_PROB ? Cell.tree : Cell.empty;
|
||||
auto nextWorld = new World(world.length, world[0].length);
|
||||
void main() @safe {
|
||||
auto world = new World(8, 65);
|
||||
foreach (row; world)
|
||||
foreach (ref el; row)
|
||||
el = (uniform01 < treeProb) ? Cell.tree : Cell.empty;
|
||||
auto nextWorld = new World(world.length, world[0].length);
|
||||
|
||||
foreach (i; 0 .. 4) {
|
||||
nextState(world, nextWorld);
|
||||
writeln(join(cast(string[])nextWorld, "\n"), "\n");
|
||||
swap(world, nextWorld);
|
||||
}
|
||||
foreach (immutable i; 0 .. 4) {
|
||||
nextState(world, nextWorld);
|
||||
writefln("%(%(%c%)\n%)\n", nextWorld);
|
||||
world.swap(nextWorld);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ immutable white = Color(255, 255, 255),
|
|||
|
||||
void nextState(ref World world, ref World nextWorld,
|
||||
ref Xorshift rnd, Image img) {
|
||||
enum double div = typeof(rnd.front).max;
|
||||
immutable nr = world.length;
|
||||
immutable nc = world[0].length;
|
||||
foreach (immutable r, const row; world)
|
||||
|
|
@ -23,8 +22,7 @@ void nextState(ref World world, ref World nextWorld,
|
|||
START: final switch (elem) with (Cell) {
|
||||
case empty:
|
||||
img.putPixel(c, r, white);
|
||||
nextWorld[r][c] = (rnd.front / div) < P_PROB ? tree : empty;
|
||||
rnd.popFront;
|
||||
nextWorld[r][c] = rnd.uniform01 < P_PROB ? tree : empty;
|
||||
break;
|
||||
|
||||
case tree:
|
||||
|
|
@ -39,8 +37,7 @@ void nextState(ref World world, ref World nextWorld,
|
|||
break START;
|
||||
}
|
||||
|
||||
nextWorld[r][c]= (rnd.front / div) < F_PROB ? burning : tree;
|
||||
rnd.popFront;
|
||||
nextWorld[r][c]= rnd.uniform01 < F_PROB ? burning : tree;
|
||||
break;
|
||||
|
||||
case burning:
|
||||
|
|
@ -57,7 +54,7 @@ void main() {
|
|||
auto world = new World(worldSide);
|
||||
foreach (ref row; world)
|
||||
foreach (ref el; row)
|
||||
el = uniform(0.0, 1.0, rnd) < TREE_PROB ? Cell.tree : Cell.empty;
|
||||
el = rnd.uniform01 < TREE_PROB ? Cell.tree : Cell.empty;
|
||||
auto nextWorld = new World(world[0].length);
|
||||
|
||||
auto w= new SimpleWindow(world.length,world[0].length,"ForestFire");
|
||||
|
|
|
|||
97
Task/Forest-fire/Lua/forest-fire.lua
Normal file
97
Task/Forest-fire/Lua/forest-fire.lua
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
-- ForestFire automaton implementation
|
||||
-- Rules: at each step:
|
||||
-- 1) a burning tree disappears
|
||||
-- 2) a non-burning tree starts burning if any of its neighbours is
|
||||
-- 3) an empty spot may generate a tree with prob P
|
||||
-- 4) a non-burning tree may ignite with prob F
|
||||
|
||||
local socket = require 'socket' -- needed for socket.sleep
|
||||
local curses = require 'curses'
|
||||
|
||||
local p_spawn, p_ignite = 0.005, 0.0002
|
||||
local naptime = 0.03 -- seconds
|
||||
local forest_x, forest_y = 60, 30
|
||||
|
||||
local forest = (function (x, y)
|
||||
local wrl = {}
|
||||
for i = 1, y do
|
||||
wrl[i] = {}
|
||||
for j = 1, x do
|
||||
local rand = math.random()
|
||||
wrl[i][j] = (rand < 0.5) and 1 or 0
|
||||
end
|
||||
end
|
||||
return wrl
|
||||
end)(forest_x, forest_y)
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
forest.step = function (self)
|
||||
for i = 1, #self do
|
||||
for j = 1, #self[i] do
|
||||
if self[i][j] == 0 then
|
||||
if math.random() < p_spawn then self[i][j] = 1 end
|
||||
elseif self[i][j] == 1 then
|
||||
if self:ignite(i, j) or math.random() < p_ignite then self[i][j] = 2 end
|
||||
elseif self[i][j] == 2 then self[i][j] = 0
|
||||
else error("Error: forest[" .. i .. "][" .. j .. "] is " .. self[i][j] .. "!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
forest.draw = function (self)
|
||||
for i = 1, #self do
|
||||
for j = 1, #self[i] do
|
||||
if self[i][j] == 0 then win:mvaddch(i,j," ")
|
||||
elseif self[i][j] == 1 then
|
||||
win:attron(curses.color_pair(1))
|
||||
win:mvaddch(i,j,"Y")
|
||||
win:attroff(curses.color_pair(1))
|
||||
elseif self[i][j] == 2 then
|
||||
win:attron(curses.color_pair(2))
|
||||
win:mvaddch(i,j,"#")
|
||||
win:attroff(curses.color_pair(2))
|
||||
else error("self[" .. i .. "][" .. j .. "] is " .. self[i][j] .. "!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
forest.ignite = function (self, i, j)
|
||||
for k = i - 1, i + 1 do
|
||||
if k < 1 or k > #self then goto continue1 end
|
||||
for l = j - 1, j + 1 do
|
||||
if l < 1 or
|
||||
l > #self[i] or
|
||||
math.abs((k - i) + (l - j)) ~= 1
|
||||
then
|
||||
goto continue2
|
||||
end
|
||||
if self[k][l] == 2 then return true end
|
||||
::continue2::
|
||||
end
|
||||
::continue1::
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local it = 1
|
||||
curses.initscr()
|
||||
curses.start_color()
|
||||
curses.echo(false)
|
||||
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
|
||||
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
|
||||
win = curses.newwin(forest_y + 2, forest_x, 0, 0)
|
||||
win:clear()
|
||||
win:mvaddstr(forest_y + 1, 0, "p_spawn = " .. p_spawn .. ", p_ignite = " .. p_ignite)
|
||||
repeat
|
||||
forest:draw()
|
||||
win:move(forest_y, 0)
|
||||
win:clrtoeol()
|
||||
win:addstr("Iteration: " .. it .. ", nap = " .. naptime*1000 .. "ms")
|
||||
win:refresh()
|
||||
forest:step()
|
||||
it = it + 1
|
||||
socket.sleep(naptime)
|
||||
until false
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
constant RED = "\e[1;31m";
|
||||
constant CLEAR = "\e[0m";
|
||||
my $RED = "\e[1;31m";
|
||||
my $YELLOW = "\e[1;33m";
|
||||
my $GREEN = "\e[1;32m";
|
||||
my $CLEAR = "\e[0m";
|
||||
|
||||
enum Cell-State <Empty Tree Burning>;
|
||||
my @show = (' ', '木', RED ~ '木' ~ CLEAR);
|
||||
enum Cell-State <Empty Tree Heating Burning>;
|
||||
my @show = (' ', $GREEN ~ '木', $YELLOW ~ '木', $RED ~ '木');
|
||||
|
||||
class Forest {
|
||||
has Cell-State @!grid;
|
||||
has @!grid;
|
||||
has @!neighbors;
|
||||
has Int $.height;
|
||||
has Int $.width;
|
||||
has $.p;
|
||||
has $.f;
|
||||
has @!cells = ^$!height X ^$!width;
|
||||
|
||||
method new(Int $height, Int $width, $p=0.01, $f=0.001) {
|
||||
my $c = self.bless(:$height, :$width, :$p, :$f);
|
||||
|
|
@ -24,36 +27,35 @@ class Forest {
|
|||
}
|
||||
|
||||
method !init-neighbors {
|
||||
for ^$!height X ^$!width -> $i, $j {
|
||||
@!neighbors[$i][$j] = gather for
|
||||
for @!cells -> $i, $j {
|
||||
@!neighbors[$i][$j] = eager gather for
|
||||
[-1,-1],[+0,-1],[+1,-1],
|
||||
[-1,+0],( ),[+1,+0],
|
||||
[-1,+1],[+0,+1],[+1,+1]
|
||||
{
|
||||
take-rw @!grid[$i + .[0]][$j + .[1]] // next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method step {
|
||||
my @new;
|
||||
for ^$!height X ^$!width -> $i, $j {
|
||||
my @heat;
|
||||
for @!cells -> $i, $j {
|
||||
given @!grid[$i][$j] {
|
||||
when Empty { @new[$i][$j] = rand < $!p ?? Tree !! Empty }
|
||||
when Tree { @new[$i][$j] =
|
||||
(@!neighbors[$i][$j].any === Burning or rand < $!f) ?? Burning !! Tree;
|
||||
}
|
||||
when Burning { @new[$i][$j] = Empty }
|
||||
when Empty { @!grid[$i][$j] = rand < $!p ?? Tree !! Empty }
|
||||
when Tree { @!grid[$i][$j] = rand < $!f ?? Heating !! Tree }
|
||||
when Heating { @!grid[$i][$j] = Burning; push @heat, $i, $j; }
|
||||
when Burning { @!grid[$i][$j] = Empty }
|
||||
}
|
||||
}
|
||||
for ^$!height X ^$!width -> $i, $j {
|
||||
@!grid[$i][$j] = @new[$i][$j];
|
||||
}
|
||||
for @heat -> $i,$j {
|
||||
$_ = Heating for @!neighbors[$i][$j].grep(Tree);
|
||||
}
|
||||
}
|
||||
|
||||
method Str {
|
||||
join '', gather for ^$!height -> $i {
|
||||
take @show[@!grid[$i].list], "\n";
|
||||
method show {
|
||||
for ^$!height -> $i {
|
||||
say @show[@!grid[$i].list].join;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +66,7 @@ print "\e[2J"; # ANSI clear screen
|
|||
my $i = 0;
|
||||
loop {
|
||||
print "\e[H"; # ANSI home
|
||||
say $i++;
|
||||
say $f.Str;
|
||||
say $CLEAR, $i++;
|
||||
$f.show;
|
||||
$f.step;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,64 +3,60 @@
|
|||
├─── full version has many more options and enhanced displays. ────┤
|
||||
└──────────────────────────────────────────────────────────────────┘ */
|
||||
signal on syntax; signal on novalue /*handle REXX program errors. */
|
||||
signal on halt /*handle cell growth interruptus.*/
|
||||
parse arg peeps '(' generations rows cols bare! life! clearscreen every
|
||||
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU
|
||||
signal on halt /*handle growth interruptus. */
|
||||
_= /*(below) nullify some options. */
|
||||
parse var _ generations rows cols birth lightning bare! fire! tree!,
|
||||
randseed clearscreen every
|
||||
if randseed\=='' then call random ,,randseed
|
||||
percent = 100 /*handy-dandy constant for using%*/
|
||||
field = percent**2 /*size of the probability field. */
|
||||
blank = 'BLANK'
|
||||
generations = p(generations 100)
|
||||
rows = p(rows 3)
|
||||
cols = p(cols 3)
|
||||
rows = p(rows word(scrsize(),1)-2)
|
||||
cols = p(cols max(79,linesize())-1)
|
||||
bare! = pickchar(bare! blank)
|
||||
clearscreen = p(clearscreen 0)
|
||||
fire! = pickchar(fire! '▒')
|
||||
tree! = pickchar(tree! '18'x)
|
||||
clearscreen = p(clearscreen 1)
|
||||
every = p(every 999999999)
|
||||
life! = pickchar(life! '☼')
|
||||
fents=max(79,cols) /*fence width shown after display*/
|
||||
$.=bare! /*the universe is new, and barren*/
|
||||
birth = p(strip(birth,,'%') 50 )*percent
|
||||
lightning = p(strip(lightning,,'%') 1/8)*percent
|
||||
$.=bare! /*the forest is a treeless field.*/
|
||||
@.=bare! /*also, the alternate universe. */
|
||||
gens=abs(generations) /*use this for convenience. */
|
||||
x=space(peeps) /*remove superfluous spaces. */
|
||||
if x=='' then x='2,1 2,2 2,3'
|
||||
|
||||
do while x \==''
|
||||
parse var x p x; parse var p r ',' c .; $.r=overlay(life!,$.r,c+1)
|
||||
end
|
||||
life=0; !.=0; call showCells /*show initial state of the cells*/
|
||||
/*─────────────────────────────────────watch cell colony grow/live/die. */
|
||||
do life=1 for gens
|
||||
do r=1 for rows; rank=bare!
|
||||
do c=2 for cols; ?=substr($.r,c,1); ??=?; n=neighbors()
|
||||
select /*select da quickest choice first*/
|
||||
when ?==bare! then if n==3 then ??=life!
|
||||
otherwise if n<2 | n>3 then ??=bare!
|
||||
end /*select*/
|
||||
/*═════════════════════════════════════watch the forest grow and/or burn*/
|
||||
do life=1 for gens /*process a forest life cycle. */
|
||||
do r=1 for rows; rank=bare!
|
||||
do c=2 for cols; ?=substr($.r,c,1); ??=?
|
||||
select /*select da quickest choice first*/
|
||||
when ?==tree! then if ignite?() then ??=fire!
|
||||
when ?==bare! then if random(1,field)<=birth then ??=tree!
|
||||
otherwise /*fire*/ ??=bare!
|
||||
end /*select*/
|
||||
rank=rank || ??
|
||||
end /*c*/
|
||||
end /*c*/ /*ignore column 1, start with 2.*/
|
||||
@.r=rank
|
||||
end /*c*/
|
||||
end /*r*/
|
||||
|
||||
do r=1 for rows; $.r=@.r; end /*assign alternate cells ──► real*/
|
||||
if life//every==0 | generations>0 | life==gens then call showCells
|
||||
end /*life*/
|
||||
/*─────────────────────────────────────stop watching the universe (life)*/
|
||||
do r=1 for rows; $.r=@.r; end /*assign alternate cells ──► real*/
|
||||
if life//every==0 | generations>0 | life==gens then call showForest
|
||||
end /*life*/
|
||||
/*═════════════════════════════════════stop watching the forest grow. */
|
||||
halt: cycles=life-1; if cycles\==gens then say 'REXX program interrupted.'
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*───────────────────────────────SHOWCELLS subroutine─-─────────────────*/
|
||||
showCells: if clearscreen then 'CLS' /* ◄─── change this for your OS.*/
|
||||
_=; do r=rows by -1 for rows /*show the forest in proper order*/
|
||||
z=strip(substr($.r,2),'T') /*pick off the meat of the row. */
|
||||
say z; _=_ || z /*be neat about trailing blanks. */
|
||||
/*───────────────────────────────SHOWFOREST subroutine──────────────────*/
|
||||
showForest: if clearscreen then 'CLS' /* ◄─── change this for your OS.*/
|
||||
do r=rows by -1 for rows /*show the forest in proper order*/
|
||||
say strip(substr($.r,2),'T') /*be neat about trailing blanks. */
|
||||
end /*r*/
|
||||
say right(copies('═',fents)life,fents) /*show&tell for a stand of trees.*/
|
||||
if _=='' then exit /*if no life, then stop the run. */
|
||||
if !._ then do; say 'repeating ...'; exit; end
|
||||
!._=1 /*assign a state & compare later.*/
|
||||
say right(copies('═',cols)life, cols) /*show&tell for a stand of trees.*/
|
||||
return
|
||||
/*───────────────────────────────NEIGHBORS subroutine───────────────────*/
|
||||
neighbors: rp=r+1; cp=c+1; rm=r-1; cm=c-1 /*count 8 neighbors of a cell*/
|
||||
return (substr($.rm,cm,1)==life!) + (substr($.rm,c ,1)==life!) + ,
|
||||
(substr($.rm,cp,1)==life!) + (substr($.r ,cm,1)==life!) + ,
|
||||
(substr($.r ,cp,1)==life!) + (substr($.rp,cm,1)==life!) + ,
|
||||
(substr($.rp,c ,1)==life!) + (substr($.rp,cp,1)==life!)
|
||||
/*───────────────────────────────1-liner subroutines────────────────────*/
|
||||
/*──────────────────────────────────IGNITE? subroutine──────────────────*/
|
||||
ignite?: if substr($.r,c+1,1)==fire! then return 1 /*east on fire ?*/
|
||||
if substr($.r,c-1,1)==fire! then return 1; rp=r+1; rm=r-1
|
||||
cm=c-1; if pos(fire!,substr($.rm,cm,3)substr($.rp,cm,3))\==0 then return 1
|
||||
return random(1,field) <= lightning
|
||||
/*───────────────────────────────1─liner subroutines─────────────────────────────────────────────────────────────────────────────────*/
|
||||
err: say;say;say center(' error! ',max(40,linesize()%2),"*");say;do j=1 for arg();say arg(j);say;end;say;exit 13
|
||||
novalue: syntax: call err 'REXX program' condition('C') "error",condition('D'),'REXX source statement (line' sigl"):",sourceline(sigl)
|
||||
pickchar: _=p(arg(1));if translate(_)==blank then _=' ';if length(_) ==3 then _=d2c(_);if length(_) ==2 then _=x2c(_);return _
|
||||
|
|
|
|||
|
|
@ -1,60 +1,44 @@
|
|||
require 'enumerator'
|
||||
class Forest_Fire
|
||||
Neighborhood = [-1,0,1].product([-1,0,1]) - [0,0]
|
||||
States = {empty:" ", tree:"T", fire:"#"}
|
||||
|
||||
def transition arr, tree_prob, fire_prob
|
||||
arr.enum_with_index.map do |cell, i|
|
||||
if i == 0 or i == arr.length - 1
|
||||
# boundary conditions: cells are always empty here
|
||||
:empty
|
||||
else
|
||||
case cell
|
||||
when :fire
|
||||
# burning cells become empty
|
||||
:empty
|
||||
when :empty
|
||||
# empty cells grow a tree with probability tree_prob
|
||||
rand < tree_prob ? :tree : :empty
|
||||
when :tree
|
||||
# check my neighbouring cells, are they on fire?
|
||||
if arr[i - 1] == :fire or arr[i + 1] == :fire
|
||||
:fire
|
||||
def initialize(xsize, ysize=xsize, p=0.5, f=0.01)
|
||||
@xsize, @ysize, @p, @f = xsize, ysize, p, f
|
||||
@field = Array.new(xsize+1) {|i| Array.new(ysize+1, :empty)}
|
||||
@generation = 0
|
||||
end
|
||||
|
||||
def evolve
|
||||
@generation += 1
|
||||
work = @field.map{|row| row.map{|cell| cell}}
|
||||
for i in 0...@xsize
|
||||
for j in 0...@ysize
|
||||
case cell=@field[i][j]
|
||||
when :empty
|
||||
cell = :tree if rand < @p
|
||||
when :tree
|
||||
cell = :fire if fire?(i,j)
|
||||
else
|
||||
# neighbours not on fire, but catch fire at random
|
||||
rand < fire_prob ? :fire : :tree
|
||||
cell = :empty
|
||||
end
|
||||
work[i][j] = cell
|
||||
end
|
||||
end
|
||||
@field = work
|
||||
end
|
||||
|
||||
def fire?(i,j)
|
||||
rand < @f or Neighborhood.any? {|di,dj| @field[i+di][j+dj] == :fire}
|
||||
end
|
||||
|
||||
def display
|
||||
puts "Generation : #@generation"
|
||||
puts @xsize.times.map{|i| @ysize.times.map{|j| States[@field[i][j]]}.join}
|
||||
end
|
||||
end
|
||||
|
||||
def pretty_print arr
|
||||
# colour the trees green, the fires red, and the empty spaces black
|
||||
print(arr.map { |cell|
|
||||
"\e[3" +
|
||||
case cell
|
||||
when :tree
|
||||
"2mT"
|
||||
when :fire
|
||||
"1mF"
|
||||
when :empty
|
||||
"0m "
|
||||
end + "\e[0m"
|
||||
}.join)
|
||||
forest = Forest_Fire.new(10,30)
|
||||
10.times do |i|
|
||||
forest.evolve
|
||||
forest.display
|
||||
end
|
||||
|
||||
N = 20 # 20 trees
|
||||
P = 0.5 # probability of growing a tree
|
||||
F = 0.1 # probability of catching on fire
|
||||
|
||||
srand Time.now.to_i
|
||||
|
||||
# each cell has a 50/50 chance of being a tree
|
||||
array = (1..N).map { rand < 0.5 ? :tree : :empty }
|
||||
array[0] = array[-1] = :empty # boundary conditions
|
||||
pretty_print array
|
||||
puts
|
||||
|
||||
begin
|
||||
array = transition(array, P, F)
|
||||
|
||||
pretty_print array
|
||||
end while gets.chomp.downcase != "q"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue