#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; }