Skip to content

Instantly share code, notes, and snippets.

@safx
Created May 2, 2015 14:45
Show Gist options
  • Save safx/d24547afbb7bde9bfb63 to your computer and use it in GitHub Desktop.
Save safx/d24547afbb7bde9bfb63 to your computer and use it in GitHub Desktop.
Fuzzified Conway's game of life
#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif
#include <SDL/SDL.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <time.h>
#include <sys/timeb.h>
using namespace std;
struct Cell {
uint8_t color;
int value;
};
const int WIDTH = 90;
const int HEIGHT = 90;
const int SIZE = WIDTH * HEIGHT;
Cell* oldmap = 0;
Cell* newmap = 0;
const int CELL_MAX = 0x01000;
const int CELL_SHIFT = 12;
inline int pos(int x, int y) { return x*WIDTH + y; }
//#define Q 0.95
#define Q 0.95
#define QQ (int(CELL_MAX*Q))
/*inline int is2(int z) {
if ((2.0-Q) * CELL_MAX < z && z <= 2 * CELL_MAX) {
return ( z + Q * CELL_MAX - 2 * CELL_MAX) / Q;
} else if (2 * CELL_MAX < z && z <= (2.0+Q) * CELL_MAX) {
return (-z + Q * CELL_MAX + 2 * CELL_MAX) / Q;
} else {
return 0;
}
}
inline int is3(int z) {
if ((3.0-Q) * CELL_MAX < z && z <= 3 * CELL_MAX) {
return ( z + Q * CELL_MAX - 3 * CELL_MAX) / Q;
} else if (3 * CELL_MAX < z && z <= (3.0+Q) * CELL_MAX) {
return (-z + Q * CELL_MAX + 3 * CELL_MAX) / Q;
} else {
return 0;
}
}
*/
inline int is2(int z) {
if ((2.0-Q) * CELL_MAX < z && z <= 2 * CELL_MAX) {
return ( z*CELL_MAX + QQ * CELL_MAX - 2 * CELL_MAX*CELL_MAX) / QQ;
} else if (2 * CELL_MAX < z && z <= (2.0+Q) * CELL_MAX) {
return (-z*CELL_MAX + QQ * CELL_MAX + 2 * CELL_MAX*CELL_MAX) / QQ;
} else {
return 0;
}
}
inline int is3(int z) {
if ((3.0-Q) * CELL_MAX < z && z <= 3 * CELL_MAX) {
return ( z*CELL_MAX + QQ * CELL_MAX - 3 * CELL_MAX*CELL_MAX) / QQ;
} else if (3 * CELL_MAX < z && z <= (3.0+Q) * CELL_MAX) {
return (-z*CELL_MAX + QQ * CELL_MAX + 3 * CELL_MAX*CELL_MAX) / QQ;
} else {
return 0;
}
}
void init() {
timeb currenttime;
//ftime(&currenttime);
time_t currenttimex = currenttime.time;
int r = currenttime.millitm;
srand(r);
memset(oldmap, 0, SIZE);
memset(newmap, 0, SIZE);
for (int y = 1; y < HEIGHT-1; ++y) {
for (int x = 1; x < WIDTH-1; ++x) {
int g = x/(WIDTH/3) + y/(HEIGHT/3)*3;
int c = rand()%2? 0 : rand() % CELL_MAX;
oldmap[pos(x,y)].color = g;
oldmap[pos(x,y)].value = c;
}
}
}
#define q0(x,y) ((oldmap[pos((x),(y))].color)==0? oldmap[pos((x),(y))].value:0)
#define q1(x,y) ((oldmap[pos((x),(y))].color)==1? oldmap[pos((x),(y))].value:0)
#define q2(x,y) ((oldmap[pos((x),(y))].color)==2? oldmap[pos((x),(y))].value:0)
#define q3(x,y) ((oldmap[pos((x),(y))].color)==3? oldmap[pos((x),(y))].value:0)
#define q4(x,y) ((oldmap[pos((x),(y))].color)==4? oldmap[pos((x),(y))].value:0)
#define q5(x,y) ((oldmap[pos((x),(y))].color)==5? oldmap[pos((x),(y))].value:0)
#define q6(x,y) ((oldmap[pos((x),(y))].color)==6? oldmap[pos((x),(y))].value:0)
#define q7(x,y) ((oldmap[pos((x),(y))].color)==7? oldmap[pos((x),(y))].value:0)
#define q8(x,y) ((oldmap[pos((x),(y))].color)==8? oldmap[pos((x),(y))].value:0)
void update() {
for (int y = 1; y < HEIGHT-1; ++y) {
for (int x = 1; x < WIDTH-1; ++x) {
int z = (oldmap[pos(x-1,y-1)].value) + (oldmap[pos(x,y-1)].value) + (oldmap[pos(x+1,y-1)].value)
+ (oldmap[pos(x-1,y )].value) + + (oldmap[pos(x+1,y )].value)
+ (oldmap[pos(x-1,y+1)].value) + (oldmap[pos(x,y+1)].value) + (oldmap[pos(x+1,y+1)].value);
int c = oldmap[pos(x,y)].value;
int g = oldmap[pos(x,y)].color;
int m2 = is2(z);
int m3 = is3(z);
int a = ((m2*c)>>CELL_SHIFT) + m3;
if (a >= CELL_MAX) a = CELL_MAX;
if (m2 < m3) {
int g0 = q0(x-1,y-1)+q0(x,y-1)+q0(x+1,y-1)+q0(x-1,y)+q0(x,y)+q0(x+1,y)+q0(x-1,y+1)+q0(x,y+1)+q0(x+1,y+1);
int g1 = q1(x-1,y-1)+q1(x,y-1)+q1(x+1,y-1)+q1(x-1,y)+q0(x,y)+q1(x+1,y)+q1(x-1,y+1)+q1(x,y+1)+q1(x+1,y+1);
int g2 = q2(x-1,y-1)+q2(x,y-1)+q2(x+1,y-1)+q2(x-1,y)+q0(x,y)+q2(x+1,y)+q2(x-1,y+1)+q2(x,y+1)+q2(x+1,y+1);
int g3 = q3(x-1,y-1)+q3(x,y-1)+q3(x+1,y-1)+q3(x-1,y)+q0(x,y)+q3(x+1,y)+q3(x-1,y+1)+q3(x,y+1)+q3(x+1,y+1);
int g4 = q4(x-1,y-1)+q4(x,y-1)+q4(x+1,y-1)+q4(x-1,y)+q0(x,y)+q4(x+1,y)+q4(x-1,y+1)+q4(x,y+1)+q4(x+1,y+1);
int g5 = q5(x-1,y-1)+q5(x,y-1)+q5(x+1,y-1)+q5(x-1,y)+q0(x,y)+q5(x+1,y)+q5(x-1,y+1)+q5(x,y+1)+q5(x+1,y+1);
int g6 = q6(x-1,y-1)+q6(x,y-1)+q6(x+1,y-1)+q6(x-1,y)+q0(x,y)+q6(x+1,y)+q6(x-1,y+1)+q6(x,y+1)+q6(x+1,y+1);
int g7 = q7(x-1,y-1)+q7(x,y-1)+q7(x+1,y-1)+q7(x-1,y)+q0(x,y)+q7(x+1,y)+q7(x-1,y+1)+q7(x,y+1)+q7(x+1,y+1);
int g8 = q8(x-1,y-1)+q8(x,y-1)+q8(x+1,y-1)+q8(x-1,y)+q0(x,y)+q8(x+1,y)+q8(x-1,y+1)+q8(x,y+1)+q8(x+1,y+1);
if (g0>g1 && g0>g2 && g0>g3 && g0>g4 && g0>g5 && g0>g6 && g0>g7 && g0>g8) g=0;
if (g1>g0 && g1>g2 && g1>g3 && g1>g4 && g1>g5 && g1>g6 && g1>g7 && g1>g8) g=1;
if (g2>g0 && g2>g1 && g2>g3 && g2>g4 && g2>g5 && g2>g6 && g2>g7 && g2>g8) g=2;
if (g3>g0 && g3>g1 && g3>g2 && g3>g4 && g3>g5 && g3>g6 && g3>g7 && g3>g8) g=3;
if (g4>g0 && g4>g1 && g4>g2 && g4>g3 && g4>g5 && g4>g6 && g4>g7 && g4>g8) g=4;
if (g5>g0 && g5>g1 && g5>g2 && g5>g3 && g5>g4 && g5>g6 && g5>g7 && g5>g8) g=5;
if (g6>g0 && g6>g1 && g6>g2 && g6>g3 && g6>g4 && g6>g5 && g6>g7 && g6>g8) g=6;
if (g7>g0 && g7>g1 && g7>g2 && g7>g3 && g7>g4 && g7>g5 && g7>g6 && g7>g8) g=7;
if (g8>g0 && g8>g1 && g8>g2 && g8>g3 && g8>g4 && g8>g5 && g8>g6 && g8>g7) g=8;
}
newmap[pos(x,y)].color = g;
newmap[pos(x,y)].value = a;
}
}
Cell* tmp = newmap;
newmap = oldmap;
oldmap = tmp;
}
void drawPixel(SDL_Surface* screen, int x, int y, Uint8 r, Uint8 g, Uint8 b) {
Uint8* bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 4;
*(bufp++) = b;
*(bufp++) = g;
*(bufp++) = r;
*bufp = 0;
}
void draw_screen() {
SDL_Surface* screen = SDL_GetVideoSurface();
//SDL_FillRect(screen, NULL, 0xff000000);
if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen);
for (int y = 1; y < HEIGHT-1; ++y) {
for (int x = 1; x < WIDTH-1; ++x) {
int g = newmap[pos(x, y)].color;
int d = newmap[pos(x, y)].value;
if (d >= 256) {
d = 255;
}
switch(g) {
case 0:
drawPixel(screen, x*4 , y*4 , d, 0, 0);
drawPixel(screen, x*4+1, y*4 , d, 0, 0);
drawPixel(screen, x*4+2, y*4 , d, 0, 0);
drawPixel(screen, x*4 , y*4+2, d, 0, 0);
drawPixel(screen, x*4+1, y*4+2, d, 0, 0);
drawPixel(screen, x*4+2, y*4+2, d, 0, 0);
drawPixel(screen, x*4 , y*4+1, d, 0, 0);
drawPixel(screen, x*4 , y*4+2, d, 0, 0);
drawPixel(screen, x*4+2, y*4+1, d, 0, 0);
drawPixel(screen, x*4+2, y*4+2, d, 0, 0);
drawPixel(screen, x*4+1, y*4+1, d, 0, 0);
break;
case 1:
drawPixel(screen, x*4 , y*4 , d>>2, d>>2, d);
drawPixel(screen, x*4+1, y*4 , d>>2, d>>2, d);
drawPixel(screen, x*4+2, y*4 , d>>2, d>>2, d);
drawPixel(screen, x*4 , y*4+2, d>>2, d>>2, d);
drawPixel(screen, x*4+1, y*4+2, d>>2, d>>2, d);
drawPixel(screen, x*4+2, y*4+2, d>>2, d>>2, d);
drawPixel(screen, x*4 , y*4+1, d>>2, d>>2, d);
drawPixel(screen, x*4 , y*4+2, d>>2, d>>2, d);
drawPixel(screen, x*4+2, y*4+1, d>>2, d>>2, d);
drawPixel(screen, x*4+2, y*4+2, d>>2, d>>2, d);
drawPixel(screen, x*4+1, y*4+1, d>>2, d>>2, d);
break;
case 2:
drawPixel(screen, x*4 , y*4 , 0, d, 0);
drawPixel(screen, x*4+1, y*4 , 0, d, 0);
drawPixel(screen, x*4+2, y*4 , 0, d, 0);
drawPixel(screen, x*4 , y*4+2, 0, d, 0);
drawPixel(screen, x*4+1, y*4+2, 0, d, 0);
drawPixel(screen, x*4+2, y*4+2, 0, d, 0);
drawPixel(screen, x*4 , y*4+1, 0, d, 0);
drawPixel(screen, x*4 , y*4+2, 0, d, 0);
drawPixel(screen, x*4+2, y*4+1, 0, d, 0);
drawPixel(screen, x*4+2, y*4+2, 0, d, 0);
drawPixel(screen, x*4+1, y*4+1, 0, d, 0);
break;
case 3:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
break;
case 4:
drawPixel(screen, x*4 , y*4 , d, d, 0);
drawPixel(screen, x*4+1, y*4 , d, d, 0);
drawPixel(screen, x*4+2, y*4 , d, d, 0);
drawPixel(screen, x*4 , y*4+2, d, d, 0);
drawPixel(screen, x*4+1, y*4+2, d, d, 0);
drawPixel(screen, x*4+2, y*4+2, d, d, 0);
drawPixel(screen, x*4 , y*4+1, d, d, 0);
drawPixel(screen, x*4 , y*4+2, d, d, 0);
drawPixel(screen, x*4+2, y*4+1, d, d, 0);
drawPixel(screen, x*4+2, y*4+2, d, d, 0);
drawPixel(screen, x*4+1, y*4+1, d, d, 0);
break;
case 5:
drawPixel(screen, x*4 , y*4 , 0, d, d);
drawPixel(screen, x*4+1, y*4 , 0, d, d);
drawPixel(screen, x*4+2, y*4 , 0, d, d);
drawPixel(screen, x*4 , y*4+2, 0, d, d);
drawPixel(screen, x*4+1, y*4+2, 0, d, d);
drawPixel(screen, x*4+2, y*4+2, 0, d, d);
drawPixel(screen, x*4 , y*4+1, 0, d, d);
drawPixel(screen, x*4 , y*4+2, 0, d, d);
drawPixel(screen, x*4+2, y*4+1, 0, d, d);
drawPixel(screen, x*4+2, y*4+2, 0, d, d);
drawPixel(screen, x*4+1, y*4+1, 0, d, d);
break;
case 6:
drawPixel(screen, x*4 , y*4 , d>>1, d>>3, d);
drawPixel(screen, x*4+1, y*4 , d>>1, d>>3, d);
drawPixel(screen, x*4+2, y*4 , d>>1, d>>3, d);
drawPixel(screen, x*4 , y*4+2, d>>1, d>>3, d);
drawPixel(screen, x*4+1, y*4+2, d>>1, d>>3, d);
drawPixel(screen, x*4+2, y*4+2, d>>1, d>>3, d);
drawPixel(screen, x*4 , y*4+1, d>>1, d>>3, d);
drawPixel(screen, x*4 , y*4+2, d>>1, d>>3, d);
drawPixel(screen, x*4+2, y*4+1, d>>1, d>>3, d);
drawPixel(screen, x*4+2, y*4+2, d>>1, d>>3, d);
drawPixel(screen, x*4+1, y*4+1, d>>1, d>>3, d);
break;
case 7:
drawPixel(screen, x*4 , y*4 , d>>1, d>>1, d>>1);
drawPixel(screen, x*4+1, y*4 , d>>1, d>>1, d>>1);
drawPixel(screen, x*4+2, y*4 , d>>1, d>>1, d>>1);
drawPixel(screen, x*4 , y*4+2, d>>1, d>>1, d>>1);
drawPixel(screen, x*4+1, y*4+2, d>>1, d>>1, d>>1);
drawPixel(screen, x*4+2, y*4+2, d>>1, d>>1, d>>1);
drawPixel(screen, x*4 , y*4+1, d>>1, d>>1, d>>1);
drawPixel(screen, x*4 , y*4+2, d>>1, d>>1, d>>1);
drawPixel(screen, x*4+2, y*4+1, d>>1, d>>1, d>>1);
drawPixel(screen, x*4+2, y*4+2, d>>1, d>>1, d>>1);
drawPixel(screen, x*4+1, y*4+1, d>>1, d>>1, d>>1);
break;
case 8:
drawPixel(screen, x*4 , y*4 , d, d>>2, d>>1);
drawPixel(screen, x*4+1, y*4 , d, d>>2, d>>1);
drawPixel(screen, x*4+2, y*4 , d, d>>2, d>>1);
drawPixel(screen, x*4 , y*4+2, d, d>>2, d>>1);
drawPixel(screen, x*4+1, y*4+2, d, d>>2, d>>1);
drawPixel(screen, x*4+2, y*4+2, d, d>>2, d>>1);
drawPixel(screen, x*4 , y*4+1, d, d>>2, d>>1);
drawPixel(screen, x*4 , y*4+2, d, d>>2, d>>1);
drawPixel(screen, x*4+2, y*4+1, d, d>>2, d>>1);
drawPixel(screen, x*4+2, y*4+2, d, d>>2, d>>1);
drawPixel(screen, x*4+1, y*4+1, d, d>>2, d>>1);
break;
/*
case 9:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 10:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 11:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 12:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 13:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 14:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;
case 15:
drawPixel(screen, x*4 , y*4 , d, 0, d);
drawPixel(screen, x*4+1, y*4 , d, 0, d);
drawPixel(screen, x*4+2, y*4 , d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+1, y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
drawPixel(screen, x*4 , y*4+1, d, 0, d);
drawPixel(screen, x*4 , y*4+2, d, 0, d);
drawPixel(screen, x*4+2, y*4+1, d, 0, d);
drawPixel(screen, x*4+2, y*4+2, d, 0, d);
if (d >= 192) {
drawPixel(screen, x*4+1, y*4+1, d, 0, d);
}
break;*/
}
}
}
SDL_Flip(screen);
if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
}
void process_events(void) {
SDL_Event event;
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
exit(0);
break;
}
}
}
void one_iter() {
update();
draw_screen();
}
int main(int argc, char** argv) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Video initialization failed: %s\n", SDL_GetError());
return 1;
}
#ifndef EMSCRIPTEN
atexit(SDL_Quit);
#endif
int width = WIDTH * 4;
int height = HEIGHT * 4;
int bpp = 16;
int flags = SDL_HWSURFACE;
//flags = SDL_OPENGL | SDL_FULLSCREEN;
flags = 0;
if (SDL_SetVideoMode(width, height, bpp, flags) == 0) {
printf("Video mode set failed: %s\n", SDL_GetError());
return 1;
}
oldmap = new Cell[SIZE];
newmap = new Cell[SIZE];
init();
#ifdef EMSCRIPTEN
emscripten_set_main_loop(one_iter, 16);
#else
while(1){
process_events();
one_iter();
SDL_Delay(10);
}
#endif
delete oldmap;
delete newmap;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment