How to resolve the algorithm Forest fire step by step in the D programming language

Published on 12 May 2024 09:40 PM
#D

How to resolve the algorithm Forest fire step by step in the D programming language

Table of Contents

Problem Statement

Implement the Drossel and Schwabl definition of the forest-fire model.

It is basically a 2D   cellular automaton   where each cell can be in three distinct states (empty, tree and burning) and evolves according to the following rules (as given by Wikipedia) Neighborhood is the   Moore neighborhood;   boundary conditions are so that on the boundary the cells are always empty ("fixed" boundary condition). At the beginning, populate the lattice with empty and tree cells according to a specific probability (e.g. a cell has the probability 0.5 to be a tree). Then, let the system evolve. Task's requirements do not include graphical display or the ability to change parameters (probabilities   p   and   f )   through a graphical or command line interface.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Forest fire step by step in the D programming language

Source code in the d programming language

import std.stdio, std.random, std.string, std.algorithm;

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 World = Cell[][];

bool hasBurningNeighbours(in World world, in ulong r, in ulong c)
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) /*nothrow*/ @safe /*@nogc*/ {
    foreach (r, row; world)
        foreach (c, elem; row)
            final switch (elem) with (Cell) {
                case empty:
                    nextWorld[r][c]= (uniform01 < cProb) ? tree : empty;
                    break;

                case tree:
                    if (world.hasBurningNeighbours(r, c))
                        nextWorld[r][c] = fire;
                    else
                        nextWorld[r][c] = (uniform01 < fProb) ? fire : tree;
                    break;

                case fire:
                    nextWorld[r][c] = empty;
                    break;
            }
}

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 (immutable i; 0 .. 4) {
        nextState(world, nextWorld);
        writefln("%(%(%c%)\n%)\n", nextWorld);
        world.swap(nextWorld);
    }
}


import std.stdio, std.random, std.algorithm, std.typetuple,
       simpledisplay;

enum double TREE_PROB = 0.55; // Original tree probability.
enum double F_PROB =    0.01; // Auto combustion probability.
enum double P_PROB =    0.01; // Tree creation probability.
enum worldSide = 600;

enum Cell : ubyte { empty, tree, burning }
alias World = Cell[worldSide][];

immutable white = Color(255, 255, 255),
          red = Color(255, 0, 0),
          green = Color(0, 255, 0);

void nextState(ref World world, ref World nextWorld,
               ref Xorshift rnd, Image img) {
  immutable nr = world.length;
  immutable nc = world[0].length;
  foreach (immutable r, const row; world)
    foreach (immutable c, immutable elem; row)
      START: final switch (elem) with (Cell) {
        case empty:
          img.putPixel(c, r, white);
          nextWorld[r][c] = rnd.uniform01 < P_PROB ? tree : empty;
          break;

        case tree:
          img.putPixel(c, r, green);

          foreach (immutable rowShift; TypeTuple!(-1, 0, 1))
            foreach (immutable colShift; TypeTuple!(-1, 0, 1))
              if ((r + rowShift) >= 0 && (r + rowShift) < nr &&
                  (c + colShift) >= 0 && (c + colShift) < nc &&
                  world[r + rowShift][c + colShift] == Cell.burning) {
                nextWorld[r][c] = Cell.burning;
                break START;
              }

          nextWorld[r][c]= rnd.uniform01 < F_PROB ? burning : tree;
          break;

        case burning:
          img.putPixel(c, r, red);
          nextWorld[r][c] = empty;
          break;
      }

  swap(world, nextWorld);
}

void main() {
  auto rnd = Xorshift(1);
  auto world = new World(worldSide);
  foreach (ref row; world)
    foreach (ref el; row)
      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");
  auto img = new Image(w.width, w.height);

  w.eventLoop(1, {
    auto painter = w.draw;
    nextState(world, nextWorld, rnd, img);
    painter.drawImage(Point(0, 0), img);
  });
}


  

You may also check:How to resolve the algorithm Binary digits step by step in the ARM Assembly programming language
You may also check:How to resolve the algorithm Probabilistic choice step by step in the E programming language
You may also check:How to resolve the algorithm Handle a signal step by step in the Julia programming language
You may also check:How to resolve the algorithm Copy stdin to stdout step by step in the Seed7 programming language
You may also check:How to resolve the algorithm Hello world/Newbie step by step in the COBOL programming language