1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#include <stdio.h>
#define LOOP(col,line) \
for (int j=0; j< 40; j++) { \
for (int i=0; i < 80; i++) { \
col \
} \
line \
}
/*
*Grid where everything is stored, 2nd least significant bit stores current
*state and least significant bit stores new state.
* The grid stores column position(x position) in the first field while row
* position( y position) is in the second field. As per c rules, this means that
* it is 80 wide by 40 tall, and the underlying datatype is a pointer to 80
* pointers stored in an array, each of which point to 40 chars stored in an
* array.
*
*We use char because it's close enough to uint8_t w/o having to include the
* standard into library.
* There's a glider stored in the first 9x9 bits. We assume that everything is
* zero'd out
*/
char grid[80][40] = {{0,0,2},{2,0,2},{0,2,2},0};
/*
*determines whether a node should live(return 1) or die (return 0) based on
* it's current state
*/
int neighbor (int x, int y) {
/*neighbor count*/
int count = 0;
/*loops through all neighbors based off of y offset j and x offset i*/
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
/* makes sure to not count itself as a neighbor*/
if (!((i == 0) && (j == 0))) {
/*
* modulo loops the grid back into itself
* the addition of the value is required
* otherwise strange nondeterministic behavior
* occurs
*/
if ( grid[(x+i + 80 )%80][(y+j + 40)%40] & 0x02) {
count++;
}
}
}
}
/*
* Switch determines the rules of conway's game of life
*/
switch (count) {
/*
* The current population of a cell determines whether it lives
* or die if it has 2 neighbors
*/
case 2:
if (grid[x][y] & 0x02) {
return 1;
} else {
return 0;
}
case 3:
return 1;
default:
return 0;
}
}
int main (int argc, char * argv[]) {
/*
* Stores the input character read from stdin. It's initialized to 0
* because the main loop depends on it not being 'q'
*/
int r = 0;
/*
* A do at least once loop that iterates through the game. It tests for
* whether the character read from stdin is 'q'
*/
do {
/*
* Input from stdin, this is blocking so it also serves as a delay
*/
r = fgetc(stdin);
/*
* First it prints the current state stored in the 2nd least
* significant bit. X if it is present, Y if it is not. This
* loop is implemented as a macro b/c the entire loop has to be
* run 3 different times. The first argument is to be run for
* every cell while the 2nd one is to be run at the end of every
* row
*/
LOOP(if (grid[i][j] & 0x02) {printf("X");}else{printf(",");},printf("\n"););
/*
* Determines the current live/die state, then puts it into the
* least significant bit representing the new state of the cell
*/
LOOP(grid[i][j] = neighbor(i,j) | (grid[i][j] & 0x02);,);
/*
* Shifts the cell's state up, thereby making the new state the
* current state and the new new state 0.
*/
LOOP(grid[i][j] = grid[i][j] << 1;,);
} while (r != 'q');
}
|