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 || bitboard == ROW1_MASK || bitboard == ROW2_MASK) // Check vertical |
if(bitboard == COL0_MASK || bitboard == COL1_MASK || bitboard == COL2_MASK) // Check horizontal _
if(bitboard == DIA0_MASK || bitboard == DIA1_MASK) // Chack diagonal \ /
return false;
}
void morpion::update_moves(uint16_t move)
{
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 << 4;
}
free_bitboard = free_bitboard >> 1;
}
uint16_t position = (state.possible_moves >> 4*m) & 15; //15 is the mask to get only one move
if (current_player() == CROSS)
state.cross_bitboard += 1 << position;
else
state.circle_bitboard += 1 << position;
//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
{
//TODO PAR ROMAIN
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
}
void morpion::playout(mt19937& engine, int max_depth)
{
while (!end_of_game())
{
uniform_int_distribution<uint16_t> distribution(0, number_of_moves() - 1);
uint16_t move = distribution(engine);
play(move);
}
}
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;
}
}