// calculates the score of the board from a player's prospective int calc_score(char board[BOARD_SIZE][BOARD_SIZE], COLOR player){ int score = 0, opposites = 0; for (int i = 0; i < BOARD_SIZE; i++) for (int j = 0; j < BOARD_SIZE; j++){ if (is_opposite(player, board[i][j])) opposites++; score += get_piece_score(board[i][j], player); } if (opposites == 0) return 100; return score; }
/* calculates the board's score. * scoring_player = color of the minimax-maximizer player * current_player = color of the player whose turn it is now. * * the function returns: * WIN_SCORE if scoring_player wins this board * LOSE_SCORE if scoring_player loses this board * scoring_player's total pieces value minus other player's total pieces value otherwise * ERROR_SCORE in case of an error */ int score(settings * set, int scoring_player, int current_player, int is_best){ int total_score; cord piece; moves possible_moves; int no_more_moves = TRUE; int no_scoring_king = TRUE; int no_other_king = TRUE; int num_of_moves; int player_score = 0; int other_player_score = 0; int is_scoring_piece; int is_scoring_checked = is_king_checked(current_player, set->board); int is_other_checked = is_king_checked(other_player(current_player), set->board); for (int i = 0; i < BOARD_SIZE; i++){ for (int j = 0; j < BOARD_SIZE; j++){ piece.x = i; piece.y = j; char cur_piece = board_piece(set->board, piece); if (cur_piece == EMPTY) continue; int piece_color = which_color(cur_piece); is_scoring_piece = (piece_color == scoring_player); int piece_score = get_piece_score(cur_piece); if (piece_score == KING_SCORE) { no_scoring_king = (no_scoring_king && !is_scoring_piece); no_other_king = (no_other_king && is_scoring_piece); } if (is_scoring_piece) player_score += piece_score; else //piece_color is other player's color other_player_score += piece_score; // we have to check that current_player has at least one piece that // can move, otherwise current_player loses or it's a tie. if (no_more_moves && (piece_color == current_player)) { // check walking move for piece. checking move of distance 1 takes only O(1) time if // player cannot move and O(n) if player can move (creating new board. occurs at most once) // is enough for both king & man (if king cannot move 1 he cannot move 2) possible_moves = get_simple_moves(set, piece); num_of_moves = possible_moves.len; free_list(&possible_moves, &free); if (num_of_moves == -1) //there was an error, return an error score return SCORE_ERROR; // once one of the current_player can move, they do not lose, // no need to preform this check again. if (num_of_moves > 0) { no_more_moves = FALSE; } } } } // current_player cannot play. if (no_more_moves) { if (is_scoring_checked) // checkmate total_score = (scoring_player == current_player) ? LOSE_SCORE : WIN_SCORE; else // tie total_score = is_best ? 0 : TIE_SCORE; // in best difficulty: 0, otherwise: better only than LOSE_SCORE } // scoring_player's king has ceased to be else if (no_scoring_king) total_score = LOSE_SCORE; // other player's king is pushing up the daisies else if (no_other_king) total_score = WIN_SCORE; //RELEVANT ONLY FOR best DIFFICULTY! else if (is_best && is_scoring_checked) { if (is_scoring_checked) return LOSE_SCORE + 42; else if (is_other_checked) return WIN_SCORE - 42; } // both players' kings are alive and pining for the fjords else total_score = player_score - other_player_score; return total_score; }