Saturday, February 20, 2010

Pseudo-Life

Nothing much to report here. I worked a bit on the cellular automata program; now it generates screen after screen of random patterns. This is not the final goal, but it is a step in the right direction. A game of pseudo-life, instead of Conway's life. When I first compiled and ran this bit of code, I saw something strange. In just a few moments the screen would fill up with green blocks. It took me a little while to figure out what the problem was. D'oh! I neglected to clear the cells vector, which would keep on magically growing. This gives you a minty green screen o' blocks.

I kept pouring over the SDL sections of the code. There was no problem with SDL code, just the plain vanilla C++ code. Happy cells.clear(); to all.

I went through the Python version of this program and figured out what functions would have to be ported to get a bare bones working version of the program. It looks like just a few:
  • countNeighbors
  • cellNextgen
  • updateCAMatrix
  • a 2D vector to hold the ruleset information.
No I haven't posted them yet -- they're still vaporware. They will all be showing up as I go along. I actually coded them using pencil and paper, but to date I have a poor track record of writing down working code with pencil and paper. I will code and debug them, then post.

One thing I learned after writing the paper and pencil code is that using c++ vector <bool> is probably not a good idea. Too bad, it looks so good on paper.

#include <iostream>
#include <vector>
#include <cstdlib>
#include "SDL/SDL.h"

using namespace std;

// Globals
const int XRES = 1024;
const int YRES = 768;
const int BLOCKSIZE = 4;
const int DELTA_T = 250;
const int FCOLOR = 0x0000FF00;
const int BCOLOR = 0x00000000;
const int ROWS = YRES / BLOCKSIZE;
const int COLS = XRES / BLOCKSIZE;

int randomStart(vector & cells, vector > & world) {
        srand(time(NULL));

        SDL_Rect p;
        int pct;

        for (int row = 0; row < ROWS; ++row)
        {
            for (int col = 0; col < COLS; ++col)
            {
                pct  = rand() % 1000;
                if (pct < 200)
                {
                    p.x = col * BLOCKSIZE;
                    p.y = row * BLOCKSIZE;
                    p.w = BLOCKSIZE;
                    p.h = BLOCKSIZE;
                    cells.push_back(p);
                    world[row][col] = 1;
                }
                else
                    world[row][col] = 0;
            }
        }
    return 0;
}

int main() {
    vector cells;
    vector< vector > world(ROWS, vector(COLS,0));

    // initialize SDL
    SDL_Init(SDL_INIT_VIDEO);

    // populate the world
    //randomStart(cells, world);   // pass by reference

    // set the title bar
    SDL_WM_SetCaption("Cellular Automata", "Cellular Automata");

    // create window
    SDL_Surface* screen = SDL_SetVideoMode(XRES, YRES, 0, SDL_DOUBLEBUF);

    // Create background and block
    SDL_Surface* bg = SDL_CreateRGBSurface(SDL_SWSURFACE,XRES, YRES, 32, 0, 0, 0, 0);
    SDL_FillRect(bg, NULL, BCOLOR);

    // Display the bank screen
    SDL_BlitSurface(bg, NULL, screen, NULL);
    SDL_Flip(screen);

    // creak the block image for a live cell
    SDL_Surface* block = SDL_CreateRGBSurface(SDL_SWSURFACE, BLOCKSIZE - 2, BLOCKSIZE - 2, 32, 0, 0, 0, 0);
    SDL_FillRect(block, NULL, FCOLOR);

    SDL_Event event;
    bool gameover = false;

    // message pump
    while (!gameover)
    {
        // look for an event
        if (SDL_PollEvent(&event)) {
            // an event was found
            switch (event.type) {
                // close button clicked
                case SDL_QUIT:
                    gameover = true;
                    break;

                // handle the keyboard
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym) {
                        case SDLK_ESCAPE:
                        case SDLK_q:
                            gameover = true;
                            break;
                    }
                    break;

            }
        }

        randomStart(cells, world);

        // draw the background
        SDL_BlitSurface(bg, NULL, screen, NULL);

        // blit the blocks
        for (unsigned int i = 0; i < cells.size(); ++i)
            SDL_BlitSurface(block, NULL, screen, &cells[i]);

        // empty the vector of cells
        cells.clear();

        // update screen
        SDL_Flip(screen);

    }

    // free the background surface
    SDL_FreeSurface(bg);

    // cleanup SDL
    SDL_Quit();

    return 0;
}

No comments:

Post a Comment