# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define UNBURNT 0
# define SMOLDERING 1
# define BURNING 2
# define BURNT 3
# define true 1
# define false 0
typedef int boolean;
int main ( );
boolean fire_spreads ( double prob_spread ) ;
int **forest_allocate ( int forest_size );
void forest_burns ( int forest_size, int **forest, double prob_spread );
void forest_delete ( int forest_size, int **forest );
void forest_initialize ( int forest_size, int **forest );
boolean forest_is_burning ( int forest_size, int **forest );
void forest_print ( int forest_size, int **forest, int i_ignite, int j_ignite );
double get_percent_burned ( int forest_size, int **forest );
int seed_by_time ( int offset );
void timestamp ( );
void tree_ignite ( int forest_size, int **forest, int i_ignite,
int j_ignite );
/******************************************************************************/
int main ( )
/******************************************************************************/
/*
Purpose:
MAIN is the main program for fire_simulation.
Modified:
30 June 2013.
*/
{
int **forest;
int forest_size = 20;
int i_ignite;
int j_ignite;
int offset;
double percent_burned = 0.0;
double prob_spread = 0.5;
int seed;
double u;
timestamp ( );
printf ( "\n" );
printf ( "fire_simulation\n" );
printf ( " C version\n" );
printf ( " A probabilistic simulation of a forest fire.\n" );
printf ( " The probability of tree-to-tree spread is %g\n", prob_spread );
/*
Initialize the random number generator.
*/
offset = 0;
seed = seed_by_time ( offset );
printf ( " The random number generator is seeded by %d.\n", seed );
srand ( seed );
/*
Create the forest.
*/
forest = forest_allocate ( forest_size );
/*
Initialize the values in the forest.
*/
forest_initialize ( forest_size, forest );
/*
Choose a tree at random where the fire will start.
*/
u = ( double ) rand ( ) / ( double ) RAND_MAX;
i_ignite = ( int ) ( ( double ) forest_size * u );
u = ( double ) rand ( ) / ( double ) RAND_MAX;
j_ignite = ( int ) ( ( double ) forest_size * u );
tree_ignite ( forest_size, forest, i_ignite, j_ignite );
printf ( "\n" );
printf ( " Fire starts at tree[%d][%d].\n", i_ignite, j_ignite );
/*
Let time run until nothing is burning any more.
*/
while ( forest_is_burning ( forest_size, forest ) )
{
forest_burns ( forest_size, forest, prob_spread );
}
/*
Display the final forest state.
*/
forest_print ( forest_size, forest, i_ignite, j_ignite );
/*
Report the percentage of forest burned.
*/
percent_burned = get_percent_burned ( forest_size, forest );
printf ( "\n" );
printf ( " Percentage of forest burned = %lf\n", percent_burned );
/*
Free memory.
*/
forest_delete ( forest_size, forest );
/*
Terminate.
*/
printf ( "\n" );
printf ( "fire_simulation:\n" );
printf ( " Normal end of execution.\n" );
printf ( "\n" );
timestamp ( );
return 0;
}
/******************************************************************************/
boolean fire_spreads ( double prob_spread )
/******************************************************************************/
/*
Purpose:
FIRE_SPREADS determines whether the fire spreads.
Modified:
30 June 2013
Parameters:
Input, double PROB_SPREAD, the probability of spreading.
Output, boolean FIRE_SPREADS, is TRUE if the fire spreads.
*/
{
double u;
boolean value;
u = ( double ) rand ( ) / ( double ) RAND_MAX;
if ( u < prob_spread )
{
value = true;
}
else
{
value = false;
}
return value;
}
/******************************************************************************/
int **forest_allocate ( int forest_size )
/******************************************************************************/
/*
Purpose:
FOREST_ALLOCATE allocates memory for a forest of the given size.
Modified:
30 June 2013
Parameters:
Input, int FOREST_SIZE, the linear dimension of the forest.
Output, int **FOREST_ALLOCATE, a pointer to the FOREST_SIZE x FOREST_SIZE
forest.
*/
{
int **forest;
int i;
forest = ( int ** ) malloc ( sizeof ( int* ) * forest_size );
for ( i = 0; i < forest_size; i++ )
{
forest[i] = ( int * ) malloc ( sizeof ( int ) * forest_size );
}
return forest;
}
/******************************************************************************/
void forest_burns ( int forest_size, int **forest, double prob_spread )
/******************************************************************************/
/*
Purpose:
FOREST_BURNS models a single time step of the burning forest.
Modified:
30 June 2013
Parameters:
Input, int FOREST_SIZE, the linear dimension of the forest.
Input, int **FOREST, a pointer to the FOREST_SIZE x FOREST_SIZE
forest.
Input, double PROB_SPREAD, the probability that the fire will spread
from a burning tree to an unburnt one.
*/
{
int i;
int j;
/*
Burning trees burn down;
Smoldering trees ignite;
*/
for ( i = 0; i < forest_size; i++ )
{
for ( j = 0; j < forest_size; j++ )
{
if ( forest[i][j] == BURNING )
{
forest[i][j] = BURNT;
}
else if ( forest[i][j] == SMOLDERING )
{
forest[i][j] = BURNING;
}
}
}
/*
Unburnt trees might catch fire.
*/
for ( i = 0; i < forest_size; i++ )
{
for ( j = 0; j < forest_size; j++ )
{
if ( forest[i][j] == BURNING)
{
/*
North.
*/
if ( i != 0 )
{
if ( fire_spreads ( prob_spread ) && forest[i-1][j] == UNBURNT )
{
forest[i-1][j] = SMOLDERING;
}
}
/*
South.
*/
if ( i != forest_size - 1 )
{
if ( fire_spreads ( prob_spread ) && forest[i+1][j] == UNBURNT )
{
forest[i+1][j] = SMOLDERING;
}
}
/*
West.
*/
if ( j != 0 )
{
if ( fire_spreads ( prob_spread ) && forest[i][j-1] == UNBURNT )
{
forest[i][j-1] = SMOLDERING;
}
}
/*
East.
*/
if ( j != forest_size - 1 )
{
if ( fire_spreads ( prob_spread ) && forest[i][j+1] == UNBURNT )
{
forest[i][j+1] = SMOLDERING;
}
}
}
}
}
return;
}
/******************************************************************************/
void forest_delete ( int forest_size, int **forest )
/******************************************************************************/
/*
Purpose:
FOREST_DELETE deletes the memory previously allocated for a forest.
Modified:
30 June 2013
Parameters:
Input, int FOREST_SIZE, the linear dimension of the forest.
Input, int **FOREST, a pointer to the FOREST_SIZE x FOREST_SIZE
forest.
*/
{
int i;
for ( i = 0; i < forest_size; i++ )
{
free ( forest[i] );
}
free ( forest );
return;
}
/******************************************************************************/
void forest_initialize ( int forest_size, int ** forest )
/******************************************************************************/
/*
Purpose:
FOREST_INITIALIZE initializes the forest values.
Modified:
30 June 2013
Parameters:
Input, int FOREST_SIZE, the linear dimension of the forest.
Input, int **FOREST, a pointer to the FOREST_SIZE x FOREST_SIZE
forest. The entries in the forest have been initialized to "UNBURNT".
*/
{
int i;
int j;
for ( i = 0; i < forest_size; i++ )
{
for ( j = 0; j < forest_size; j++ )
{
forest[i][j] = UNBURNT;
}
}
return;
}
/******************************************************************************/
boolean forest_is_burning ( int forest_size, int **forest )
/******************************************************************************/
/*
Purpose:
FOREST_IS_BURNING reports whether any trees in the forest are burning.
Modified:
30 June