Forest fire: Difference between revisions

Content deleted Content added
SqrtNegInf (talk | contribs)
m →‎{{header|Perl}}: future-proof for 5.36, use new bitwise string operators
Torbjoern (talk | contribs)
add Evaldraw (.kc) solution
Line 4,292: Line 4,292:
{burning,{5,5}}]
{burning,{5,5}}]
</pre>
</pre>


=={{header|Evaldraw}}==

[[File:Evaldrawforest.gif|right|thumb|Forest fire animation]]

Creates a 256x256 pixel forest, try adjusting the probability for ignite, spread, sprout and max neighbors.

<syntaxhighlight lang="c">
enum{XSIZ=255, YSIZ=XSIZ} // size of forest
enum{EMPTY=0, TREE=1, BURN=2} // possible states of a cell
static prob_ignite = .000001; // very rare, but remember we have many trees.
static prob_spread = .25; // Fire spread speed/probability if neighbor on fire
static prob_sprout = 0.25; // probability of new tree to sprout
static MAX_NEIGHBORS = 6; // tree refuses to sprout if overcrowded
static forest[2][YSIZ][XSIZ]; // state of pixel
static fuel[2][YSIZ][XSIZ]; // stores fuel (wood) 0-255
static heat[2][YSIZ][XSIZ]; // tree refuses to spout if heat!=0, also, sets draw color.
static arr_numburn[YSIZ][XSIZ]; // number of burning trees for this cell
static arr_numtree[YSIZ][XSIZ]; // number of neighbor trees for this cell
static xoff[8] = {-1,+0,+1,-1,/*NA*/1,-1,+0,+1}; // offsets to find 8-connected neighbors
static yoff[8] = {-1,-1,-1,+0,/*NA*/0,+1,+1,+1};
() { // Main in evaldraw scripts is a unnamed function.
static otim;
tim = klock(); // Time since program start in seconds.
dt=tim-otim; // Deltatime. 1/dt is FPS. 0 in first frame.
otim=tim; // store old time for next dt.
simulate(); // simulate and draw are coupled, since draw also ping-pongs state.
draw();
setcol(0); fillrect(0,YSIZ,XSIZ,15);
setcol(0xffffff); moveto(0,YSIZ); printf("%4.0ffps generation %5.0f", 1 /dt, numframes);
if (bstatus>0) setFire(mousx,mousy);
}// end main

draw() {
for(y=0; y<YSIZ; y++)
for(x=0; x<XSIZ; x++)
{
cell = forest[1][y][x];
if (cell == EMPTY) setcol(0);
else if(cell==BURN) setcol(511-.25*fuel[0][y][x],255-3*heat[0][y][x],33);
else if(cell==TREE) setcol(0,64+fuel[0][y][x],0);
setpix(x,y);
// Transfer next simulation state into current ready for next frame
forest[0][y][x] = forest[1][y][x];
heat[0][y][x] = heat[1][y][x];
fuel[0][y][x] = fuel[1][y][x];
// Count neighbors burning and not
numburn = 0; numtree = 0;
for(n=0; n<8; n++) {
ypos=y+yoff[n];
xpos=x+xoff[n];
if (xpos<0 || xpos > XSIZ-1)continue;
if (ypos<0 || ypos > YSIZ-1)continue;
cell = forest[1][ypos][xpos];
if (cell==BURN) numburn++;
else if (cell==TREE) numtree++;
}
arr_numburn[y][x] = numburn;
arr_numtree[y][x] = numtree;
}
}

fillrect(x0,y0,w,h) {
x0=int(x0); y0=int(y0); w=int(w) + 1; h=int(h);
for(y=y0;y<=y0+h;y++) { moveto(x0,y); lineto(x0+w,y); }
}

simulate() {
for(y=0; y<YSIZ; y++)
for(x=0; x<XSIZ; x++) {
cell = forest[0][y][x];
cellfuel = fuel[0][y][x];
celltemp = heat[0][y][x];
rand=rnd;
numburn = arr_numburn[y][x];
numtree = arr_numtree[y][x];
if (cell == BURN) {
if (cellfuel <= 0) {
forest[1][y][x] = EMPTY;
}
else {
fuel[1][y][x] = cellfuel - 1;
heat[1][y][x] = celltemp + 1;
}
}
else if (cell == TREE) {
if (numburn == 0 && rand < prob_ignite) setFire(x,y);
else if (numburn > 0 && rand < prob_spread) setFire(x,y);
else if(cellfuel < 255) fuel[1][y][x] = cellfuel + 1;
}
else if (cell == EMPTY) {
if ( celltemp > 0 ) heat[1][y][x] = celltemp - 1;
else if (numburn==0 && rand < prob_sprout && numtree <= MAX_NEIGHBORS) setTree(x,y);
}
}
} // end sim

setFire(x,y) {
forest[1][y][x] = BURN;
}

setTree(x,y) {
forest[1][y][x] = TREE;
}
</syntaxhighlight>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==