diff options
| -rw-r--r-- | include/ct1986.c | 109 | ||||
| -rw-r--r-- | include/tak.c | 2 | ||||
| -rw-r--r-- | src/ctaklm.c | 2 | ||||
| -rw-r--r-- | src/pptdb.c | 4 |
4 files changed, 65 insertions, 52 deletions
diff --git a/include/ct1986.c b/include/ct1986.c index 4e081d1..1c3fa79 100644 --- a/include/ct1986.c +++ b/include/ct1986.c @@ -115,56 +115,61 @@ previous_ply(void) { } } -static inline int -win_evaluate_or_recurse(const uint8_t cur_depth, - const uint8_t max_depth, const uint8_t min, - float* alpha, float* beta, float *optimal) { - float this; - enum WIN_TYPE w = 0xFF; - if (ply >= 2*board_size - 2) w = check_win(); - if (w < 0xFF) { - /* Somebody won, assign weights accordingly */ - if (min == 0) { - if (w == WIN_ROAD_BLACK || w == WIN_FLAT_BLACK || w == WIN_DRAGON) - this = infty; - else this = -infty; - } else { - if (w == WIN_ROAD_WHITE || w == WIN_FLAT_WHITE || w == WIN_DRAGON) - this = -infty; - else this = infty; - } - } else if (cur_depth == max_depth) { - /* We're at the bottom, evaluate */ - this = ct1986_evaluate_black_win(); - if ((ply & 1) == 0) this = this - 1.0; - } else { - /* We're not at the bottom, recurse first */ - next_ply(); - this = ct1986_minimax(cur_depth + 1, max_depth, 1-min, *alpha, *beta); - previous_ply(); - } - /* Update alpha and beta */ - if (min) { - if (this < *beta) *beta = this; - } else { - if (this > *alpha) *alpha = this; - } - /* Update the optimal value */ - if (((min > 0) && (this < *optimal)) - || ((min == 0) && (this > *optimal))) { - *optimal = this; - /* If we're at the top, store the PTN of the winning turn */ - if (cur_depth == 0) { return 1; }; - } - return 0; +/* + * static inline int + * win_evaluate_or_recurse(const uint8_t cur_depth, + * const uint8_t max_depth, const uint8_t min, + * float* alpha, float* beta, float *optimal) { + * float this; + * enum WIN_TYPE w = 0xFF; + */ + +static float val; +static enum WIN_TYPE w; + +#define WIN_EVALUATE_OR_RECURSE(store) { \ + w = 0xFF; \ + if (ply >= 2*board_size - 2) w = check_win(); \ + if (w < 0xFF) { \ + /* Somebody won, assign weights accordingly */ \ + if (min == 0) { \ + if (w == WIN_ROAD_BLACK || w == WIN_FLAT_BLACK || w == WIN_DRAGON) \ + val = infty; \ + else val = -infty; \ + } else { \ + if (w == WIN_ROAD_WHITE || w == WIN_FLAT_WHITE || w == WIN_DRAGON) \ + val = -infty; \ + else val = infty; \ + } \ + } else if (cur_depth == max_depth) { \ + /* We're at the bottom, evaluate */ \ + val = ct1986_evaluate_black_win(); \ + if ((ply & 1) == 0) val = val - 1.0; \ + } else { \ + /* We're not at the bottom, recurse first */ \ + next_ply(); \ + val = ct1986_minimax(cur_depth + 1, max_depth, 1-min, alpha, beta); \ + previous_ply(); \ + } \ + /* Update the optimal value */ \ + if (((min > 0) && (val < optimal)) \ + || ((min == 0) && (val > optimal))) { \ + optimal = val; \ + if (cur_depth == 0) (store); \ + } \ + /* Update alpha and beta */ \ + if (min) { \ + if (optimal < beta) beta = optimal; \ + } else { \ + if (optimal > alpha) alpha = optimal; \ + } \ } float ct1986_minimax(const uint8_t cur_depth, const uint8_t max_depth, const uint8_t min, float alpha, float beta) { + enum E_RESULT r; - uint16_t colours_backup[board_size]; - uint8_t celldat_backup[board_size], drops[board_size]; const uint8_t white_count_backup = white_count, black_count_backup = black_count; @@ -184,6 +189,8 @@ ct1986_minimax(const uint8_t cur_depth, const uint8_t max_depth, // better than manually unrolling this. Sufficiently smart // compilers? + uint16_t colours_backup[board_size]; + uint8_t celldat_backup[board_size], drops[board_size-1]; // Back up the row of the board for (uint8_t y = 0; y < board_size; y++) { colours_backup[y] = colours[THE_COORDS(col, y)]; @@ -201,7 +208,7 @@ ct1986_minimax(const uint8_t cur_depth, const uint8_t max_depth, // just try everything... // For every number of steps - for (uint8_t steps = 1; steps <= board_size && steps <= count; steps++) { + for (uint8_t steps = 1; steps < board_size && steps <= count; steps++) { uint8_t idx, carry; for (idx = 0; idx < steps; idx++) drops[idx]=0; idx = 0; @@ -224,8 +231,11 @@ ct1986_minimax(const uint8_t cur_depth, const uint8_t max_depth, if (r == ACT_OK) { // First check for wins, if we're at the bottom // evaluate, otherwise recurse - if (win_evaluate_or_recurse(cur_depth, max_depth, min, &alpha, &beta, &optimal)) - generate_move(loc, dir, steps, drops, ct1986_ptn); + WIN_EVALUATE_OR_RECURSE({ + // If we did update the optimal value, store + // this move + generate_move(loc, dir, steps, drops, ct1986_ptn); + }); // Reset the board data if (dir <= M_DOWN) { for (uint8_t y = 0; y < board_size; y++) { @@ -257,8 +267,11 @@ ct1986_minimax(const uint8_t cur_depth, const uint8_t max_depth, if (r == ACT_OK) { // First check for wins, if we're at the bottom // evaluate, otherwise recurse - if (win_evaluate_or_recurse(cur_depth, max_depth, min, &alpha, &beta, &optimal)) + WIN_EVALUATE_OR_RECURSE({ + // If we did update the optimal value, store + // this move generate_place(loc, stone, ct1986_ptn); + }); // Reset the state celldat[loc] = 0; white_count = white_count_backup; diff --git a/include/tak.c b/include/tak.c index 657df9d..2ddb78b 100644 --- a/include/tak.c +++ b/include/tak.c @@ -126,7 +126,7 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction, // Game is over? if (won < 0xFF) return GAME_END; // Can't do this - if (steps == 0 || steps > 5) return ACT_ILLEGAL; + if (steps == 0 || steps > board_size) return ACT_ILLEGAL; // Check for stones at all const uint8_t avail = COUNT_AT(location); if (avail == 0) return ACT_ILLEGAL; diff --git a/src/ctaklm.c b/src/ctaklm.c index 7ee86ec..40d16fb 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -410,7 +410,7 @@ main(int argc, char **argv) { if (human && line == NULL) { playing = 0; } else { - ct1986_turn(1); + ct1986_turn(2); human = 1; } } diff --git a/src/pptdb.c b/src/pptdb.c index 345b995..5358885 100644 --- a/src/pptdb.c +++ b/src/pptdb.c @@ -9,7 +9,7 @@ uint64_t heights[16]; FILE *training_fh = NULL; int generate, outcome_black; -const int max_depth = 8; +const int max_depth = 6; static void write_input(void) { @@ -105,7 +105,7 @@ parse_line(const char *pt, const ssize_t read) { } } // Generate training data, not too early in the game - if (generate && ply + 7 > total_plies) { + if (generate && ply + 6 >= total_plies) { write_input(); fprintf(training_fh,"%d\n", outcome_black); } |
