/* ex1-c: Advent2020 game, day 17/game 1 */ #include #include #include #include #include #include "list.h" #define LOOPS 6 #define MAXINIT 8 #define SIZE ((2*LOOPS)+MAXINIT) #define ZERO (SIZE/2) #define ACTIVE '#' #define INACTIVE '.' typedef struct cell { char state; char oldstate; bool visited; /* redundant ? */ unsigned count; /* active neighbors */ // for runs, we don't care unused cells struct list_head set; /* current actives */ struct list_head viewed; /* current visited */ } CELL; LIST_HEAD(qset); LIST_HEAD(qviewed); static CELL cube[SIZE][SIZE][SIZE]; #define CUBE2X(cell) (((cell)-&cube[0][0][0])/SIZE/SIZE) #define CUBE2Y(cell) (((cell)-&cube[0][0][0])/SIZE%SIZE) #define CUBE2Z(cell) (((cell)-&cube[0][0][0])/(SIZE/SIZE)%SIZE) #define HEADRESET(elt) { \ (elt)->next=POISON_POINTER1;(elt)->prev=POISON_POINTER1; } static void reset_cell(CELL *pcell) { pcell->state=INACTIVE; pcell->oldstate=INACTIVE; pcell->visited=false; pcell->count=0; } static void reset_cube() { int i, j, k; for (i=0; iset, &qset); list_add(&pcell->viewed, &qviewed); pcell->state=ACTIVE; pcell->visited=1; } } } void run_life() { struct cell *pcell, *ptmp; int x, y, z, x1, y1, z1; /* 1) count +1 for neighbors */ list_for_each_entry(pcell, &qset, set) { x=CUBE2X(pcell); y=CUBE2Y(pcell); z=CUBE2Z(pcell); for (x1=x-1; x1<=x+1; x1++) { for (y1=y-1; y1<=y+1; y1++) { for (z1=z-1; z1<=z+1; z1++) { if ((x1!=x || y1!=y || z1!=z)) { ptmp=&cube[x1][y1][z1]; ++ptmp->count; if (!ptmp->visited) { list_add(&ptmp->viewed, &qviewed); ptmp->visited=1; } } } } } } list_for_each_entry_safe(pcell, ptmp, &qviewed, viewed) { switch (pcell->state) { case ACTIVE: if (pcell->count != 2 && pcell->count != 3) { list_del(&pcell->set); pcell->state=INACTIVE; pcell->visited=0; } break; case INACTIVE: if (pcell->count == 3) { list_add(&pcell->set, &qset); pcell->state=ACTIVE; pcell->visited=1; } break; } pcell->count=0; if (pcell->state == INACTIVE) { pcell->visited=0; list_del(&pcell->viewed); } } } int main(ac, av) int ac; char **av; { char line[16]; int nline=0; reset_cube(); INIT_LIST_HEAD(&qset); INIT_LIST_HEAD(&qviewed); while (fgets(line, sizeof line, stdin)) { init_row(line, nline); nline++; } for (int i=0; i