···
struct WinningBoardCollection
12
+
binary_board* boards;
MakeMoveResult make_move_table_partial[2][MAKE_MOVE_TABLE_PARTIAL_SIZE];
MakeMoveResult make_move_table_full[2][MAKE_MOVE_TABLE_FULL_SIZE];
18
-
const uint8_t CHECK_FOR_WIN_PROCESSED_COLUMN_TABLE_SIZE = 0b01111111;
18
+
const uint8_t CHECK_FOR_WIN_PROCESSED_COLUMN_TABLE_SIZE = MAX_FULL_COLUMN + 1;
uint8_t check_for_win_processed_column_table[2][CHECK_FOR_WIN_PROCESSED_COLUMN_TABLE_SIZE];
20
-
WinningBoardCollection check_for_win_processed_winning_boards_table[6][7];
20
+
WinningBoardCollection check_for_win_processed_winning_boards_table[NUM_ROWS][NUM_COLUMNS];
void init_board(BoardState state)
24
-
for (uint8_t col = 0; col < 7; ++col)
24
+
for (uint8_t col = 0; col < NUM_COLUMNS; ++col)
···
inline int8_t get_board_value(BoardState state, uint8_t row, uint8_t col)
32
-
assert(row < 6 && col < 7);
32
+
assert(row < NUM_ROWS && col < NUM_COLUMNS);
return state[col] < (1 << (row + 1)) ? -1 : ((state[col] & (1 << row)) >> row);
int8_t make_move_column(uint8_t player, uint8_t* column_state)
39
-
if (*column_state >= 0b01000000)
39
+
if (*column_state >= MIN_FULL_COLUMN)
uint8_t mask = *column_state; // 0011 0000 (example)
···
76
-
inline uint64_t bit_set(uint64_t num, uint8_t row, uint8_t col)
76
+
inline binary_board bit_set(binary_board num, uint8_t row, uint8_t col)
78
-
return num | ((uint64_t)1 << (col * 8 + (row)));
78
+
return num | ((binary_board)1 << (col * 8 + (row)));
···
for (uint8_t player = 0; player < 2; ++player)
make_move_table_partial[player][0] = MakeMoveResult { -1, 0 };
89
-
for (uint8_t column_state = 1; column_state < 0b01000000; ++column_state)
89
+
for (uint8_t column_state = 1; column_state < MAKE_MOVE_TABLE_PARTIAL_SIZE; ++column_state)
result.column_state = column_state;
···
// Building check_for_win winning board lookup table
140
-
for (uint8_t table_row = 0; table_row < 6; ++table_row)
140
+
for (uint8_t table_row = 0; table_row < NUM_ROWS; ++table_row)
142
-
for (uint8_t table_col = 0; table_col < 7; ++table_col)
142
+
for (uint8_t table_col = 0; table_col < NUM_COLUMNS; ++table_col)
144
-
uint64_t boards[32];
144
+
binary_board boards[32];
148
-
for (uint8_t row_start = 0; row_start < 3; ++row_start)
148
+
for (uint8_t row_start = 0; row_start <= (NUM_ROWS - NUM_TO_WIN); ++row_start)
150
-
uint64_t winning_board_state = 0;
151
-
for (uint8_t row_offset = 0; row_offset < 4; ++row_offset)
150
+
binary_board winning_board_state = 0;
151
+
for (uint8_t row_offset = 0; row_offset < NUM_TO_WIN; ++row_offset)
winning_board_state = bit_set(winning_board_state, row_start + row_offset, table_col);
···
161
-
for (uint8_t col_start = 0; col_start < 4; ++col_start)
161
+
for (uint8_t col_start = 0; col_start <= (NUM_COLUMNS - NUM_TO_WIN); ++col_start)
163
-
uint64_t winning_board_state = 0;
164
-
for (uint8_t col_offset = 0; col_offset < 4; ++col_offset)
163
+
binary_board winning_board_state = 0;
164
+
for (uint8_t col_offset = 0; col_offset < NUM_TO_WIN; ++col_offset)
winning_board_state = bit_set(winning_board_state, table_row, col_start + col_offset);
···
183
-
while (diag_row + 4 <= 6 && diag_col + 4 <= 7)
183
+
while (diag_row + NUM_TO_WIN <= NUM_ROWS && diag_col + NUM_TO_WIN <= NUM_COLUMNS)
185
-
uint64_t winning_board_state = 0;
186
-
for (uint8_t i = 0; i < 4; ++i)
185
+
binary_board winning_board_state = 0;
186
+
for (uint8_t i = 0; i < NUM_TO_WIN; ++i)
winning_board_state = bit_set(winning_board_state, diag_row + i, diag_col + i);
···
int8_t diag_row = table_row;
uint8_t diag_col = table_col;
203
-
while (diag_row + 1 < 6 && diag_col > 0)
203
+
while (diag_row + 1 < NUM_ROWS && diag_col > 0)
209
-
while ((diag_row + 1) - 4 >= 0 && diag_col + 4 <= 7)
209
+
while ((diag_row + 1) - NUM_TO_WIN >= 0 && diag_col + NUM_TO_WIN <= NUM_COLUMNS)
211
-
uint64_t winning_board_state = 0;
212
-
for (uint8_t i = 0; i < 4; ++i)
211
+
binary_board winning_board_state = 0;
212
+
for (uint8_t i = 0; i < NUM_TO_WIN; ++i)
winning_board_state = bit_set(winning_board_state, diag_row - i, diag_col + i);
···
WinningBoardCollection board_collection;
board_collection.num_boards = num_boards;
227
-
board_collection.boards = (uint64_t*)malloc(num_boards * sizeof(uint64_t));
228
-
memcpy(board_collection.boards, boards, num_boards * sizeof(uint64_t));
227
+
board_collection.boards = (binary_board*)malloc(num_boards * sizeof(binary_board));
228
+
memcpy(board_collection.boards, boards, num_boards * sizeof(binary_board));
check_for_win_processed_winning_boards_table[table_row][table_col] = board_collection;
···
int8_t make_move(uint8_t player, uint8_t column, BoardState state)
237
-
assert(column >= 0 && column < 7);
237
+
assert(column >= 0 && column < NUM_COLUMNS);
return make_move_column(player, &state[column]);
···
bool check_for_win(BoardState state, uint8_t last_move_player, uint8_t last_move_row, uint8_t last_move_col)
assert(last_move_player <= 1);
245
-
assert(last_move_row < 6 && last_move_col < 7);
245
+
assert(last_move_row < NUM_ROWS && last_move_col < NUM_COLUMNS);
247
-
uint8_t processed_board_state[8] = { 0 };
248
-
for (uint8_t col = 0; col < 7; ++col)
247
+
uint8_t processed_board_state[NUM_COLUMNS_PROCESSED] = { 0 };
248
+
for (uint8_t col = 0; col < NUM_COLUMNS; ++col)
250
-
assert(state[col] < 0b10000000);
250
+
assert(state[col] < MAX_FULL_COLUMN + 1);
processed_board_state[col] = check_for_win_processed_column_table[last_move_player][state[col]];
254
-
uint64_t* processed_board_state_binary = (uint64_t*)processed_board_state;
254
+
binary_board* processed_board_state_binary = (binary_board*)processed_board_state;
WinningBoardCollection winning_boards = check_for_win_processed_winning_boards_table[last_move_row][last_move_col];
for (uint8_t i = 0; i < winning_boards.num_boards; ++i)
259
-
uint64_t winning_board_state = winning_boards.boards[i];
259
+
binary_board winning_board_state = winning_boards.boards[i];
if ((winning_board_state & *processed_board_state_binary) == winning_board_state)
···
283
-
void get_move_scores(int64_t final_scores[7])
283
+
void get_move_scores(int64_t final_scores[NUM_COLUMNS])
init_board(nodes[0].state);
···
++nodes[depth].curr_move_column;
// If we've checked every column...
361
-
while (nodes[depth].curr_move_column >= 7)
361
+
while (nodes[depth].curr_move_column >= NUM_COLUMNS)
min_depth = depth < min_depth ? depth : min_depth;
···
void sprint_board(BoardState state, char* buffer)
395
-
snprintf(buffer, 256, "_1_2_3_4_5_6_7_\n");
397
-
for (int8_t row = 6 - 1; row >= 0; --row)
395
+
for (uint8_t i = 0; i < NUM_COLUMNS; ++i)
397
+
snprintf(buffer, 256, "_%d", i + 1);
401
+
snprintf(buffer, 256, "_\n");
403
+
for (int8_t row = NUM_ROWS - 1; row >= 0; --row)
snprintf(buffer, 256, "|");
401
-
for (uint8_t col = 0; col < 7; ++col)
407
+
for (uint8_t col = 0; col < NUM_COLUMNS; ++col)
switch (get_board_value(state, row, col))
···
snprintf(buffer, 256, "\n");
425
-
snprintf(buffer, 256, "‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\n");
431
+
for (uint8_t i = 0; i < NUM_COLUMNS; ++i)
433
+
snprintf(buffer, 256, "--");
436
+
snprintf(buffer, 256, "‾\n");
void print_board(BoardState state)