diff --git a/AI/src/game/connect4.cpp b/AI/src/game/connect4.cpp deleted file mode 100644 index c4d05c85e6b0ce05879becd5c38048ca8a843f94..0000000000000000000000000000000000000000 --- a/AI/src/game/connect4.cpp +++ /dev/null @@ -1,363 +0,0 @@ -#include "connect4.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>> connect4::cross_hash_values = create_hash_values(); - vector<vector<uint64_t>> connect4::circle_hash_values = create_hash_values(); - - connect4::connect4() - { - } - - shared_ptr<game<connect4_state>> connect4::do_copy() const - { - return shared_ptr<connect4>(new connect4(*this)); - } - - connect4_state connect4::get_state() - { - return state; - } - - void connect4::set_state(const connect4_state& s) - { - state = s; - } - - bool connect4::end_of_game() const - { - return state.first_player_win || state.second_player_win || state.total_moves == 42; - } - - bool connect4::won(std::uint8_t player) const - { - if (player == 0) return state.first_player_win; - return state.second_player_win; - } - - bool connect4::lost(std::uint8_t player) const - { - if (player == 0) return state.second_player_win; - return state.first_player_win; - } - - bool connect4::draw(std::uint8_t player) const - { - if (state.first_player_win || state.second_player_win) return false; - return state.total_moves == 42; - } - - uint8_t connect4::current_player() const - { - return state.total_moves & 1 ? CIRCLE : CROSS; - } - - // uint8_t connect4::current_player_representation() const - // { - // return state.total_moves & 1 ? CIRCLE_REPRESENTATION : CROSS_REPRESENTATION; - // } - - // uint8_t connect4::player_representation_to_player(uint8_t player) const - // { - // return player == CIRCLE_REPRESENTATION ? CIRCLE : (player == CROSS_REPRESENTATION ? CROSS : -1); - // } - - int connect4::value(uint8_t player) const - { - if (player == CROSS) - { - return state.first_player_win ? 1 : (state.second_player_win ? -1 : 0); - } - else if (player == CIRCLE) - { - return state.second_player_win ? 1 : (state.first_player_win ? -1 : 0); - } - return 0; - } - - uint16_t connect4::number_of_moves() const - { - return state.nb_moves; - } - - bool connect4::get(uint64_t bitboard, uint8_t col, uint8_t row) const - { - return bitboard & (1LL << ((col << 3) + row)); - //return (state.board[i] >> (j << 1)) & 3; - } - -#define set(bitboard, col, row) (bitboard |= (1LL << (((col) << 3) + (row)))) - - // bool connect4::vertical(uint8_t position, uint8_t free, uint8_t player) const - // { - // return free >= 3 && get(position, free - 1) == player && get(position, free - 2) == player && get(position, free - 3) == player; - // } - - // bool connect4::horizontal(uint8_t position, uint8_t free, uint8_t player) const - // { - // uint8_t sum = 0; - // if (position >= 1 && get(position - 1, free) == player) - // { - // ++sum; - // if (position >= 2 && get(position - 2, free) == player) - // { - // ++sum; - // if (position >= 3 && get(position - 3, free) == player) ++sum; - // } - // } - // if (position <= 5 && get(position + 1, free) == player) - // { - // ++sum; - // if (position <= 4 && get(position + 2, free) == player) - // { - // ++sum; - // if (position <= 3 && get(position + 3, free) == player) ++sum; - // } - // } - // return sum >= 3; - // } - - // bool connect4::diagonal(uint8_t position, uint8_t free, uint8_t player) const - // { - // uint8_t sum = 0; - // if (position >= 1 && free <= 4 && get(position - 1, free + 1) == player) - // { - // ++sum; - // if (position >= 2 && free <= 3 && get(position - 2, free + 2) == player) - // { - // ++sum; - // if (position >= 3 && free <= 2 && get(position - 3, free + 3) == player) ++sum; - // } - // } - // if (position <= 5 && free >= 1 && get(position + 1, free - 1) == player) - // { - // ++sum; - // if (position <= 4 && free >= 2 && get(position + 2, free - 2) == player) - // { - // ++sum; - // if (position <= 3 && free >= 3 && get(position + 3, free - 3) == player) ++sum; - // } - // } - // return sum >= 3; - // } - - // bool connect4::other_diagonal(uint8_t position, uint8_t free, uint8_t player) const - // { - // uint8_t sum = 0; - // if (position >= 1 && free >= 1 && get(position - 1, free - 1) == player) - // { - // ++sum; - // if (position >= 2 && free >= 2 && get(position - 2, free - 2) == player) - // { - // ++sum; - // if (position >= 3 && free >= 3 && get(position - 3, free - 3) == player) ++sum; - // } - // } - // if (position <= 5 && free <= 4 && get(position + 1, free + 1) == player) - // { - // ++sum; - // if (position <= 4 && free <= 3 && get(position + 2, free + 2) == player) - // { - // ++sum; - // if (position <= 3 && free <= 2 && get(position + 3, free + 3) == player) ++sum; - // } - // } - // return sum >= 3; - // } - - // void connect4::update_win(uint8_t position, uint8_t free) - // { - // uint8_t player = current_player_representation(); - // bool win = - // vertical(position, free, player) - // || - // horizontal(position, free, player) - // || - // diagonal(position, free, player) - // || - // other_diagonal(position, free, player); - // if (win) - // { - // if (player == CROSS_REPRESENTATION) state.first_player_win = true; - // else state.second_player_win = true; - // } - // } - - void connect4::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; - } - - bool connect4::has_won(uint64_t bitboard) - { - int64_t y = bitboard & (bitboard >> 7); - if (y & (y >> 2 * 7)) // check \ diagonal - return true; - y = bitboard & (bitboard >> 8); - if (y & (y >> 2 * 8)) // check horizontal - - return true; - y = bitboard & (bitboard >> 9); - if (y & (y >> 2 * 9)) // check / diagonal - return true; - y = bitboard & (bitboard >> 1); - if (y & (y >> 2)) // check vertical | - return true; - return false; - } - - void connect4::update_moves(uint16_t move) - { - --state.nb_moves; - uint32_t prefix = state.moves >> ((move + 1) * 3); - uint8_t shift = 32 - move * 3; - state.moves = (uint32_t)((uint64_t)state.moves << shift) >> shift; - state.moves |= prefix << (move * 3); - } - - void connect4::play(uint16_t m) - { - uint8_t position = ((state.moves >> (m * 3)) & 7); - uint8_t p = position * 3; - uint8_t f = (state.free >> p) & 7; - // state.hash_value ^= current_player() == CIRCLE ? circle_hash_values[position][f] : cross_hash_values[position][f]; - // state.board[position] |= current_player_representation() << (f << 1); - if (current_player() == CROSS) - { - set(state.cross_bitboard, position, f); - } - else - { - set(state.circle_bitboard, position, f); - } - update_win(); - ++f; - state.free = (state.free & ~(((uint32_t)7) << p)) | (f << p); - if (f == 6) - { - update_moves(m); - } - ++state.total_moves; - } - - string connect4::player_to_string(uint8_t player) const - { - return player == CROSS ? "X" : (player == CIRCLE ? "O" : " "); - } - - string connect4::move_to_string(uint16_t m) const - { - uint8_t position = ((state.moves >> (m * 3)) & 7); - return std::to_string(position); - } - - set<int> connect4::to_input_vector() const - { - set<int> res; - int k = 0; - if (current_player()) res.insert(k++); - for (int col = 0; col < 7; ++col) - { - for (int row = 0; row < 6; ++row) - { - if (get(state.cross_bitboard, col, row)) res.insert(k++); - } - } - for (int col = 0; col < 7; ++col) - { - for (int row = 0; row < 6; ++row) - { - if (get(state.circle_bitboard, col, row)) res.insert(k++); - } - } - return res; - } - - void connect4::from_input_vector(const std::set<int>& input) - { - state = connect4_state(); - for (int index : input) - { - if (index == 1) continue; - if (index <= 43) - { - index -= 2; - state.cross_bitboard |= 1LL << (index + (index / 6) * 2); - } - else - { - index -= 44; - state.circle_bitboard |= 1LL << (index + (index / 6) * 2); - } - state.total_moves += 1; - } - } - - string connect4::to_string() const - { - stringbuf buffer; - ostream os(&buffer); - for (int y = 5; y >= 0; --y) - { - for (int k = 0; k < 7; ++k) os << "+-"; - os << "+" << endl; - for (int x = 0; x < 7; ++x) - { - os << "|" << (get(state.cross_bitboard, x, y) ? player_to_string(CROSS) : (get(state.circle_bitboard, x, y) ? player_to_string(CIRCLE) : " ")); - } - os << "|" << endl; - } - for (int k = 0; k < 7; ++k) os << "+-"; - os << "+" << endl; - for (int k = 0; k < 7; ++k) os << " " << k; - os << endl; - return buffer.str(); - } - - // void connect4::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 connect4::hash() const - { - return state.hash_value; - } - - std::uint64_t connect4::hash(std::uint16_t m) const - { - uint8_t position = ((state.moves >> (m * 3)) & 7); - uint8_t p = position * 3; - uint8_t f = (state.free >> p) & 7; - return state.hash_value ^ (current_player() == CIRCLE ? circle_hash_values[position][f] : cross_hash_values[position][f]); - } - - ostream& operator<<(ostream& os, const connect4& c4) - { - os << c4.to_string() << endl; - return os; - } -} diff --git a/AI/src/game/connect4.hpp b/AI/src/game/connect4.hpp deleted file mode 100644 index 1ea92aedf328a7fb13d090f7dd9c39a54a7f8183..0000000000000000000000000000000000000000 --- a/AI/src/game/connect4.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef __CONNECT4_HPP__ -#define __CONNECT4_HPP__ - -#include "game.hpp" -#include <random> -#include <array> -#include <iostream> -#include <memory> - -namespace game -{ - - struct connect4_state - { - uint64_t cross_bitboard = 0; - uint64_t circle_bitboard = 0; - // std::array<uint16_t, 7> board{}; - std::uint32_t moves = 0x1AC688; - std::uint32_t free = 0; - uint64_t hash_value = 0; - std::uint16_t nb_moves = 7; - uint8_t total_moves = 0; - bool first_player_win = false; - bool second_player_win = false; - }; - - class connect4 : public game<connect4_state> - { - public: - connect4(); - connect4(const connect4& c4) = default; - connect4& operator=(const connect4& c4) = default; - bool end_of_game() const; - int value(std::uint8_t player) const; - bool won(std::uint8_t player) const; - bool lost(std::uint8_t player) const; - bool draw(std::uint8_t player) const; - uint8_t current_player() const; - std::uint16_t number_of_moves() const; - void play(std::uint16_t m); - void undo(std::uint16_t m) {} - std::string player_to_string(std::uint8_t player) const; - std::string move_to_string(std::uint16_t m) const; - std::string to_string() const; - // void playout(std::mt19937& engine, int max_depth = -1); - std::set<int> to_input_vector() const; - void from_input_vector(const std::set<int>& input); - connect4_state get_state(); - void set_state(const connect4_state& state); - std::shared_ptr<game<connect4_state>> do_copy() const; - std::uint64_t hash(std::uint16_t m) const; - std::uint64_t hash() const; - - private: - inline void update_win(); - inline bool has_won(uint64_t bitboard); - inline void update_moves(uint16_t move); - inline bool get(uint64_t bitboard, uint8_t i, uint8_t j) const; - // inline bool vertical(uint8_t position, uint8_t free, uint8_t player) const; - // inline bool horizontal(uint8_t position, uint8_t free, uint8_t player) const; - // inline bool diagonal(uint8_t position, uint8_t free, uint8_t player) const; - // inline bool other_diagonal(uint8_t position, uint8_t free, uint8_t player) const; - // inline uint8_t current_player_representation() const; - // inline uint8_t player_representation_to_player(uint8_t player) const; - - const uint8_t CROSS = 0; - const uint8_t CIRCLE = 1; - // const uint8_t CROSS_REPRESENTATION = 1; - // const uint8_t CIRCLE_REPRESENTATION = 2; - - connect4_state state; - - static std::vector<std::vector<uint64_t>> cross_hash_values; - static std::vector<std::vector<uint64_t>> circle_hash_values; - }; - std::ostream& operator<<(std::ostream& os, const connect4& c4); -} - -#endif diff --git a/AI/src/game/morpion.cpp b/AI/src/game/morpion.cpp deleted file mode 100644 index 4662a6fc0689030159e852f4941b588ae13d64ea..0000000000000000000000000000000000000000 --- a/AI/src/game/morpion.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#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 - { - if (player == CROSS) { - return state.first_player_win ? 1 : (state.second_player_win ? -1 : 0); - } - else if (player == CIRCLE) { - return state.second_player_win ? 1 : (state.first_player_win ? -1 : 0); - } - return 0; - } - - /* Number of moves that you can play */ - uint16_t morpion::number_of_moves() const - { - return 9 - state.total_moves; - } - - uint16_t morpion::number_moves_played() const - { - return state.total_moves; - } - - bool morpion::get(uint16_t bitboard, uint8_t col, uint8_t row) const - { - return bitboard & (1LL << (3*row)) << col; - } - -//#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; - } - - bool morpion::has_won(uint16_t bitboard) - { - if(((bitboard | ROW0_MASK) == ALL_ONES) || ((bitboard | ROW1_MASK) == ALL_ONES) || ((bitboard | ROW2_MASK) == ALL_ONES)) // Check horizontal --- - return true; - if(((bitboard | COL0_MASK) == ALL_ONES) || ((bitboard | COL1_MASK) == ALL_ONES) || ((bitboard | COL2_MASK) == ALL_ONES)) // Check vertical | - return true; - if(((bitboard | DIA0_MASK) == ALL_ONES) || ((bitboard | DIA1_MASK) == ALL_ONES)) // Chack diagonal \ / - return true; - return false; - } - - - void morpion::update_moves() - { - uint16_t free_bitboard = ~(state.cross_bitboard | state.circle_bitboard); - //free_bitboard &= ALL_ONES; //When we complements, all unused bits in uint_16 are complemented to. ALL_ONES is a mask in which we have ones in the position used by the bitboard - //cout << "Free bitboard: " << (free_bitboard & ALL_ONES) << endl; - state.possible_moves = 0; - uint16_t mask = 256; //256 = 100 000 000 - for(int i = 8; i >=0; i--) - { - if(free_bitboard & mask) - { - state.possible_moves = state.possible_moves << 4; - state.possible_moves |= i; - } - mask = mask >> 1; - } - //cout << "Possible moves: " << state.possible_moves << endl; - } - - //Play the mth move in the possible moves list. - void morpion::play(uint16_t m) - { - uint64_t possible_moves = state.possible_moves; - possible_moves = possible_moves >> 4*m; //A move is coded with 4 bit - uint16_t move = possible_moves & 15; //15 = 1111 - //cout << "You choose the possible move number " << m << endl; - //cout << "You choose move " << move << endl; - if (current_player() == CROSS) - state.cross_bitboard |= (((uint16_t) 1) << move); - else - state.circle_bitboard |= (((uint16_t) 1) << move); - - //State update - state.total_moves++; - update_win(); - update_moves(); - return; - } - - - /** - * 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 - { - return std::to_string((state.possible_moves >> (4 * m)) & 0xf); - } - - 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 = "-------\n"; - for (int row = 2; row >= 0; row--) - { - result += "|"; - for (int col = 2; col >= 0; col--) - { - if(((state.cross_bitboard >> (3*row)) >> col) & 1) - result += player_to_string(CROSS)+"|"; - else if (((state.circle_bitboard >> (3*row)) >> col) & 1) - result += player_to_string(CIRCLE)+"|"; - else - result += std::to_string(row * 3 + col) + "|"; - } - result += "\n-------\n"; - } - return result; - } - - 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; - } -} diff --git a/AI/src/game/morpion.hpp b/AI/src/game/morpion.hpp deleted file mode 100644 index e210f5e5a419df9b26f084415ac58e454ddea600..0000000000000000000000000000000000000000 --- a/AI/src/game/morpion.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __MORPION_HPP__ -#define __MORPION_HPP__ - -#include "game.hpp" -#include <random> -#include <array> -#include <iostream> -#include <memory> - -namespace game -{ - struct morpion_state - { - uint16_t cross_bitboard = 0; //bitboard with the played moves of the cross - uint16_t circle_bitboard = 0; //bitboard with the played moves of the circle - uint8_t total_moves = 0; //Total played moves (<= 9) - uint64_t possible_moves = 0x876543210; //List of possible moves left - bool first_player_win = false; //First player is always the cross - bool second_player_win = false; //Second player is always the circle - }; - - class morpion : public game<morpion_state> - { - public: - morpion(); - morpion(const morpion& mor) = default; - morpion& operator=(const morpion& mor) = default; - bool end_of_game() const; //Is the game ended? (draw or won) - int value(std::uint8_t player) const; //Returns if the player win, loose or nothing - bool won(std::uint8_t player) const; - bool lost(std::uint8_t player) const; - bool draw(std::uint8_t player) const; - uint8_t current_player() const; //The player that has to play next (at the beginning, the first player) - std::uint16_t number_of_moves() const; //Number of moves that you can play - std::uint16_t number_moves_played() const; //Number of moves played until now - void play(std::uint16_t m); //Play the move m (updates the state). m is the position on the board of where you want to play - void undo(std::uint16_t m) {} - std::string player_to_string(std::uint8_t player) const; //String representation of a player - std::string move_to_string(std::uint16_t m) const; //String representation of a move (for example, A1) - std::string to_string() const; //String representation of the entire game - std::set<int> to_input_vector() const; - void from_input_vector(const std::set<int>& input); - morpion_state get_state(); //Return the state - void set_state(const morpion_state& state); //Replace the current state with the one passed as a parameter - std::shared_ptr<game<morpion_state>> do_copy() const; - std::uint64_t hash(std::uint16_t m) const; - std::uint64_t hash() const; - - private: - inline void update_win(); //Check if someone won and update the state - inline bool has_won(uint16_t bitboard); //Check if the player whose bitboard was passed as a param has won - inline bool get(uint16_t bitboard, uint8_t i, uint8_t j) const; //Get a case of the board - inline void update_moves(); //Update the list of all possible moves - - const uint8_t CROSS = 0; - const uint8_t CIRCLE = 1; - - morpion_state state; - - //WIN CONSTANTS - const uint16_t ROW0_MASK = 504; - const uint16_t ROW1_MASK = 455; - const uint16_t ROW2_MASK = 63; - const uint16_t COL0_MASK = 438; - const uint16_t COL1_MASK = 365; - const uint16_t COL2_MASK = 219; - const uint16_t DIA0_MASK = 238; - const uint16_t DIA1_MASK = 427; - const uint16_t ALL_ONES = 511; - - static std::vector<std::vector<uint64_t>> cross_hash_values; - static std::vector<std::vector<uint64_t>> circle_hash_values; - }; - std::ostream& operator<<(std::ostream& os, const morpion& mor); -} - -#endif diff --git a/AI/src/game/test_connect4.cpp b/AI/src/game/test_connect4.cpp deleted file mode 100644 index 4269f324270374010b23011dd3450e2c899f543b..0000000000000000000000000000000000000000 --- a/AI/src/game/test_connect4.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "connect4.hpp" -#include "test_connect4.hpp" -#include <iostream> -#include <map> - -using namespace std; - -namespace game -{ - test_connect4::test_connect4() - { - playout(); - play(); - } - - void test_connect4::playout() - { - mt19937 mt; - connect4 c4; - cout << "playout" << endl; - for (int i = 0; i < 100; ++i) - { - uint8_t player = c4.current_player(); - auto state = c4.get_state(); - c4.playout(mt); - cout << "value: " << c4.value(player) << endl << c4 << endl; - c4.set_state(state); - string wait; - getline(cin, wait); - } - } - - void test_connect4::play() - { - connect4 c4; - int player = 0; - cout << "play one game" << endl; - while (!c4.end_of_game()) - { - cout << c4 << endl; - cout << c4.player_to_string(player) << " move: "; - map<string, int> m; - for (int i = 0; i < c4.number_of_moves(); ++i) - { - m[c4.move_to_string(i)] = i; - } - string move; - cin >> move; - c4.play(m[move]); - player = 1 - player; - } - cout << c4 << endl; - if (c4.value(0) == 1) cout << c4.player_to_string(0) << " won"; - else if (c4.value(1) == 1) cout << c4.player_to_string(1) << " won"; - else cout << "draw"; - cout << endl; - } -} diff --git a/AI/src/game/test_connect4.hpp b/AI/src/game/test_connect4.hpp deleted file mode 100644 index 1ecee241bf2950e5217d808856eb76ac1689601a..0000000000000000000000000000000000000000 --- a/AI/src/game/test_connect4.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __TEST_CONNECT4_HPP__ -#define __TEST_CONNECT4_HPP__ - -namespace game -{ - class test_connect4 - { - void playout(); - void play(); - public: - test_connect4(); - }; -} -#endif diff --git a/AI/src/mcts/test_mcts_two_players.cpp b/AI/src/mcts/test_mcts_two_players.cpp index c462a7bdff0253f6375a993f6566a376dd37d311..041b9f2db9ced2bfe236d3978e576c8b25172622 100644 --- a/AI/src/mcts/test_mcts_two_players.cpp +++ b/AI/src/mcts/test_mcts_two_players.cpp @@ -1,6 +1,5 @@ #include "mcts_two_players.hpp" #include "test_mcts_two_players.hpp" -#include "connect4.hpp" #include <iostream> #include <iomanip> #include <map> @@ -131,7 +130,7 @@ namespace mcts // c4.set_state(state); // openings_.update(c4, moves, v); // c4.set_state(state); - // for (uint16_t m : moves) + // for (uint16_t m : moves) // { // c4.play(m); // v = -v; @@ -150,10 +149,10 @@ namespace mcts // } // cout << "number of learning examples: " << learning_examples.size() << endl; // ofstream output("learning_examples.txt"); - // for (const auto& example : learning_examples) + // for (const auto& example : learning_examples) // { // output << example.second.second; - // for (int index : example.first) + // for (int index : example.first) // { // output << " " << index << ":" << 1; // } diff --git a/AI/src/minmax/connect4_heuristic.cpp b/AI/src/minmax/connect4_heuristic.cpp deleted file mode 100644 index 25ad3a68164d9a37cce728826ae3aaa922529eac..0000000000000000000000000000000000000000 --- a/AI/src/minmax/connect4_heuristic.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "connect4_heuristic.hpp" - -namespace minmax -{ - double connect4_heuristic::value(const connect4& c4) const - { - const connect4_state& state = c4.get_state(); - return 0; - } - -} diff --git a/AI/src/minmax/connect4_heuristic.hpp b/AI/src/minmax/connect4_heuristic.hpp deleted file mode 100644 index 050d176de3d5f29fd37804e054d3e98556a7a0c1..0000000000000000000000000000000000000000 --- a/AI/src/minmax/connect4_heuristic.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __CONNECT4_HEURISTIC_HPP__ -#define __CONNECT4_HEURISTIC_HPP__ - -#include <connect4.hpp> - -namespace minmax -{ - class connect4_heuristic : public heuristic<connect4> - { - double value(const connect4& c4) const; - }; -} - -#endif diff --git a/AI/src/minmax/heuristic.hpp b/AI/src/minmax/heuristic.hpp deleted file mode 100644 index 09803f07736b0e5534696be18bde3c9cc446208d..0000000000000000000000000000000000000000 --- a/AI/src/minmax/heuristic.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __HEURISTIC_HPP__ -#define __HEURISTIC_HPP__ - -namespace minmax -{ - template <typename Game> - class heuristic - { - public: - virtual double value(const Game& game) const = 0; - }; - - template <typename Game> - class null_heuristic : public heuristic<Game> - { - double value(const Game& game) const; - }; - - template <typename Game> - double null_heuristic<Game>::value(const Game& game) const - { - return 0; - } -} - -#endif diff --git a/AI/src/minmax/minmax.hpp b/AI/src/minmax/minmax.hpp deleted file mode 100644 index 6a77f7cc0d2ed11ffc0e9db2b3cdb1cb1962e9e4..0000000000000000000000000000000000000000 --- a/AI/src/minmax/minmax.hpp +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef __MINMAX_HPP__ -#define __MINMAX_HPP__ - -#include <chrono> -#include <vector> -#include "game.hpp" -#include "heuristic.hpp" -#include <iostream> -#include <limits> - -namespace minmax -{ - struct cannot_prove : std::exception - { - const char* what() const noexcept { return "cannot prove the game theoritical value"; } - }; - - template <typename Game> - class minmax - { - protected: - Game& game; - std::chrono::milliseconds milliseconds; - const heuristic<Game>& h; - std::vector<uint16_t> principal_variation; - std::chrono::steady_clock::time_point start; - - public: - minmax(Game& game, uint32_t milliseconds, const heuristic<Game>& h = null_heuristic<Game>()) - : game(game), milliseconds(milliseconds), h(h) - { - } - - int prove(); - double solve(); - uint16_t select_move(); - - private: - long prove(int depth); - double solve(int depth); - }; - - template <typename Game> - minmax<Game> make_minmax(Game& game, uint32_t milliseconds, const heuristic<Game>& h = null_heuristic<Game>()) - { - return minmax<Game>(game, milliseconds, h); - } - - template <typename Game> - double minmax<Game>::solve() - { - return 0; - } - - template <typename Game> - double minmax<Game>::solve(int depth) - { - return 0; - } - - template <typename Game> - uint16_t minmax<Game>::select_move() - { - return 0; - } - - const long UNKNOWN = std::numeric_limits<long>::max(); - - template <typename Game> - int minmax<Game>::prove() - { - start = std::chrono::steady_clock::now(); - uint16_t nb_moves = game.number_of_moves(); - long value[nb_moves]; - std::fill_n(value, nb_moves, UNKNOWN); - int depth = 3; - auto state = game.get_state(); - try - { - int nb_proved_moves = 0, nb_draws = 0; - while (true) - { - for (uint16_t move = 0; move < nb_moves; ++move) - { - if (value[move] != UNKNOWN) continue; - game.play(move); - value[move] = prove(depth); - game.set_state(state); - if (value[move] == -1) return 1; - if (value[move] == 0) ++nb_draws; - if (value[move] != UNKNOWN) ++nb_proved_moves; - } - if (nb_proved_moves == nb_moves) - { - if (nb_draws != 0) return 0; - return -1; - } - ++depth; - } - } - catch (cannot_prove fail) - { - game.set_state(state); - } - throw cannot_prove(); - } - - template <typename Game> - long minmax<Game>::prove(int depth) - { - if (game.end_of_game()) return game.value(game.current_player()); - if (depth == 0) return UNKNOWN; - if ((depth & 3) && std::chrono::steady_clock::now() >= start + milliseconds) throw cannot_prove(); - uint16_t nb_moves = game.number_of_moves(); - auto state = game.get_state(); - int nb_proved_moves = 0, nb_draws = 0; - for (uint16_t move = 0; move < nb_moves; ++move) - { - game.play(move); - long v = prove(depth - 1); - game.set_state(state); - if (v == -1) return 1; - if (v == 0) ++nb_draws; - if (v != UNKNOWN) ++nb_proved_moves; - } - if (nb_proved_moves == nb_moves) - { - if (nb_draws != 0) return 0; - return -1; - } - return UNKNOWN; - } -} - -#endif diff --git a/AI/src/minmax/test_minmax.cpp b/AI/src/minmax/test_minmax.cpp deleted file mode 100644 index 7d5aa9c583ebb0e5f0a5e79f4789baeacbce6fd5..0000000000000000000000000000000000000000 --- a/AI/src/minmax/test_minmax.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "minmax.hpp" -#include "test_minmax.hpp" -#include "connect4.hpp" -#include <iostream> -#include <iomanip> -#include <map> - -using namespace std; -using namespace game; - -namespace minmax -{ - test_minmax::test_minmax() - { - play(); - } - - template <typename Game> - int test_minmax::select_move(Game& game) - { - cout << game.player_to_string(game.current_player()) << " move: "; - map<string, int> m; - for (int i = 0; i < game.number_of_moves(); ++i) - { - m[game.move_to_string(i)] = i; - } - string move; - getline(cin, move); - game.play(m[move]); - return m[move]; - } - - void test_minmax::play() - { - connect4 c4; - auto minimax = make_minmax(c4, 2000); - cout << "play one game" << endl; - cout << c4 << endl; - while (!c4.end_of_game()) - { - cout << "try to prove? (y/n)" << endl; - string ans; - getline(cin, ans); - if (ans == "y") - { - try - { - int v = minimax.prove(); - if (v == 1) cout << "won position" << endl; - if (v == -1) cout << "lost position" << endl; - if (v == 0) cout << "drawn position" << endl; - } - catch (exception fail) - { - cout << "unable to prove" << endl; - } - } - select_move(c4); - cout << c4 << endl; - } - if (c4.value(0) == 1) cout << c4.player_to_string(0) << " won"; - else if (c4.value(1) == 1) cout << c4.player_to_string(1) << " won"; - else cout << "draw"; - cout << endl; - } - -} diff --git a/AI/src/minmax/test_minmax.hpp b/AI/src/minmax/test_minmax.hpp deleted file mode 100644 index 7d8fe99d111c3e634d4a8ede551a3b8f80f2fe26..0000000000000000000000000000000000000000 --- a/AI/src/minmax/test_minmax.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __TEST_MINMAX_HPP__ -#define __TEST_MINMAX_HPP__ - -namespace minmax -{ - class test_minmax - { - void play(); - template <typename Game> - int select_move(Game& game); - public: - test_minmax(); - }; -} - -#endif diff --git a/AI/tools/gui.py b/AI/tools/gui.py deleted file mode 100755 index 3842f44904173c642a2cf3e9dd4e00984e85851e..0000000000000000000000000000000000000000 --- a/AI/tools/gui.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -#-*- encoding: utf-8 -*- -import drawState -import subprocess -import json -import os - -if __name__ == "__main__": - programname = os.path.join(os.path.dirname(__file__), "../bin/theturk") - program = subprocess.Popen(programname, stdin = subprocess.PIPE, stdout = subprocess.PIPE, universal_newlines = True, bufsize = 1) - try: - program.stdin.write("h\n") - while True: - #READ - readloop = True - comments = [] - json_data = "" - brackets_count = 0 - while readloop: - line = program.stdout.readline() - #print(line) - line = line.replace("who's first? (h)uman/(c)omputer ", "") - line = line.replace("Red move: ", "") - line = line.replace("Blue move: ", "") - if line.startswith("{"): #Reading json - json_data = line - else: - comments.append(line) - if line == "\n": - readloop = False - #PRINT STATE - print("Comments: {}".format(''.join(comments))) - state = json.loads(json_data) - drawState.drawBitboard(state["bitboards"]["onefish"],state["bitboards"]["twofish"],state["bitboards"]["threefish"]) - print("Red penguins (Red score: {}, Total moves: {} [0..{}])".format(state["score"]["red"], state["nb_moves"]["red"], state["nb_moves"]["red"]-1)) - for i in range(4): - drawState.drawPenguin(state["penguins"]["red"][i]) - print("Blue penguins (Blue score: {}, Total moves: {} [0..{}])".format(state["score"]["blue"], state["nb_moves"]["blue"], state["nb_moves"]["blue"] -1)) - for i in range(4): - drawState.drawPenguin(state["penguins"]["blue"][i]) - #PLAY NEXT MOVE - if state["current_player"] == "Red": - move = input("Enter Red move: ") - else: - move = input("Enter Blue move: ") - program.stdin.write(move+"\n") - program.stdin.flush() - except BrokenPipeError: - print("Game end") - except KeyboardInterrupt: - print("\nMay the fish be with you.") - finally: - program.kill()