int main(int argc, char **argv) { GWindow gw(WIDTH, HEIGHT); int n; #if 1 do{ n = getInteger("Please input the board size(int between 1 and 20):"); if(n <= 0 || n >= 20) cout << "you input a wrong size, please input a correct size." << endl; else break; }while(n <= 0 || n >= 20); #endif Grid<bool> ChessBoard(n, n); #if 0 can_be_placed(ChessBoard, GPoint(5,3)); display_ChessBoard(ChessBoard); #endif #if 1 if(solveChessBoard(ChessBoard)) { draw_ChessBoard(ChessBoard, gw); } else cout << "can't find a solution for " << ChessBoard.numRows() << "x" << ChessBoard.numRows() << " board" <<endl; #endif return 0; }
static int try_place(t_element *el, t_field *f) { if (!find_empty_point(f, el->position)) { el->position->x = -1; el->position->y = 0; return (0); } while (!can_be_placed(el, f, el->position)) { if (!find_empty_point(f, el->position)) { el->position->x = -1; el->position->y = 0; return (0); } } place_element(el, f, el->position); return (1); }
// This is the core function to solve queen problem // queen_to_find is the number of queens to be find. bool solve(Grid<bool> &ChessBoard, GPoint start, int queen_to_find) { if(queen_to_find == 0) return true; int i,j; int board_size = ChessBoard.numRows(); int start_x = start.getX(); int start_y = start.getY(); ChessBoard.set(start_x, start_y, true); display_ChessBoard(ChessBoard); Direction dirs[4] = {NORTH, EAST,SOUTH, WEST}; for(int i = 0; i < 4; i++) { GPoint adjPoint = adjacentGPoint(start, dirs[i]); if(!can_be_placed(ChessBoard, adjPoint)) continue; if(solve(ChessBoard, adjPoint, queen_to_find - 1 )) return true; } ChessBoard.set(start_x, start_y, false); return false; }
int calc_best_column(void) { struct Player me; struct Player them; int col_to_drop = game.settings.field_columns / 2; int ordering[MAX_FIELD_COLUMNS]; int col; int i; int j; int maxAB = INT_MIN; int resAB; int x; int y; me.id = game.settings.your_botid; them.id = game.settings.their_botid; me.attacks = ATTACK_POINTS_DEFAULT; them.attacks = ATTACK_POINTS_DEFAULT; get_attack_point_counts(&me, &them, game.field); fprintf(stderr, "Your shared odd count: %d\n", me.attacks.shared_odd_count); fprintf(stderr, "Their shared odd count: %d\n", them.attacks.shared_odd_count); fprintf(stderr, "Your shared even count: %d\n", me.attacks.shared_even_count); fprintf(stderr, "Their shared even count: %d\n", them.attacks.shared_even_count); fprintf(stderr, "Your unshared odd count: %d\n", me.attacks.unshared_odd_count); fprintf(stderr, "Their unshared odd count: %d\n", them.attacks.unshared_odd_count); fprintf(stderr, "Your unshared even count: %d\n", me.attacks.unshared_even_count); fprintf(stderr, "Their unshared even count: %d\n", them.attacks.unshared_even_count); if (has_advantage(me, them, FALSE)) fprintf(stderr, "Your advantage!\n"); else if (has_advantage(them, me, FALSE)) fprintf(stderr, "Their advantage...\n"); i = game.settings.field_columns / 2; ordering[0] = i; for (j = 1; j < game.settings.field_columns; ++j) { if (j % 2 == 0) ordering[j] = i + j; else ordering[j] = i - j; i = ordering[j]; } for (x = 0; x < game.settings.field_columns; ++x) { for (y = 0; y < game.settings.field_rows; ++y) { col = ordering[x]; if (can_be_placed(col, y, game.field)) { game.field[col][y] = game.settings.your_botid; if (game.time_remaining > TIMEBANK_LOW && game.round > 11) resAB = alpha_beta(game.field, col, y, ALPHABETA_LEVEL, INT_MIN, INT_MAX, FALSE); else resAB = alpha_beta(game.field, col, y, ALPHABETA_LEVEL - 1, INT_MIN, INT_MAX, FALSE); game.field[col][y] = 0; fprintf(stderr, "(%d, %d): %d\n", col, y, resAB); if (resAB > maxAB) { maxAB = resAB; col_to_drop = col; } } } } return col_to_drop; }
static int alpha_beta(int field[][MAX_FIELD_ROWS], int x, int y, int depth, int alpha, int beta, int maximizing_player) { int done = FALSE; int their_longest = get_longest_line(x, y, game.settings.their_botid, field); int your_longest = get_longest_line(x, y, game.settings.your_botid, field); int last_player; int chldx; int chldy; int v; if (depth <= 0 || their_longest >= WIN_LENGTH || your_longest >= WIN_LENGTH) { if (maximizing_player) last_player = 2; else last_player = 1; if (their_longest >= WIN_LENGTH) return evaluate(game.settings.your_botid, game.settings.their_botid, x, y, last_player, field) + (ALPHABETA_LEVEL - depth); else if (your_longest >= WIN_LENGTH) return evaluate(game.settings.your_botid, game.settings.your_botid, x, y, last_player, field) - (ALPHABETA_LEVEL - depth); else return evaluate(game.settings.your_botid, 0, x, y, last_player, field) - (ALPHABETA_LEVEL - depth); } else if (board_full(game.round + ALPHABETA_LEVEL - depth)) return 0; if (maximizing_player) { v = INT_MIN; for (chldx = 0; chldx < game.settings.field_columns; ++chldx) { for (chldy = 0; chldy < game.settings.field_rows; ++chldy) { if (can_be_placed(chldx, chldy, field)) { field[chldx][chldy] = game.settings.your_botid; v = max(v, alpha_beta(field, chldx, chldy, depth - 1, alpha, beta, FALSE)); alpha = max(alpha, v); field[chldx][chldy] = 0; if (beta <= alpha) { done = TRUE; break; } } } if (done) break; } return v; } else { v = INT_MAX; for (chldx = 0; chldx < game.settings.field_columns; ++chldx) { for (chldy = 0; chldy < game.settings.field_rows; ++chldy) { if (can_be_placed(chldx, chldy, field)) { field[chldx][chldy] = game.settings.their_botid; v = min(v, alpha_beta(field, chldx, chldy, depth - 1, alpha, beta, TRUE)); beta = min(beta, v); field[chldx][chldy] = 0; if (beta <= alpha) { done = TRUE; break; } } } if (done) break; } return v; } }
/* * returns true if it finds an attack point */ static int increment_points(struct Player *red, struct Player *black, int field[][MAX_FIELD_ROWS], int x, int y) { int red_count; int black_count; if (field[x][y] == 0 && !can_be_placed(x, y, field)) { field[x][y] = red->id; red_count = get_pot_longest_line(x, y, red->id, field); field[x][y] = black->id; black_count = get_pot_longest_line(x, y, black->id, field); field[x][y] = 0; if (red_count >= WIN_LENGTH && black_count >= WIN_LENGTH) { if (y % 2 == 0) { red->attacks.shared_even_count++; black->attacks.shared_even_count++; } else { red->attacks.shared_odd_count++; black->attacks.shared_odd_count++; } return TRUE; } if (red_count >= WIN_LENGTH) { if (y % 2 == 0) red->attacks.unshared_even_count++; else red->attacks.unshared_odd_count++; return TRUE; } if (black_count >= WIN_LENGTH) { if (y % 2 == 0) black->attacks.unshared_even_count++; else black->attacks.unshared_odd_count++; return TRUE; } if (red_count == WIN_LENGTH - 1 && black_count == WIN_LENGTH - 1) { if (y % 2 == 0) { red->attacks.minor_shared_even_count++; black->attacks.minor_shared_even_count++; } else { red->attacks.minor_shared_odd_count++; black->attacks.minor_shared_odd_count++; } return FALSE; } if (red_count == WIN_LENGTH - 1) { if (y % 2 == 0) red->attacks.minor_unshared_even_count++; else red->attacks.minor_unshared_odd_count++; return FALSE; } if (black_count == WIN_LENGTH - 1) { if (y % 2 == 0) black->attacks.minor_unshared_even_count++; else black->attacks.minor_unshared_odd_count++; return FALSE; } }; return FALSE; }