-
clemo authored
Signed-off-by:
clemo <clemo@cbcode.at>
clemo authoredSigned-off-by:
clemo <clemo@cbcode.at>
gol.c 2.97 KiB
#include "gol.h"
#include <stdlib.h>
#ifdef GOL_DEBUG
#include <stdio.h>
#endif
/**
* @param int width - width in byte (/=8)
* @param int height - height in bit
*/
gol *gol_setup(unsigned int width, unsigned int height)
{
gol *gameData = calloc(sizeof(gol), 1);
gameData->width = width;
gameData->height = height;
gameData->next = calloc(width * height, sizeof(unsigned int));
gameData->current = calloc(width * height, sizeof(unsigned int));
return gameData;
}
void gol_free(gol *data)
{
free(data->next);
free(data->current);
free(data);
}
unsigned int getCell(gol *g, unsigned int row, unsigned int colmn, unsigned int coffset)
{
return g->current[row * g->width + colmn] & (1 << (7 - coffset)) ? 1 : 0;
}
unsigned int sumNeighbours(gol *g, unsigned int row, unsigned int colmn, unsigned int coffset)
{
unsigned int sum = 0;
//up
unsigned int urow = row - 1;
if (row < 1)
{
urow = g->height - 1;
}
//left
unsigned int loffset = coffset - 1;
unsigned int lcolmn = colmn;
if (coffset < 1)
{
loffset = 7;
lcolmn = colmn - 1;
if (colmn < 1)
{
lcolmn = g->width - 1;
}
}
//right
unsigned int roffset = coffset + 1;
unsigned int rcolmn = colmn;
if (7 < roffset)
{
roffset = 0;
rcolmn += 1;
if (g->width <= rcolmn)
{
rcolmn = 0;
}
}
//down
unsigned int drow = row + 1;
if (g->height <= drow)
{
drow = 0;
}
//up - left
sum += getCell(g, urow, lcolmn, loffset);
//up
sum += getCell(g, urow, colmn, coffset);
//up -right
sum += getCell(g, urow, rcolmn, roffset);
//right
sum += getCell(g, row, rcolmn, roffset);
//down -right
sum += getCell(g, drow, rcolmn, roffset);
//down
sum += getCell(g, drow, colmn, coffset);
//down-left
sum += getCell(g, drow, lcolmn, loffset);
//left
sum += getCell(g, row, lcolmn, loffset);
return sum;
}
void printBits(unsigned int i, gol_print_colmn colmnFn)
{
for (unsigned int j = 0; j < 8; j++)
{
colmnFn((i & (1 << (7 - j)) ? 1 : 0));
}
}
void gol_each(gol *g, gol_print_colmn colmnFn, gol_print_ln lnFn)
{
for (unsigned int row = 0; row < g->height; row++)
{
for (unsigned int colmn = 0; colmn < g->width; colmn++)
{
#ifdef GOL_DEBUG
printf("<%d:%d>(%d) %d\t", row, colmn, row * g->width + colmn, g->current[row * g->width + colmn]);
#endif
printBits(g->current[row * g->width + colmn], colmnFn);
}
lnFn(row);
}
}
void gol_tick(gol *g)
{
for (unsigned int row = 0; row < g->height; row++)
{
for (unsigned int colmn = 0; colmn < g->width; colmn++)
{
g->next[row * g->width + colmn] = 0;
for (unsigned int coff = 0; coff < 8; coff++)
{
const unsigned int sn = sumNeighbours(g, row, colmn, coff);
if (getCell(g, row, colmn, coff) == 1)
{
//living cell
if (1 < sn && sn < 4)
{
g->next[row * g->width + colmn] |= (1 << (7 - coff));
}
}
else
{
//dead cell
if (sn == 3)
{
g->next[row * g->width + colmn] |= (1 << (7 - coff));
}
}
}
}
}
unsigned int *tmp = g->current;
g->current = g->next;
g->next = tmp;
}