Pożar lasu
-- Sebastian Pawlak, 2003.
Pożar lasu został zaimplementowany z wykorzystaniem biblioteki
graficznej SDL w Microsoft Visual Studio. Lewym przyciskiem myszy
wznieca się pożar. Prawym przyciskiem myszy tworzy się ziemną przeszkodę
dla ognia. Las odrasta.
Kod źródłowy pliku "las.cpp":
/******************************
* POZAR LASU *
* Sebastian Pawlak *
******************************/
#include <math.h>
#include <stdlib.h>
#include "..\SDL-1.2.5\include\sdl.h"
#include "..\SDL-1.2.5\include\SDL_endian.h"
void Slock(SDL_Surface *screen)
{
if (SDL_MUSTLOCK(screen) && SDL_LockSurface(screen) < 0)
return;
}
void Sulock(SDL_Surface *screen)
{
if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
}
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
if (SDL_MUSTLOCK(screen) && SDL_LockSurface(screen) < 0)
return;
switch (screen->format->BytesPerPixel) {
case 1: { /* 8-bpp */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y * screen->pitch + x;
*bufp = color;
}
break;
case 2: { /* 15-bpp lub 16-bpp */
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y * screen->pitch / 2 + x;
*bufp = color;
}
break;
case 3: { /* powolony tryb 24-bpp */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y * screen->pitch + x * 3;
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else {
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: { /* 32-bpp */
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y * screen->pitch / 4 + x;
*bufp = color;
}
break;
}
if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
}
enum {
MAXX = 512, /* rozmiar planszy */
MAXY = 512
};
/* zawartosc pojedynczej komorki */
typedef struct _komorka {
char stan;
int czas;
int miliczas;
} komorka;
komorka plansza[MAXX][MAXY]; /* plansza aktualna */
komorka plansza2[MAXX][MAXY]; /* plansza po przeksztalceniach */
int main(int argc, char* argv[])
{
/* losowe tworzenie planszy poczatkowej */
for (int x = 0; x < MAXX; x++)
for (int y = 0; y < MAXY; y++) {
int w = rand() % 9;
plansza[x][y].miliczas = plansza2[x][y].miliczas = 0;
plansza[x][y].czas = plansza2[x][y].czas = 0;
if (w < 3)
plansza[x][y].stan = 'E', plansza[x][y].miliczas = rand() % 100;
else if (w == 4)
plansza[x][y].stan = 'G';
else if (w == 5)
plansza[x][y].stan = 'W';
else
plansza[x][y].stan = 'F';
plansza2[x][y].stan = plansza[x][y].stan;
}
/* inicjalizacja biblioteki SDL */
SDL_Init(SDL_INIT_VIDEO);
atexit ( SDL_Quit ) ;
SDL_Surface *pSurface = SDL_SetVideoMode(MAXX, MAXY, 0, SDL_ANYFORMAT);
SDL_Event event;
SDL_WM_SetCaption("Pożar lasu", NULL);
while (1) {
Slock(pSurface);
for (x = 1; x < MAXX - 1; x++)
for (int y = 1; y < MAXY - 1; y++) {
/* zmiana stanu automatu */
if (plansza[x][y].stan == 'I' && plansza[x][y].czas == 0)
plansza2[x][y].stan = 'E',
plansza2[x][y].czas = 0,
plansza2[x][y].miliczas = rand() % 100;
else if (plansza[x][y].stan == 'E' && plansza[x][y].czas == 1)
plansza2[x][y].stan = 'G',
plansza2[x][y].czas = 2;
else if (plansza[x][y].stan == 'G' && plansza[x][y].czas == 4)
plansza2[x][y].stan = 'W',
plansza2[x][y].czas = 5;
else if (plansza[x][y].stan == 'W' && plansza[x][y].czas == 49)
plansza2[x][y].stan = 'F',
plansza2[x][y].czas = 50;
/* wyswietlanie komorki na ekranie */
switch(plansza[x][y].stan) {
case 'I': DrawPixel(pSurface, x, y, 200 + plansza[x][y].czas * 3, 0, 0);
break;
case 'E': DrawPixel(pSurface, x, y, 166, 124, 82);
break;
case 'G': DrawPixel(pSurface, x, y, 0, 150 + plansza[x][y].czas * 25, 0);
break;
case 'W': DrawPixel(pSurface, x, y, 0, 200 + plansza[x][y].czas, 0);
break;
case 'F': DrawPixel(pSurface, x, y, 0, 255, 0);
break;
}
/* podpalanie lasu */
if (plansza[x][y].stan == 'I' && plansza[x][y].czas != 0) {
if (plansza[x][y].czas > 0 && plansza2[x][y].czas)
plansza2[x][y].czas--;
char t[] = "FWG";
int c[] = { 15, 3, 3 };
for (int i = 0; i < 3; i++) {
if (plansza[x-1][y].stan == t[i])
plansza2[x-1][y].stan = 'I',
plansza2[x-1][y].czas = c[i],
plansza2[x-1][y].miliczas = 0;
if (plansza[x][y-1].stan == t[i])
plansza2[x][y-1].stan = 'I',
plansza2[x][y-1].czas = c[i],
plansza2[x][y-1].miliczas = 0;
if (plansza[x][y+1].stan == t[i])
plansza2[x][y+1].stan = 'I',
plansza2[x][y+1].czas = c[i],
plansza2[x][y+1].miliczas = 0;
if (plansza[x+1][y].stan == t[i])
plansza2[x+1][y].stan = 'I',
plansza2[x+1][y].czas = c[i],
plansza2[x+1][y].miliczas = 0;
}
}
}
Sulock(pSurface);
SDL_Flip(pSurface);
for (x = 0; x < MAXX; x++)
for (int y = 0; y < MAXY; y++)
plansza[x][y].stan = plansza2[x][y].stan,
plansza[x][y].czas = plansza2[x][y].czas,
plansza[x][y].miliczas = plansza2[x][y].miliczas;
/* obsluga zdarzen */
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
exit(0);
if (event.type == SDL_MOUSEBUTTONDOWN)
if (event.button.button == SDL_BUTTON_LEFT) {
plansza[event.button.x][event.button.y].stan = 'I',
plansza[event.button.x][event.button.y].czas = 1;
} else if (event.button.x >= 3 && event.button.x <= MAXX - 4 &&
event.button.y >= 3 && event.button.y <= MAXY - 4)
for(int x = -3; x < 5; x++)
for(int y = -3; y < 5; y++)
plansza2[event.button.x+x][event.button.y+y].stan = 'E',
plansza2[event.button.x+x][event.button.y+y].czas = 0;
}
/* obsluga czasu */
for(int x = 0; x < MAXX; x++)
for(int y = 0; y < MAXY; y++)
if (plansza[x][y].stan != 'I') {
plansza2[x][y].miliczas++;
if(plansza[x][y].miliczas > 300)
plansza2[x][y].miliczas = 0, plansza2[x][y].czas++;
}
}
return 0;
}





