Created
June 16, 2011 15:54
-
-
Save neuro-sys/1029558 to your computer and use it in GitHub Desktop.
game of life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <math.h> | |
#include <time.h> | |
#include <ctype.h> | |
#include <SDL/SDL.h> | |
#include <SDL/SDL_gfxPrimitives.h> | |
#include "main.h" | |
#include "isometric.h" | |
#define SCREEN_W 400 | |
#define SCREEN_H 400 | |
#define CELL_SIZ 20 | |
#define CELL_COLOR 0xaaaaaa | |
#define W SCREEN_W / CELL_SIZ | |
#define H SCREEN_H / CELL_SIZ | |
//SDL_Surface *scr; | |
int cells[H][W]; | |
int cells2[H][W]; | |
int (*cellsPtr)[W] = cells; | |
int (*cells2Ptr)[W] = cells2; | |
int (*cellsTmp)[W]; | |
int life_speed = 100; | |
int done; | |
int start; | |
enum { NORMAL, ISOMETRIC }; | |
int view_mode = ISOMETRIC; | |
void handle_keys(SDL_Surface* scr) | |
{ | |
int x, y; | |
static int tile_x, tile_y; /* should be static to keep the old values when there are no events */ | |
SDL_Event event; | |
while (SDL_PollEvent(&event)) { | |
SDL_GetMouseState(&x, &y); | |
if (view_mode == NORMAL) { | |
tile_x = x / CELL_SIZ; | |
tile_y = y / CELL_SIZ; | |
} else if (view_mode == ISOMETRIC) { | |
get_tile_coords(x, y, &tile_x, &tile_y); | |
} | |
/* clip boundary violations */ | |
if (tile_x < 0 || tile_x > W || tile_y < 0 || tile_y > H) | |
return; | |
switch (event.type) { | |
case SDL_KEYDOWN: | |
if (event.key.keysym.sym == SDLK_ESCAPE) | |
exit(0); | |
else if (event.key.keysym.sym == SDLK_SPACE) | |
start = !start; | |
else if (event.key.keysym.sym == SDLK_n) | |
life(); | |
else if (event.key.keysym.sym == SDLK_r) | |
gen_random_organisms(10); | |
else if (event.key.keysym.sym == SDLK_1) | |
view_mode = NORMAL; | |
else if (event.key.keysym.sym == SDLK_2) | |
view_mode = ISOMETRIC; | |
break; | |
case SDL_MOUSEBUTTONDOWN: | |
cellsPtr[tile_y][tile_x] = !cellsPtr[tile_y][tile_x]; | |
break; | |
case SDL_QUIT: | |
exit(0); | |
} | |
} | |
/* hover display */ | |
if (SDL_MUSTLOCK(scr)) | |
SDL_LockSurface(scr); | |
if (view_mode == NORMAL) { | |
int x1 = tile_x * CELL_SIZ; | |
int y1 = tile_y * CELL_SIZ; | |
int x2 = x1 + CELL_SIZ; | |
int y2 = y1 + CELL_SIZ; | |
boxColor(scr, x1, y1, x2, y2, CELL_COLOR); | |
} | |
else if (view_mode == ISOMETRIC) | |
draw_hover(tile_x, tile_y); | |
if (SDL_MUSTLOCK(scr)) | |
SDL_UnlockSurface(scr); | |
} | |
void draw_cells(SDL_Surface *scr) | |
{ | |
int i, j; | |
for (i = 0; i < H; i++) { | |
for (j = 0; j < W; j++) { | |
if (cellsPtr[i][j]) { | |
if (SDL_MUSTLOCK(scr)) | |
SDL_LockSurface(scr); | |
if (view_mode == NORMAL) { | |
int x1 = j * CELL_SIZ; | |
int y1 = i * CELL_SIZ; | |
int x2 = x1 + CELL_SIZ; | |
int y2 = y1 + CELL_SIZ; | |
boxColor(scr, x1, y1, x2, y2, CELL_COLOR); | |
} | |
else if (view_mode == ISOMETRIC) | |
draw_cube(i, j); | |
if (SDL_MUSTLOCK(scr)) | |
SDL_UnlockSurface(scr); | |
} | |
} | |
} | |
} | |
void life() | |
{ | |
int i, j; | |
for (i = 0; i < H; i++) | |
for (j = 0; j < W; j++) { | |
cells2Ptr[i][j] = 0; | |
int num_alive_adj = 0; | |
num_alive_adj += cellsPtr[i][j-1]; | |
num_alive_adj += cellsPtr[i-1][j-1]; | |
num_alive_adj += cellsPtr[i-1][j]; | |
num_alive_adj += cellsPtr[i-1][j+1]; | |
num_alive_adj += cellsPtr[i][j+1]; | |
num_alive_adj += cellsPtr[i+1][j+1]; | |
num_alive_adj += cellsPtr[i+1][j]; | |
num_alive_adj += cellsPtr[i+1][j-1]; | |
if (cellsPtr[i][j]) { | |
if (num_alive_adj == 2 || num_alive_adj == 3) /* survive */ | |
cells2Ptr[i][j] = 1; | |
else if (num_alive_adj > 3) /* overpopulation */ | |
cells2Ptr[i][j] = 0; | |
else if (num_alive_adj <= 2) | |
cells2Ptr[i][j] = 0; | |
} else { | |
if (num_alive_adj == 3) /* birth! */ | |
cells2Ptr[i][j] = 1; | |
} | |
} | |
cellsTmp = cellsPtr; | |
cellsPtr = cells2Ptr; | |
cells2Ptr = cellsTmp; | |
} | |
void gen_random_organisms(int num) | |
{ | |
int x, y; | |
while(num--) { | |
x = rand() % (W-2) + 2; | |
y = rand() % (H-2) + 2; | |
/* glider */ | |
cells[y][x] = 1; | |
cells[y][x+1] = 1; | |
cells[y][x+2] = 1; | |
cells[y-1][x+2] = 1; | |
cells[y-2][x+1] = 1; | |
} | |
} | |
int main() | |
{ | |
SDL_Surface *scr; | |
Uint32 second, life_second; | |
int fps = 0, fps_print = 0; | |
SDL_Init(SDL_INIT_VIDEO); | |
atexit(SDL_Quit); | |
scr = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 32, SDL_SWSURFACE | SDL_DOUBLEBUF); | |
SDL_ShowCursor(SDL_ENABLE); | |
srand(time(NULL)); | |
gfxPrimitivesSetFont(NULL, 0, 0); | |
init_isometric(scr, SCREEN_W, SCREEN_H, SCREEN_H / 2, W); | |
second = SDL_GetTicks() + 1000; | |
life_second = SDL_GetTicks() + 300; | |
while(!done) { | |
SDL_FillRect(scr, NULL, start ? 0x111111 : 0); | |
handle_keys(scr); | |
if (start) { | |
/* slow down a bit */ | |
if (SDL_GetTicks() > life_second) { | |
life_second = SDL_GetTicks() + life_speed; | |
life(); | |
} | |
} | |
draw_cells(scr); | |
stringColor(scr, 10, 10, "Numbers to switch view", 0xff00ff); | |
stringColor(scr, 10, 20, "'SPACEBAR' to start, 'R' for random ", 0xff00ff); | |
SDL_Flip(scr); | |
if (SDL_GetTicks() > second) { | |
fps_print = fps; | |
fps = 0; | |
second = SDL_GetTicks() + 1000; | |
} | |
SDL_Delay(30); | |
fps++; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment