new files
This commit is contained in:
parent
3af7344581
commit
86c034bb8b
1364 changed files with 21352 additions and 0 deletions
196
Task/Forest-fire/Sather/forest-fire.sa
Normal file
196
Task/Forest-fire/Sather/forest-fire.sa
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
class FORESTFIRE is
|
||||
private attr fields:ARRAY{ARRAY{INT}};
|
||||
private attr swapu:INT;
|
||||
private attr rnd:RND;
|
||||
private attr verbose:BOOL;
|
||||
private attr generation:INT;
|
||||
readonly attr width, height:INT;
|
||||
const empty:INT := 0;
|
||||
const tree:INT := 1;
|
||||
const burning:INT := 2;
|
||||
|
||||
attr prob_tree, prob_p, prob_f :FLT;
|
||||
|
||||
create(w, h:INT, v:BOOL):SAME is
|
||||
res:FORESTFIRE := new;
|
||||
res.fields := #(2);
|
||||
res.fields[0] := #(w*h);
|
||||
res.fields[1] := #(w*h);
|
||||
res.width := w; res.height := h;
|
||||
res.swapu := 0;
|
||||
res.prob_tree := 0.55;
|
||||
res.prob_p := 0.001;
|
||||
res.prob_f := 0.00001;
|
||||
res.rnd := #RND;
|
||||
res.verbose := v;
|
||||
res.generation := 0;
|
||||
res.initfield;
|
||||
return res;
|
||||
end;
|
||||
|
||||
-- to give variability
|
||||
seed(i:INT) is
|
||||
rnd.seed(i);
|
||||
end;
|
||||
|
||||
create(w, h:INT):SAME is
|
||||
res ::= create(w, h, false);
|
||||
return res;
|
||||
end;
|
||||
|
||||
initfield is
|
||||
n ::= 0;
|
||||
swapu := 0;
|
||||
if verbose and generation > 0 then
|
||||
#ERR + "Previous generation " + generation + "\n";
|
||||
end;
|
||||
generation := 0;
|
||||
loop i ::= 0.upto!(width-1);
|
||||
loop j ::= 0.upto!(height-1);
|
||||
if rnd.uniform > prob_tree.fltd then
|
||||
cset(i, j, empty);
|
||||
else
|
||||
n := n + 1;
|
||||
cset(i, j, tree);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if verbose then
|
||||
#ERR + #FMT("Field size is %dx%d (%d)", width, height, size) + "\n";
|
||||
#ERR + "There are " + n + " trees (" + (100.0*n.flt/size.flt) + "%)\n";
|
||||
#ERR + "prob_tree = " + prob_tree + "\n";
|
||||
#ERR + "prob_f = " + prob_f + "\n";
|
||||
#ERR + "prob_p = " + prob_p + "\n";
|
||||
#ERR + "ratio = " + prob_p/prob_f + "\n";
|
||||
end;
|
||||
end;
|
||||
|
||||
field:ARRAY{INT} is
|
||||
return fields[swapu];
|
||||
end;
|
||||
|
||||
ofield:ARRAY{INT} is
|
||||
return fields[swapu.bxor(1)];
|
||||
end;
|
||||
|
||||
size:INT is
|
||||
return width*height;
|
||||
end;
|
||||
|
||||
set(i, j, t:INT)
|
||||
pre bcheck(i, j)
|
||||
is
|
||||
ofield[j*width + i] := t;
|
||||
end;
|
||||
|
||||
cset(i, j, t:INT)
|
||||
pre bcheck(i, j)
|
||||
is
|
||||
field[j*width + i] := t;
|
||||
end;
|
||||
|
||||
private bcheck(i, j:INT):BOOL is
|
||||
if i.is_between(0, width-1) and j.is_between(0, height-1) then
|
||||
return true; -- is inside
|
||||
else
|
||||
return false; -- is outside
|
||||
end;
|
||||
end;
|
||||
|
||||
get(i, j:INT):INT is
|
||||
if ~bcheck(i, j) then
|
||||
return empty;
|
||||
end;
|
||||
return field[j*width + i];
|
||||
end;
|
||||
|
||||
oget(i, j:INT):INT is
|
||||
if ~bcheck(i, j) then
|
||||
return empty;
|
||||
end;
|
||||
return ofield[j*width + i];
|
||||
end;
|
||||
|
||||
burning_neighbor(i, j:INT):BOOL is
|
||||
loop x ::= (-1).upto!(1);
|
||||
loop y ::= (-1).upto!(1);
|
||||
if x /= y then
|
||||
if get(i+x, j+y) = burning then return true; end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
return false;
|
||||
end;
|
||||
|
||||
evolve is
|
||||
bp ::= 0;
|
||||
loop i ::= 0.upto!(width-1);
|
||||
loop j ::= 0.upto!(height-1);
|
||||
case get(i, j)
|
||||
when burning then set(i, j, empty); bp := bp + 1;
|
||||
when empty then
|
||||
if rnd.uniform > prob_p.fltd then
|
||||
set(i, j, empty);
|
||||
else
|
||||
set(i, j, tree);
|
||||
end;
|
||||
when tree then
|
||||
if burning_neighbor(i, j) then
|
||||
set(i, j, burning);
|
||||
else
|
||||
if rnd.uniform > prob_f.fltd then
|
||||
set(i, j, tree);
|
||||
else
|
||||
set(i, j, burning);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
#ERR + "corrupted field\n";
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
generation := generation + 1;
|
||||
if verbose then
|
||||
if bp > 0 then
|
||||
#ERR + #FMT("Burning at gen %d: %d\n", generation-1, bp);
|
||||
end;
|
||||
end;
|
||||
swapu := swapu.bxor(1);
|
||||
end;
|
||||
|
||||
str:STR is
|
||||
s ::= "";
|
||||
loop j ::= 0.upto!(height -1);
|
||||
loop i ::= 0.upto!(width -1);
|
||||
case get(i, j)
|
||||
when empty then s := s + ".";
|
||||
when tree then s := s + "Y";
|
||||
when burning then s := s + "*";
|
||||
end;
|
||||
end;
|
||||
s := s + "\n";
|
||||
end;
|
||||
s := s + "\n";
|
||||
return s;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
class MAIN is
|
||||
|
||||
main is
|
||||
forestfire ::= #FORESTFIRE(74, 40);
|
||||
-- #FORESTFIRE(74, 40, true) to have some extra info
|
||||
-- (redirecting stderr to a file is a good idea!)
|
||||
|
||||
#OUT + forestfire.str;
|
||||
-- evolve 1000 times
|
||||
loop i ::= 1000.times!;
|
||||
forestfire.evolve;
|
||||
-- ANSI clear screen sequence
|
||||
#OUT + 0x1b.char + "[H" + 0x1b.char + "[2J";
|
||||
#OUT + forestfire.str;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
Loading…
Add table
Add a link
Reference in a new issue