finish writing
This commit is contained in:
@ -13,6 +13,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "dataload.h"
|
||||
|
||||
extern int rows; // The count of rows of the game map
|
||||
extern int columns; // The count of columns of the game map
|
||||
|
||||
@ -38,6 +40,7 @@ void Execute(int row, int column);
|
||||
* map and the first step taken by the server (see README).
|
||||
*/
|
||||
void InitGame() {
|
||||
LoadData();
|
||||
int first_row, first_column;
|
||||
std::cin >> first_row >> first_column;
|
||||
Execute(first_row, first_column);
|
||||
@ -493,6 +496,137 @@ std::pair<int, int> SimpleGuess() {
|
||||
}
|
||||
return best_guess;
|
||||
}
|
||||
double EstimateProb(std::pair<int, int> pos, double default_p = 0.06) {
|
||||
if (pos.first == 0 || pos.first == rows - 1 || pos.second == 0 ||
|
||||
pos.second == columns - 1)
|
||||
return default_p;
|
||||
std::vector<double> ps;
|
||||
double res = 0;
|
||||
typedef long long LL;
|
||||
const LL raw_line_base = 243;
|
||||
const LL vis_line_base = 100000;
|
||||
int rid[15] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
|
||||
int cid[15] = {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4};
|
||||
if (pos.second + 3 <= columns - 1) {
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int x = pos.first + rid[i] - 1, y = pos.second + cid[i] - 1;
|
||||
if (map_status[x][y] != 2)
|
||||
visible_status = (visible_status * 10) + 9;
|
||||
else if (map_status[x][y] == 2)
|
||||
visible_status = (visible_status * 10) + game_map[x][y] - '0';
|
||||
}
|
||||
LL invers_vis_status =
|
||||
(visible_status % vis_line_base) * vis_line_base * vis_line_base +
|
||||
((visible_status / vis_line_base) % vis_line_base) * vis_line_base +
|
||||
visible_status / (vis_line_base * vis_line_base);
|
||||
if (DataLoad::visible_to_probability.find(visible_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[visible_status] / 255.0);
|
||||
if (DataLoad::visible_to_probability.find(invers_vis_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[invers_vis_status] / 255.0);
|
||||
}
|
||||
if (pos.second - 3 >= 0) {
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int x = pos.first + rid[i] - 1, y = pos.second - (cid[i] - 1);
|
||||
if (map_status[x][y] != 2)
|
||||
visible_status = (visible_status * 10) + 9;
|
||||
else if (map_status[x][y] == 2)
|
||||
visible_status = (visible_status * 10) + game_map[x][y] - '0';
|
||||
}
|
||||
LL invers_vis_status =
|
||||
(visible_status % vis_line_base) * vis_line_base * vis_line_base +
|
||||
((visible_status / vis_line_base) % vis_line_base) * vis_line_base +
|
||||
visible_status / (vis_line_base * vis_line_base);
|
||||
if (DataLoad::visible_to_probability.find(visible_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[visible_status] / 255.0);
|
||||
if (DataLoad::visible_to_probability.find(invers_vis_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[invers_vis_status] / 255.0);
|
||||
}
|
||||
if (pos.first + 3 <= rows - 1) {
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int x = pos.first + cid[i] - 1, y = pos.second + rid[i] - 1;
|
||||
if (map_status[x][y] != 2)
|
||||
visible_status = (visible_status * 10) + 9;
|
||||
else if (map_status[x][y] == 2)
|
||||
visible_status = (visible_status * 10) + game_map[x][y] - '0';
|
||||
}
|
||||
LL invers_vis_status =
|
||||
(visible_status % vis_line_base) * vis_line_base * vis_line_base +
|
||||
((visible_status / vis_line_base) % vis_line_base) * vis_line_base +
|
||||
visible_status / (vis_line_base * vis_line_base);
|
||||
if (DataLoad::visible_to_probability.find(visible_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[visible_status] / 255.0);
|
||||
if (DataLoad::visible_to_probability.find(invers_vis_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[invers_vis_status] / 255.0);
|
||||
}
|
||||
if (pos.first - 3 >= 0) {
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int x = pos.first - (cid[i] - 1), y = pos.second + rid[i] - 1;
|
||||
if (map_status[x][y] != 2)
|
||||
visible_status = (visible_status * 10) + 9;
|
||||
else if (map_status[x][y] == 2)
|
||||
visible_status = (visible_status * 10) + game_map[x][y] - '0';
|
||||
}
|
||||
LL invers_vis_status =
|
||||
(visible_status % vis_line_base) * vis_line_base * vis_line_base +
|
||||
((visible_status / vis_line_base) % vis_line_base) * vis_line_base +
|
||||
visible_status / (vis_line_base * vis_line_base);
|
||||
if (DataLoad::visible_to_probability.find(visible_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[visible_status] / 255.0);
|
||||
if (DataLoad::visible_to_probability.find(invers_vis_status) !=
|
||||
DataLoad::visible_to_probability.end())
|
||||
ps.push_back(DataLoad::visible_to_probability[invers_vis_status] / 255.0);
|
||||
}
|
||||
for (int i = 0; i < ps.size(); i++) res += ps[i] * ps[i];
|
||||
return sqrt(res / ps.size());
|
||||
}
|
||||
/**
|
||||
* @brief The definition of function GreedyGuess()
|
||||
*
|
||||
* @details This function is designed to make a guess when there is no definite
|
||||
*/
|
||||
std::pair<int, int> GreedyGuess() {
|
||||
double default_probability = 0.06;
|
||||
int total_known = 0, total_known_with_mine = 0;
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = 0; j < columns; j++)
|
||||
if (map_status[i][j] != 0) {
|
||||
total_known++;
|
||||
if (map_status[i][j] == -1) total_known_with_mine++;
|
||||
}
|
||||
if (total_known > 5)
|
||||
default_probability = (double)(total_known_with_mine) / (total_known);
|
||||
std::pair<int, int> res;
|
||||
bool is_first = true;
|
||||
double res_prob = 1;
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = 0; j < columns; j++)
|
||||
if (map_status[i][j] == 0) {
|
||||
if (is_first) {
|
||||
is_first = false;
|
||||
res = std::make_pair(i, j);
|
||||
double res_prob = EstimateProb(res, default_probability);
|
||||
continue;
|
||||
}
|
||||
double this_prob =
|
||||
EstimateProb(std::make_pair(i, j), default_probability);
|
||||
if (this_prob < res_prob) {
|
||||
res = std::make_pair(i, j);
|
||||
res_prob = this_prob;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* @brief The definition of function MakeBestGuess()
|
||||
*
|
||||
|
1
src/include/data.h
Normal file
1
src/include/data.h
Normal file
File diff suppressed because one or more lines are too long
64
src/include/dataload.h
Normal file
64
src/include/dataload.h
Normal file
@ -0,0 +1,64 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "data.h"
|
||||
#include "zb64.h"
|
||||
namespace DataLoad {
|
||||
typedef long long LL;
|
||||
const int buf_size = 4412555 * 4;
|
||||
unsigned char buf[buf_size], data[buf_size];
|
||||
bool already_have[14348907];
|
||||
std::unordered_map<LL,unsigned char> visible_to_probability;
|
||||
int rid[15] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
|
||||
int cid[15] = {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4};
|
||||
} // namespace DataLoad
|
||||
void LoadData() {
|
||||
using namespace DataLoad;
|
||||
size_t raw_length = base64_decode(pre_calc_prob, buf, buf_size);
|
||||
size_t data_length = decompressData(buf, raw_length, data, buf_size);
|
||||
// std::cout<<"decompress finished.\n"<<std::endl;
|
||||
// already_have.rehash(4412555);
|
||||
visible_to_probability.rehash(4412555);
|
||||
const LL raw_line_base = 243;
|
||||
const LL vis_line_base = 100000;
|
||||
int cnt=0;
|
||||
for (int status = 0; status < 14348907; status++) {
|
||||
LL inverse_status =
|
||||
(status % raw_line_base) * raw_line_base * raw_line_base +
|
||||
((status / raw_line_base) % raw_line_base) * raw_line_base +
|
||||
(status / (raw_line_base * raw_line_base));
|
||||
if (already_have[inverse_status]) continue;
|
||||
// assert(already_have.find(status) == already_have.end());
|
||||
already_have[status]=true;
|
||||
int inner_mp[3][5] = {0}, visible_map[3][5];
|
||||
LL status_tmp = status;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int row = rid[i], col = cid[i];
|
||||
inner_mp[row][col] = (status_tmp % 3); // uncode the inner_status
|
||||
status_tmp /= 3;
|
||||
}
|
||||
for (int row = 0; row < 3; row++)
|
||||
for (int col = 0; col < 5; col++) {
|
||||
if (inner_mp[row][col] == 0 || inner_mp[row][col] == 1) {
|
||||
visible_map[row][col] = 9; // 9 means unshown to player
|
||||
} else {
|
||||
int mcnt = 0;
|
||||
const int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1},
|
||||
dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int nr = row + dx[i], nc = col + dy[i];
|
||||
if (nr < 0 || nr >= 3 || nc < 0 || nc >= 5) continue;
|
||||
mcnt += (inner_mp[nr][nc] == 0 ? 1 : 0);
|
||||
}
|
||||
visible_map[row][col] = mcnt;
|
||||
}
|
||||
}
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int row = rid[i], col = cid[i];
|
||||
visible_status = visible_status * 10 + visible_map[row][col];
|
||||
}
|
||||
visible_to_probability[visible_status] = data[cnt++];
|
||||
}
|
||||
// std::cout<<"Load data finished.\n"<<std::endl;
|
||||
}
|
@ -24,9 +24,9 @@ unordered_map<LL, LL> inner_to_visible;
|
||||
vector<LL> valid_visible_status;
|
||||
unordered_map<LL, double> visible_to_probability;
|
||||
unordered_set<LL> already_have;
|
||||
const LL raw_line_base = 243;
|
||||
const LL vis_line_base = 100000;
|
||||
void FindStatus() {
|
||||
const LL raw_line_base = 243;
|
||||
const LL vis_line_base = 100000;
|
||||
for (int status = 0; status < 14348907; status++) {
|
||||
int inner_mp[3][5] = {0}, visible_map[3][5];
|
||||
LL status_tmp = status;
|
||||
|
Reference in New Issue
Block a user