establish the main structure & update advance.cpp
This commit is contained in:
@ -27,11 +27,13 @@ void Execute(int row, int column) {
|
|||||||
PrintMap();
|
PrintMap();
|
||||||
std::cout.rdbuf(old_output_buffer); // Restore the output buffer
|
std::cout.rdbuf(old_output_buffer); // Restore the output buffer
|
||||||
str = oss.str(); // Read the output
|
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
|
std::istringstream iss(str); // Redirect the input to the string, which
|
||||||
// stores the output recently
|
// stores the output recently
|
||||||
std::streambuf *old_input_buffer = std::cin.rdbuf();
|
std::streambuf *old_input_buffer = std::cin.rdbuf();
|
||||||
ReadMap();
|
ReadMap();
|
||||||
std::cin.rdbuf(old_input_buffer);
|
std::cin.rdbuf(old_input_buffer); // Restore the input buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <random>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
extern int rows; // The count of rows of the game map
|
extern int rows; // The count of rows of the game map
|
||||||
@ -49,15 +51,71 @@ void InitGame() {
|
|||||||
* 01?
|
* 01?
|
||||||
*/
|
*/
|
||||||
namespace Client {
|
namespace Client {
|
||||||
|
const unsigned int RndSeed = std::random_device{}();
|
||||||
|
std::mt19937 RawRnd(RndSeed); // a basic random generator
|
||||||
const int max_size = 35;
|
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<std::pair<int, int> >
|
||||||
|
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()
|
* @brief The definition of function PreProcessData()
|
||||||
*
|
*
|
||||||
* @details This function is designed to preprocess the data of the game map
|
* @details This function is designed to preprocess the data of the game map
|
||||||
* immedietly after reading it.
|
* 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<int, int> MakeBestGuess() {
|
||||||
|
using namespace Client;
|
||||||
|
return std::make_pair(0, 0);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief The definition of function GenerateNextStep()
|
* @brief The definition of function GenerateNextStep()
|
||||||
*
|
*
|
||||||
@ -66,7 +124,12 @@ void PreProcessData() { using namespace Client; }
|
|||||||
*/
|
*/
|
||||||
std::pair<int, int> GenerateNextStep() {
|
std::pair<int, int> GenerateNextStep() {
|
||||||
using namespace Client;
|
using namespace Client;
|
||||||
return std::make_pair(0, 0);
|
if (!no_mine_block_to_be_clicked.empty()) {
|
||||||
|
std::pair<int, int> next_step = no_mine_block_to_be_clicked.front();
|
||||||
|
no_mine_block_to_be_clicked.pop();
|
||||||
|
return next_step;
|
||||||
|
} else
|
||||||
|
return MakeBestGuess();
|
||||||
}
|
}
|
||||||
} // namespace Client
|
} // namespace Client
|
||||||
void ReadMap() {
|
void ReadMap() {
|
||||||
|
Reference in New Issue
Block a user