87 lines
1.5 KiB
C++
87 lines
1.5 KiB
C++
#include <cassert>
|
|
#include <algorithm>
|
|
#include <random>
|
|
#include "Game.h"
|
|
|
|
using std::vector;
|
|
|
|
GameState::GameState(int n) : n(n), cp(0), win(-1), B(n, vector<int>(n)) {
|
|
C[0].resize(n);
|
|
C[1].resize(n);
|
|
assert(n % 2 == 1);
|
|
}
|
|
|
|
bool GameState::_checkEnd() const {
|
|
int v = 0;
|
|
for (int i = 0; i < n; ++i) {
|
|
if (C[cp][i] >= (n + 1) / 2)
|
|
v += 1;
|
|
}
|
|
return v >= (n + 1) / 2;
|
|
}
|
|
|
|
bool GameState::move(int x, int y) {
|
|
if (x < 0 || x >= n || y < 0 || y >= n) {
|
|
return false;
|
|
}
|
|
|
|
if (B[x][y] == -1) {
|
|
return false;
|
|
}
|
|
|
|
const int dx[] = {0, 0, 1, -1};
|
|
const int dy[] = {1, -1, 0, 0};
|
|
for (int i = 0; i < 4; ++i) {
|
|
int xx = x + dx[i], yy = y + dy[i];
|
|
if (xx < 0 || xx >= n || yy < 0 || yy >= n || B[xx][yy] == -1)
|
|
goto OK;
|
|
}
|
|
return false;
|
|
|
|
OK:
|
|
C[cp][B[x][y]] += 1;
|
|
if (C[cp][B[x][y]] >= (n + 1) / 2) {
|
|
int t = B[x][y];
|
|
for (int i = 0; i < n; ++i) {
|
|
for (int j = 0; j < n; ++j) {
|
|
if (B[i][j] == t)
|
|
B[i][j] = -1;
|
|
}
|
|
}
|
|
if (_checkEnd())
|
|
win = cp;
|
|
}
|
|
|
|
B[x][y] = -1;
|
|
cp ^= 1;
|
|
return true;
|
|
}
|
|
|
|
void GameState::randomBoard() {
|
|
using namespace std;
|
|
vector<int> z;
|
|
mt19937 rng(random_device{}());
|
|
for (int i = 0; i < n; ++i) {
|
|
for (int j = 0; j < n; ++j)
|
|
z.push_back(i);
|
|
}
|
|
|
|
shuffle(z.begin(), z.end(), rng);
|
|
for (int i = 0; i < n; ++i) {
|
|
for (int j = 0; j < n; ++j)
|
|
B[i][j] = z[i * n + j];
|
|
}
|
|
}
|
|
|
|
std::string GameState::boardString() const {
|
|
std::string res;
|
|
for (int i = 0; i < n; ++i) {
|
|
for (int j = 0; j < n; ++j) {
|
|
res += std::to_string(B[i][j]);
|
|
res += " \n"[j == n - 1];
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|