C/ncurses implementation of conway's game of life. wasd/hjkl movement. r to run one cycle, space to toggle a cell's alive state.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

123 lines
2.8 KiB

#include <ncurses.h>
#include <stdlib.h>
int *cells;
int *initcells() {
int *cells = malloc(sizeof(int) * (COLS * LINES));
for(int y = 0; y < LINES; y++)
for(int x = 0; x < COLS; x++)
cells[x + y * COLS] = 0;
return cells;
}
int getcell(size_t x, size_t y) {
return cells[x + y * COLS];
}
void setcell(int *cells, size_t x, size_t y, int value) {
cells[x + y * COLS] = value;
}
int getcellneighbours(int x, int y) {
int neighbours = 0;
for(int ny = y - 1; ny < y + 2; ny++)
for(int nx = x - 1; nx < x + 2; nx++) {
if(ny == y && nx == x) continue;
if(ny < 0 || nx < 0 || ny > LINES || nx > COLS) continue;
neighbours += getcell(nx, ny);
}
return neighbours;
}
void runlife() {
int *newcells = initcells();
for(int y = 0; y < LINES; y++)
for(int x = 0; x < COLS; x++) {
int n = getcellneighbours(x, y);
int alive = getcell(x, y);
if(alive && n > 1 && n < 4) {
setcell(newcells, x, y, 1);
} else if(!alive && n == 3) {
setcell(newcells, x, y, 1);
} else {
setcell(newcells, x, y, 0);
}
}
free(cells);
cells = newcells;
}
void drawcells() {
for(int y = 0; y < LINES; y++) {
for(int x = 0; x < COLS; x++) {
switch(getcell(x, y)) {
case 0: mvprintw(y, x, "."); break;
case 1: mvprintw(y, x, "#"); break;
}
}
}
}
int main() {
stdscr = initscr();
noecho();
cbreak();
curs_set(0);
int running = 1;
int cx = COLS / 2;
int cy = LINES / 2;
cells = initcells();
while(running) {
drawcells();
mvprintw(cy, cx, "@");
switch(getch()) {
case 'w':
case 'k':
cy--;
break;
case 'a':
case 'h':
cx--;
break;
case 's':
case 'j':
cy++;
break;
case 'd':
case 'l':
cx++;
break;
case ' ':
setcell(cells, cx, cy, !getcell(cx, cy));
break;
case 'r':
runlife();
break;
case 'q':
running = 0;
break;
}
if(cx < 0) cx = 0;
if(cx == COLS) cx = COLS - 1;
if(cy < 0) cy = 0;
if(cy == LINES) cy = LINES - 1;
}
echo();
nocbreak();;
curs_set(1);
endwin();
}