new files
This commit is contained in:
parent
3af7344581
commit
86c034bb8b
1364 changed files with 21352 additions and 0 deletions
248
Task/Forest-fire/C/forest-fire-1.c
Normal file
248
Task/Forest-fire/C/forest-fire-1.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
// defaults
|
||||
#define PROB_TREE 0.55
|
||||
#define PROB_F 0.00001
|
||||
#define PROB_P 0.001
|
||||
|
||||
#define TIMERFREQ 100
|
||||
|
||||
#ifndef WIDTH
|
||||
# define WIDTH 640
|
||||
#endif
|
||||
#ifndef HEIGHT
|
||||
# define HEIGHT 480
|
||||
#endif
|
||||
#ifndef BPP
|
||||
# define BPP 32
|
||||
#endif
|
||||
|
||||
#if BPP != 32
|
||||
#warning This program could not work with BPP different from 32
|
||||
#endif
|
||||
|
||||
uint8_t *field[2], swapu;
|
||||
double prob_f = PROB_F, prob_p = PROB_P, prob_tree = PROB_TREE;
|
||||
|
||||
enum cell_state {
|
||||
VOID, TREE, BURNING
|
||||
};
|
||||
|
||||
// simplistic random func to give [0, 1)
|
||||
double prand()
|
||||
{
|
||||
return (double)rand() / (RAND_MAX + 1.0);
|
||||
}
|
||||
|
||||
// initialize the field
|
||||
void init_field(void)
|
||||
{
|
||||
int i, j;
|
||||
swapu = 0;
|
||||
for(i = 0; i < WIDTH; i++)
|
||||
{
|
||||
for(j = 0; j < HEIGHT; j++)
|
||||
{
|
||||
*(field[0] + j*WIDTH + i) = prand() > prob_tree ? VOID : TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the "core" of the task: the "forest-fire CA"
|
||||
bool burning_neighbor(int, int);
|
||||
pthread_mutex_t synclock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static uint32_t simulate(uint32_t iv, void *p)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
Since this is called by SDL, "likely"(*) in a separated
|
||||
thread, we try to avoid corrupted updating of the display
|
||||
(done by the show() func): show needs the "right" swapu
|
||||
i.e. the right complete field. (*) what if it is not so?
|
||||
The following is an attempt to avoid unpleasant updates.
|
||||
*/
|
||||
pthread_mutex_lock(&synclock);
|
||||
|
||||
for(i = 0; i < WIDTH; i++) {
|
||||
for(j = 0; j < HEIGHT; j++) {
|
||||
enum cell_state s = *(field[swapu] + j*WIDTH + i);
|
||||
switch(s)
|
||||
{
|
||||
case BURNING:
|
||||
*(field[swapu^1] + j*WIDTH + i) = VOID;
|
||||
break;
|
||||
case VOID:
|
||||
*(field[swapu^1] + j*WIDTH + i) = prand() > prob_p ? VOID : TREE;
|
||||
break;
|
||||
case TREE:
|
||||
if (burning_neighbor(i, j))
|
||||
*(field[swapu^1] + j*WIDTH + i) = BURNING;
|
||||
else
|
||||
*(field[swapu^1] + j*WIDTH + i) = prand() > prob_f ? TREE : BURNING;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "corrupted field\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
swapu ^= 1;
|
||||
pthread_mutex_unlock(&synclock);
|
||||
return iv;
|
||||
}
|
||||
|
||||
// the field is a "part" of an infinite "void" region
|
||||
#define NB(I,J) (((I)<WIDTH)&&((I)>=0)&&((J)<HEIGHT)&&((J)>=0) \
|
||||
? (*(field[swapu] + (J)*WIDTH + (I)) == BURNING) : false)
|
||||
bool burning_neighbor(int i, int j)
|
||||
{
|
||||
return NB(i-1,j-1) || NB(i-1, j) || NB(i-1, j+1) ||
|
||||
NB(i, j-1) || NB(i, j+1) ||
|
||||
NB(i+1, j-1) || NB(i+1, j) || NB(i+1, j+1);
|
||||
}
|
||||
|
||||
|
||||
// "map" the field into gfx mem
|
||||
// burning trees are red
|
||||
// trees are green
|
||||
// "voids" are black;
|
||||
void show(SDL_Surface *s)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t *pixels = (uint8_t *)s->pixels;
|
||||
uint32_t color;
|
||||
SDL_PixelFormat *f = s->format;
|
||||
|
||||
pthread_mutex_lock(&synclock);
|
||||
for(i = 0; i < WIDTH; i++) {
|
||||
for(j = 0; j < HEIGHT; j++) {
|
||||
switch(*(field[swapu] + j*WIDTH + i)) {
|
||||
case VOID:
|
||||
color = SDL_MapRGBA(f, 0,0,0,255);
|
||||
break;
|
||||
case TREE:
|
||||
color = SDL_MapRGBA(f, 0,255,0,255);
|
||||
break;
|
||||
case BURNING:
|
||||
color = SDL_MapRGBA(f, 255,0,0,255);
|
||||
break;
|
||||
}
|
||||
*(uint32_t*)(pixels + j*s->pitch + i*(BPP>>3)) = color;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&synclock);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SDL_Surface *scr = NULL;
|
||||
SDL_Event event[1];
|
||||
bool quit = false, running = false;
|
||||
SDL_TimerID tid;
|
||||
|
||||
// add variability to the simulation
|
||||
srand(time(NULL));
|
||||
|
||||
// we can change prob_f and prob_p
|
||||
// prob_f prob of spontaneous ignition
|
||||
// prob_p prob of birth of a tree
|
||||
double *p;
|
||||
for(argv++, argc--; argc > 0; argc--, argv++)
|
||||
{
|
||||
if ( strcmp(*argv, "prob_f") == 0 && argc > 1 )
|
||||
{
|
||||
p = &prob_f;
|
||||
} else if ( strcmp(*argv, "prob_p") == 0 && argc > 1 ) {
|
||||
p = &prob_p;
|
||||
} else if ( strcmp(*argv, "prob_tree") == 0 && argc > 1 ) {
|
||||
p = &prob_tree;
|
||||
} else continue;
|
||||
|
||||
|
||||
argv++; argc--;
|
||||
char *s = NULL;
|
||||
double t = strtod(*argv, &s);
|
||||
if (s != *argv) *p = t;
|
||||
}
|
||||
|
||||
printf("prob_f %lf\nprob_p %lf\nratio %lf\nprob_tree %lf\n",
|
||||
prob_f, prob_p, prob_p/prob_f,
|
||||
prob_tree);
|
||||
|
||||
if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0 ) return EXIT_FAILURE;
|
||||
atexit(SDL_Quit);
|
||||
|
||||
field[0] = malloc(WIDTH*HEIGHT);
|
||||
if (field[0] == NULL) exit(EXIT_FAILURE);
|
||||
field[1] = malloc(WIDTH*HEIGHT);
|
||||
if (field[1] == NULL) { free(field[0]); exit(EXIT_FAILURE); }
|
||||
|
||||
scr = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDL_HWSURFACE|SDL_DOUBLEBUF);
|
||||
if (scr == NULL) {
|
||||
fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
|
||||
free(field[0]); free(field[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
init_field();
|
||||
|
||||
tid = SDL_AddTimer(TIMERFREQ, simulate, NULL); // suppose success
|
||||
running = true;
|
||||
|
||||
event->type = SDL_VIDEOEXPOSE;
|
||||
SDL_PushEvent(event);
|
||||
|
||||
while(SDL_WaitEvent(event) && !quit)
|
||||
{
|
||||
switch(event->type)
|
||||
{
|
||||
case SDL_VIDEOEXPOSE:
|
||||
while(SDL_LockSurface(scr) != 0) SDL_Delay(1);
|
||||
show(scr);
|
||||
SDL_UnlockSurface(scr);
|
||||
SDL_Flip(scr);
|
||||
event->type = SDL_VIDEOEXPOSE;
|
||||
SDL_PushEvent(event);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
switch(event->key.keysym.sym)
|
||||
{
|
||||
case SDLK_q:
|
||||
quit = true;
|
||||
break;
|
||||
case SDLK_p:
|
||||
if (running)
|
||||
{
|
||||
running = false;
|
||||
pthread_mutex_lock(&synclock);
|
||||
SDL_RemoveTimer(tid); // ignore failure...
|
||||
pthread_mutex_unlock(&synclock);
|
||||
} else {
|
||||
running = true;
|
||||
tid = SDL_AddTimer(TIMERFREQ, simulate, NULL);
|
||||
// suppose success...
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT:
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (running) {
|
||||
pthread_mutex_lock(&synclock);
|
||||
SDL_RemoveTimer(tid);
|
||||
pthread_mutex_unlock(&synclock);
|
||||
}
|
||||
free(field[0]); free(field[1]);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
65
Task/Forest-fire/C/forest-fire-2.c
Normal file
65
Task/Forest-fire/C/forest-fire-2.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum { empty = 0, tree = 1, fire = 2 };
|
||||
const char *disp[] = {" ", "\033[32m/\\\033[m", "\033[07;31m/\\\033[m"};
|
||||
double tree_prob = 0.01, burn_prob = 0.0001;
|
||||
|
||||
#define for_x for (int x = 0; x < w; x++)
|
||||
#define for_y for (int y = 0; y < h; y++)
|
||||
#define for_yx for_y for_x
|
||||
#define chance(x) (rand() < RAND_MAX * x)
|
||||
void evolve(int w, int h)
|
||||
{
|
||||
unsigned univ[h][w], new[h][w];
|
||||
for_yx new[y][x] = univ[y][x] = chance(tree_prob) ? tree : empty;
|
||||
|
||||
show: printf("\033[H");
|
||||
for_y {
|
||||
for_x printf(disp[univ[y][x]]);
|
||||
printf("\033[E");
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
for_yx {
|
||||
switch (univ[y][x]) {
|
||||
case fire: new[y][x] = empty;
|
||||
break;
|
||||
case empty: if (chance(tree_prob)) new[y][x] = tree;
|
||||
break;
|
||||
default:
|
||||
for (int y1 = y - 1; y1 <= y + 1; y1++) {
|
||||
if (y1 < 0 || y1 >= h) continue;
|
||||
for (int x1 = x - 1; x1 <= x + 1; x1++) {
|
||||
if (x1 < 0 || x1 >= w) continue;
|
||||
if (univ[y1][x1] != fire) continue;
|
||||
|
||||
new[y][x] = fire;
|
||||
goto burn;
|
||||
}
|
||||
}
|
||||
|
||||
burn:
|
||||
if (new[y][x] == tree && chance(burn_prob))
|
||||
new[y][x] = fire;
|
||||
}
|
||||
}
|
||||
|
||||
for_yx { univ[y][x] = new[y][x]; }
|
||||
//usleep(100000);
|
||||
goto show;
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
//srand(time(0));
|
||||
int w = 0, h = 0;
|
||||
|
||||
if (c > 1) w = atoi(v[1]);
|
||||
if (c > 2) h = atoi(v[2]);
|
||||
if (w <= 0) w = 30;
|
||||
if (h <= 0) h = 30;
|
||||
|
||||
evolve(w, h);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue