diff --git a/uttt.c b/uttt.c index 850a4a7..f8d9bdd 100644 --- a/uttt.c +++ b/uttt.c @@ -779,27 +779,80 @@ int main(int argc, char **argv) { int ut_boardValue(const char *tiles, int offset, int stride) { - int v = 0; + // could change this too.. + int value = 0; for(int r = 0; r < 3; r++) for(int c = 0; c < 3; c++) - v += (T(r, c) == 'X') ? 1 : (T(r, c) == 'O') ? -1 : 0; - return v; + value += (T(r, c) == 'X') ? 1 : (T(r, c) == 'O') ? -1 : 0; + return value; } -#define UT_VALUEMAX 81 -#define UT_VALUEMIN (-81) +#define UT_VALUEMAX 81 * 2 +#define UT_VALUEMIN (-81 * 2) int ut_value(const struct ut_state *state) { - int v = 0; + int value = 0; + + // game is won char winner = ut_winner(state); if(winner != '\0') { - return (winner == 'X') ? 81 : (winner == 'O') ? -81 : 0; + return (winner == 'X') ? 81 * 2 : (winner == 'O') ? -81 * 2 : 0; } - for(int r = 0; r < 3; r++) - for(int c = 0; c < 3; c++) - v += (state->boards[r][c] == '\0') ? ut_boardValue((char *)state->tiles, 27 * r + 3 * c, 9) : - (state->boards[r][c] == 'X') ? 9 : (state->boards[r][c] == 'O') ? -9 : 0; - return v; + + // weight each board: 2x if taken, 2x if blank but would lead to a 2-of-3 + // line (for X or O), 1x otherwise + char importance[3][3] = {1}; + for(int r = 0; r < 3; r++) { + for(int c = 0; c < 3; c++) { + char board = state->boards[r][c]; + if (board == '\0') { + char b1, b2; + // horizontal + b1 = state->boards[r][(c+1)%3]; + b2 = state->boards[r][(c+2)%3]; + if (b2 < b1) { char tmp = b1; b1 = b2; b2 = tmp; } + if (b1 == '\0' && b2 != '\0') importance[r][c] = 2; + // vertical + b1 = state->boards[(r+1)%3][c]; + b2 = state->boards[(r+2)%3][c]; + if (b2 < b1) { char tmp = b1; b1 = b2; b2 = tmp; } + if (b1 == '\0' && b2 != '\0') importance[r][c] = 2; + // diagonals + if (r == c) { + b1 = state->boards[(r+1)%3][(c+1)%3]; + b2 = state->boards[(r+2)%3][(c+2)%3]; + if (b2 < b1) { char tmp = b1; b1 = b2; b2 = tmp; } + if (b1 == '\0' && b2 != '\0') importance[r][c] = 2; + } + if (r == 2 - c) { + b1 = state->boards[(r+1)%3][(c+2)%3]; + b2 = state->boards[(r+2)%3][(c+1)%3]; + if (b2 < b1) { char tmp = b1; b1 = b2; b2 = tmp; } + if (b1 == '\0' && b2 != '\0') importance[r][c] = 2; + } + } + else if (board == 'X') importance[r][c] = 2; + else if (board == 'O') importance[r][c] = 2; + } + } + + // game is in progress + for(int r = 0; r < 3; r++) { + for(int c = 0; c < 3; c++) { + char board = state->boards[r][c]; + int board_value; + if (board == '\0') { + // board is in progress + board_value = ut_boardValue((char *)state->tiles, 27 * r + 3 * c, 9); + } else { + // board is won + board_value = (board == 'X') ? 9 : (board == 'O') ? -9 : 0; + } + value += board_value * importance[r][c]; + } + } + + return value; } int ut_alphabetaq(const struct ut_state *state, struct ut_move move, int depth, int a, int b)