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; }