-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
gameoflife.c
127 lines (105 loc) · 2.89 KB
/
gameoflife.c
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <uvm/syscalls.h>
#include <uvm/utils.h>
#include <uvm/window.h>
#include <stdlib.h>
#include <stdint.h>
#define FRAME_WIDTH 600
#define FRAME_HEIGHT 600
#define CELL_SIZE 4
#define NUM_ROWS 150
#define NUM_COLS 150
// RGBA pixels: 600 * 600
uint32_t frame_buffer[360_000];
// Current and next board
bool board[2][NUM_ROWS][NUM_COLS];
// Current generation counter
uint32_t gen_no = 0;
void draw_rect(int xmin, int ymin, int width, int height, u32 color)
{
for (int j = 0; j < height; ++j)
{
for (int i = 0; i < width; ++i)
{
u32* pix_ptr = frame_buffer + (FRAME_WIDTH) * (ymin + j) + (xmin + i);
*pix_ptr = color;
}
}
}
int get_cell(uint32_t board_idx, int row, int col)
{
return (int)board[board_idx][(uint32_t)row % NUM_ROWS][(uint32_t)col % NUM_COLS];
}
int count_neighbors(uint32_t board_idx, int row, int col)
{
int count = 0;
// Row above
count = count + get_cell(board_idx, row - 1, col - 1);
count = count + get_cell(board_idx, row - 1, col );
count = count + get_cell(board_idx, row - 1, col + 1);
// Middle row
count = count + get_cell(board_idx, row, col - 1);
count = count + get_cell(board_idx, row, col + 1);
// Row below
count = count + get_cell(board_idx, row + 1, col - 1);
count = count + get_cell(board_idx, row + 1, col );
count = count + get_cell(board_idx, row + 1, col + 1);
return count;
}
void update()
{
// Clear the screen
memset(frame_buffer, 0, sizeof(frame_buffer));
uint32_t prev_board = gen_no % 2;
uint32_t next_board = (gen_no + 1) % 2;
gen_no = gen_no + 1;
for (int row = 0; row < NUM_ROWS; ++row)
{
for (int col = 0; col < NUM_COLS; ++col)
{
int count = count_neighbors(prev_board, row, col);
int alive = get_cell(prev_board, row, col);
if (alive)
{
if (count < 2)
alive = 0;
else if (count > 3)
alive = 0;
}
else
{
if (count == 3)
alive = 1;
}
board[next_board][row][col] = alive;
if (alive)
{
draw_rect(
col * CELL_SIZE,
row * CELL_SIZE,
CELL_SIZE,
CELL_SIZE,
0x00_EE_00
);
}
}
}
window_draw_frame(0, frame_buffer);
}
void bench_update()
{
benchmark(update());
}
void main()
{
window_create(FRAME_WIDTH, FRAME_HEIGHT, "Game of Life", 0);
// Randomly initialize the board
srand(time_current_ms());
for (int row = 0; row < NUM_ROWS; ++row)
{
for (int col = 0; col < NUM_COLS; ++col)
{
board[0][row][col] = rand() % 2;
}
}
anim_event_loop(20, bench_update);
}