Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "morpion.hpp"
#include <sstream>
using namespace std;
namespace game
{
static vector<vector<uint64_t>> create_hash_values()
{
default_random_engine generator;
uniform_int_distribution<uint64_t> distribution;
vector<vector<uint64_t>> res(7, vector<uint64_t>(6, 0));
for (int i = 0; i < 7; ++i)
{
for (int j = 0; j < 6; ++j)
{
res[i][j] = distribution(generator);
}
}
return res;
}
vector<vector<uint64_t>> morpion::cross_hash_values = create_hash_values();
vector<vector<uint64_t>> morpion::circle_hash_values = create_hash_values();
morpion::morpion()
{
}
shared_ptr<game<morpion_state>> morpion::do_copy() const
{
return shared_ptr<morpion>(new morpion(*this));
}
morpion_state morpion::get_state()
{
return state;
}
void morpion::set_state(const morpion_state& s)
{
state = s;
}
bool morpion::end_of_game() const
{
return state.first_player_win || state.second_player_win || state.total_moves == 9;
}
bool morpion::won(std::uint8_t player) const
{
if (player == CROSS) return state.first_player_win;
return state.second_player_win;
}
bool morpion::lost(std::uint8_t player) const
{
if (player == CIRCLE) return state.first_player_win;
return state.second_player_win;
}
bool morpion::draw(std::uint8_t player) const
{
if (state.first_player_win || state.second_player_win) return false;
return state.total_moves == 9;
}
uint8_t morpion::current_player() const
{
return state.total_moves & 1 ? CIRCLE : CROSS; // CROSS even, CIRCLE odd
int morpion::value(uint8_t player) const
{
return state.first_player_win? 1 : (state.second_player_win? -1 : 0);
return state.second_player_win? 1 : (state.first_player_win? -1 : 0);
return 0;
}
uint16_t morpion::number_of_moves() const
{
bool morpion::get(uint16_t bitboard, uint8_t col, uint8_t row) const
}
//#define set(bitboard, col, row) (bitboard |= (1LL << (((col) << 3) + (row))))
void morpion::update_win()
{
if(has_won(state.cross_bitboard))
state.first_player_win = true;
else if(has_won(state.circle_bitboard))
state.second_player_win = true;
if(((bitboard | ROW0_MASK) == ALL_ONES) || ((bitboard | ROW1_MASK) == ALL_ONES) || ((bitboard | ROW2_MASK) == ALL_ONES)) // Check horizontal ---
if(((bitboard | COL0_MASK) == ALL_ONES) || ((bitboard | COL1_MASK) == ALL_ONES) || ((bitboard | COL2_MASK) == ALL_ONES)) // Check vertical |
if(((bitboard | DIA0_MASK) == ALL_ONES) || ((bitboard | DIA1_MASK) == ALL_ONES)) // Chack diagonal \ /
return false;
}
uint16_t free_bitboard = ~(state.cross_bitboard | state.circle_bitboard);
for(int i = 0; i <=8; i++)
{
if(free_bitboard & 1)
{
state.possible_moves += i;
state.possible_moves = state.possible_moves << 4;
}
free_bitboard = free_bitboard >> 1;
}
//State update
state.total_moves++;
update_win();
update_moves();
/**
* player_to_string
* Retourne X si le joueur joue les croix, O s'il joue les ronds,
* et un espace sinon.
*/
string morpion::player_to_string(uint8_t player) const
{
return player == CROSS ? "X" : (player == CIRCLE ? "O" : " ");
string morpion::move_to_string(uint16_t m) const
{
uint8_t row = m/3;
uint8_t col = m%3;
return "( "+std::to_string(row)+", "+std::to_string(col)+" )";
}
set<int> morpion::to_input_vector() const
{
return set<int>();
}
void morpion::from_input_vector(const std::set<int>& input)
{
}
string morpion::to_string() const
{
string result = "";
for (int row = 2; row >= 0; row--)
{
if(((state.cross_bitboard >> (3*row)) >> col) & 1)
else if (((state.circle_bitboard >> (3*row)) >> col) & 1)
result += player_to_string(CIRCLE)+"|";
else
result += " |";
}
result += "\n-------\n";
}
return result;
}
void morpion::playout(mt19937& engine, int max_depth)
{
while (!end_of_game())
{
uniform_int_distribution<uint16_t> distribution(0, 8-state.total_moves);
uint16_t move = distribution(engine);
uint16_t position = (state.possible_moves >> 4*move) & 15; //15 is the mask to get only one move
play(position);
}
}
std::uint64_t morpion::hash() const
{
//TODO: Implement
return 0;
}
std::uint64_t morpion::hash(std::uint16_t m) const
{
//TODO: Implement
return 0;
}
ostream& operator<<(ostream& os, const morpion& mor)
{
os << mor.to_string() << endl;
return os;
}
}