Game of Life

    -- Sebastian Pawlak, 2003.


Game of Life została zaimplementowana z wykorzystaniem biblioteki graficznej SDL w Microsoft Visual Studio.

Automat dwuwymiarowy synchroniczny.
Periodyczne warunku brzegowe.
Stany: 0-komórka martwa, 1-komórka żywa.
Sąsiedztwo Moora R=1.
Reguły:
- jeśli komórka=1 oraz ma dwóch lub trzech sąsiadów=1, to komórka=1,
- jeśli komórka=1 oraz ma wiecej niż trzech sąsiadów=1, to komórka=0,
- jeśli komórka=1 oraz ma mniej niż dwóch sąsiadów=1, to komórka=0,
- jeśli komórka=0 oraz ma dokładnie trzech sąsiadów=1, to komórka=1.


Kod źródłowy pliku "life.cpp":

/******************************
 *         GAME OF LIFE       *
 *       Sebastian Pawlak     *
 ******************************/

#include <math.h>
#include <stdlib.h>
#include <string.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
};


short int plansza[MAXX][MAXY];  /* plansza aktualna */
short int 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() % 4;
            if (w == 0)
                plansza2[x][y] = plansza[x][y] = 0;
            else
                plansza2[x][y] = plansza[x][y] = 1;
        }

    /* 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("Game of life", NULL);

    while (1) {

        Slock(pSurface);

        SDL_Rect rect = { 0, 0, MAXX, MAXY };
        SDL_FillRect(pSurface, &rect, SDL_MapRGB(pSurface->format, 255, 255, 255));

        for (x = 0; x < MAXX; x++)
            for (int y = 0; y < MAXY; y++) {

                /* zmiana stanu automatu */
                int w = 0;
                for (int xx = (x == 0 ? 0 : -1); xx <= (x == MAXX - 1 ? 0 : 1); xx++)
                    for(int yy = (y == 0 ? 0 : -1); yy <= (y == MAXY - 1 ? 0 : 1); yy++)
                        if (plansza[x + xx][y + yy] == 1)
                            w++;

                if (plansza[x][y] == 1)  /* nie liczymy srodka */
                    w--;

                if (plansza[x][y] == 1) {
                    if (w == 2 || w == 3)
                        plansza2[x][y] = 1;
                    else if (w < 2 || w > 3)
                        plansza2[x][y] = 0;
                } else if (w == 3)
                    plansza2[x][y] = 1;
 
                /* wyswietlanie komorki na ekranie */
                if (plansza[x][y] == 1)
                    DrawPixel(pSurface, x, y, 0, 0, 255);
            }

        Sulock(pSurface);
        SDL_Flip(pSurface);

        /* kopiowanie planszy wynikowej do planszy pierwotnej */
        for (x = 0; x < MAXX; x++)
            memcpy(&plansza[x][0], &plansza2[x][0], sizeof(plansza[0][0]) * MAXY);

        /* obsluga zdarzen */
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT)
                exit(0);

            if (event.type == SDL_MOUSEBUTTONDOWN)
                plansza[event.button.x][event.button.y] =
                    plansza2[event.button.x][event.button.y] = 1;
        }

    }

    return 0;
}
w3cw3c
automatyka przemysłowa