diff --git a/src/advanced.cpp b/src/advanced.cpp index 698c286..aca9f0e 100644 --- a/src/advanced.cpp +++ b/src/advanced.cpp @@ -27,11 +27,13 @@ void Execute(int row, int column) { PrintMap(); std::cout.rdbuf(old_output_buffer); // Restore the output buffer str = oss.str(); // Read the output + // debug: output status of map to original stdout + PrintMap(); std::istringstream iss(str); // Redirect the input to the string, which // stores the output recently std::streambuf *old_input_buffer = std::cin.rdbuf(); ReadMap(); - std::cin.rdbuf(old_input_buffer); + std::cin.rdbuf(old_input_buffer); // Restore the input buffer } int main() { diff --git a/src/include/client.h b/src/include/client.h index 6126ad7..5fe14f1 100644 --- a/src/include/client.h +++ b/src/include/client.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include extern int rows; // The count of rows of the game map @@ -49,15 +51,71 @@ void InitGame() { * 01? */ namespace Client { +const unsigned int RndSeed = std::random_device{}(); +std::mt19937 RawRnd(RndSeed); // a basic random generator const int max_size = 35; -char game_map[max_size][max_size]; +char game_map[max_size][max_size]; // store the raw game map in format of char +std::queue > + no_mine_block_to_be_clicked; // store the block that definitely has no mine + // and not yet clicked +int map_status[max_size] + [max_size]; // store the status of each block(processed version), + // 0 means unknown , -1 means has mine, 1 means no + // mine and not yet clicked, and 2 means has been + // clicked Note that if some block is found to be + // definitely has no mine or has mine, it will be + // marked as known even if it is not clicked. In + // conclusion, if map_status[i][j] == 0, then + // game_map[i][j] == '?'. If map_status[i][j] == -1, + // then game_map[i][j] == '?', and it will never be + // clicked. If map_status[i][j] == 1, then + // game_map[i][j] == '?', and it will be clicked + // later. If map_status[i][j] == 2, then + // game_map[i][j] == '0'-'8', and it has been clicked + // And when a block's status is updated from 0 to 1, + // it will be pushed into no_mine_block_to_be_clicked /** * @brief The definition of function PreProcessData() * * @details This function is designed to preprocess the data of the game map * immedietly after reading it. + * It will check unknown blocks and use Gaussian Elimination to find if there is + * any block that definitely has no mine or has mine. If there is a block + * definitely has no mine, it will push the block into + * no_mine_block_to_be_clicked. + * Note that if some block is found to be definitely has no mine or has mine, it + * will be marked as known even if it is not clicked. */ -void PreProcessData() { using namespace Client; } +void PreProcessData() { + using namespace Client; + // scan the game_map and mark clicked block in map_status + for (int i = 0; i < rows; i++) + for (int j = 0; j < columns; j++) + if (game_map[i][j] != '?') { + assert(game_map[i][j] >= '0' && game_map[i][j] <= '8'); + map_status[i][j] = 2; + // special process for 0 before Gaussian Elimination starts + if (game_map[i][j] == '0') { + for (int k = i - 1; k <= i + 1; k++) + for (int l = j - 1; l <= j + 1; l++) + if (k >= 0 && k < rows && l >= 0 && l < columns && + map_status[k][l] == 0) { + map_status[k][l] = 1; + no_mine_block_to_be_clicked.push(std::make_pair(k, l)); + } + } + } +} +/** + * @brief The definition of function MakeBestGuess() + * + * @details This function is designed to make the best guess when there is no + * definite none-mine block to be clicked. + */ +std::pair MakeBestGuess() { + using namespace Client; + return std::make_pair(0, 0); +} /** * @brief The definition of function GenerateNextStep() * @@ -66,7 +124,12 @@ void PreProcessData() { using namespace Client; } */ std::pair GenerateNextStep() { using namespace Client; - return std::make_pair(0, 0); + if (!no_mine_block_to_be_clicked.empty()) { + std::pair next_step = no_mine_block_to_be_clicked.front(); + no_mine_block_to_be_clicked.pop(); + return next_step; + } else + return MakeBestGuess(); } } // namespace Client void ReadMap() {