Skip to content
Snippets Groups Projects
Commit aefe25da authored by Bariatti Francesco's avatar Bariatti Francesco
Browse files

Created skel for morpion game. Functions are empty.

TODO: implementation of every function.
connect4.cpp and test_connect4.cpp were left in the sources of the
Makefile so the project could compile
parent cfe9818a
No related branches found
No related tags found
No related merge requests found
......@@ -3,7 +3,7 @@ BIN=bin
INCLUDE=-I src/game -I src/util -I src/monte_carlo -I src/mcts -I src/minmax
CFLAGS=-g -O3 -ffast-math -fopenmp -c -Wall -std=c++11 $(INCLUDE)
LDFLAGS=-fopenmp -std=c++11 #-lprofiler -Wl,-no_pie
SOURCES=omp_util.cpp fast_log.cpp display_node.cpp connect4.cpp test_connect4.cpp monte_carlo.cpp test_monte_carlo.cpp test_fast_log.cpp\
SOURCES=omp_util.cpp fast_log.cpp display_node.cpp morpion.cpp connect4.cpp test_connect4.cpp monte_carlo.cpp test_monte_carlo.cpp test_fast_log.cpp\
statistics.cpp node.cpp allocator.cpp test_allocator.cpp openings.cpp mcts_two_players.cpp test_mcts_two_players.cpp test_minmax.cpp\
bits.cpp test_bits.cpp main.cpp
OBJECTS=$(addprefix $(BIN)/, $(SOURCES:.cpp=.o))
......
#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
{
//TODO: Implement
return false;
}
bool morpion::won(std::uint8_t player) const
{
//TODO: Implement
return false;
}
bool morpion::lost(std::uint8_t player) const
{
//TODO: Implement
return false;
}
bool morpion::draw(std::uint8_t player) const
{
//TODO: Implement
return false;
}
uint8_t morpion::current_player() const
{
//TODO: Implement
return 0;
}
int morpion::value(uint8_t player) const
{
//TODO: Implement
return 0;
}
uint16_t morpion::number_of_moves() const
{
//TODO: Implement
return 0;
}
bool morpion::get(uint64_t bitboard, uint8_t col, uint8_t row) const
{
//TODO: Implement
return false;
}
//#define set(bitboard, col, row) (bitboard |= (1LL << (((col) << 3) + (row))))
void morpion::update_win()
{
//TODO: Implement
}
bool morpion::has_won(uint64_t bitboard)
{
//TODO: Implement
return false;
}
void morpion::update_moves(uint16_t move)
{
//TODO: Implement
}
void morpion::play(uint16_t m)
{
//TODO: Implement
}
string morpion::player_to_string(uint8_t player) const
{
//TODO: Implement
return "TODO";
}
string morpion::move_to_string(uint16_t m) const
{
//TODO: Implement
return "TODO";
}
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: Implement
return "TODO";
}
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;
}
}
#ifndef __MORPION_HPP__
#define __MORPION_HPP__
#include "game.hpp"
#include <random>
#include <array>
#include <iostream>
#include <memory>
namespace game
{
struct morpion_state
{
uint8_t total_moves = 0;
bool first_player_win = false;
bool second_player_win = false;
};
class morpion : public game<morpion_state>
{
public:
morpion();
morpion(const morpion& mor) = default;
morpion& operator=(const morpion& mor) = default;
bool end_of_game() const;
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;
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);
morpion_state get_state();
void set_state(const morpion_state& state);
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();
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;
const uint8_t CROSS = 0;
const uint8_t CIRCLE = 1;
morpion_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 morpion& mor);
}
#endif
#include "mcts_two_players.hpp"
#include "test_mcts_two_players.hpp"
#include "connect4.hpp"
#include "morpion.hpp"
#include <iostream>
#include <iomanip>
#include <map>
......@@ -12,7 +12,7 @@ using namespace game;
namespace mcts
{
test_mcts_two_players::test_mcts_two_players() : openings_(connect4())
test_mcts_two_players::test_mcts_two_players() : openings_(morpion())
{
//self_play(1000);
play();
......@@ -44,19 +44,19 @@ namespace mcts
void test_mcts_two_players::play()
{
// ProfilerStart("theturk.prof");
connect4 c4;
auto the_turk = make_mcts_two_players(c4, 5000, 0.3, 4);
morpion mor;
auto the_turk = make_mcts_two_players(mor, 5000, 0.3, 4);
cout << "play one game" << endl;
cout << "who's first? (h)uman/(c)omputer ";
string ans;
getline(cin, ans);
cout << c4 << endl;
cout << mor << endl;
int human_last_move = -1, computer_last_move = -1;
while (!c4.end_of_game())
while (!mor.end_of_game())
{
if ((ans == "h" && c4.current_player() == 0) || (ans == "c" && c4.current_player() == 1))
if ((ans == "h" && mor.current_player() == 0) || (ans == "c" && mor.current_player() == 1))
{
human_last_move = select_move(c4);
human_last_move = select_move(mor);
}
else
{
......@@ -66,13 +66,13 @@ namespace mcts
}
uint16_t move = the_turk.select_move();
computer_last_move = move;
cout << c4.player_to_string(c4.current_player()) << " move: " << c4.move_to_string(move) << endl;
c4.play(move);
cout << mor.player_to_string(mor.current_player()) << " move: " << mor.move_to_string(move) << endl;
mor.play(move);
}
cout << c4 << endl;
cout << mor << 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";
if (mor.value(0) == 1) cout << mor.player_to_string(0) << " won";
else if (mor.value(1) == 1) cout << mor.player_to_string(1) << " won";
else cout << "draw";
cout << endl;
// ProfilerStop();
......@@ -80,25 +80,25 @@ namespace mcts
void test_mcts_two_players::self_play_learn_openings(int n)
{
connect4 c4;
morpion mor;
vector<uint16_t> moves(200);
auto state = c4.get_state();
auto the_turk_1 = make_mcts_two_players(c4, 1000, 0.6, 2);
auto the_turk_2 = make_mcts_two_players(c4, 1000, 0.6, 2);
auto state = mor.get_state();
auto the_turk_1 = make_mcts_two_players(mor, 1000, 0.6, 2);
auto the_turk_2 = make_mcts_two_players(mor, 1000, 0.6, 2);
map<set<int>, pair<uint32_t, double>> learning_examples;
for (int i = 0; i < n; ++i)
{
cout << i << endl;
cout << openings_ << endl << endl;
moves.clear();
c4.set_state(state);
mor.set_state(state);
the_turk_1.reset();
the_turk_1.init_with_openings(openings_);
the_turk_2.reset();
the_turk_2.init_with_openings(openings_);
int the_turk_1_last_move = -1, the_turk_2_last_move = -1;
int k = 0;
while (!c4.end_of_game())
while (!mor.end_of_game())
{
if (k == 1) the_turk_2.last_move(the_turk_1_last_move);
if (k % 2 == 0)
......@@ -110,7 +110,7 @@ namespace mcts
uint16_t move = the_turk_1.select_move();
moves.push_back(move);
the_turk_1_last_move = move;
c4.play(move);
mor.play(move);
}
else
{
......@@ -121,21 +121,21 @@ namespace mcts
uint16_t move = the_turk_2.select_move();
moves.push_back(move);
the_turk_2_last_move = move;
c4.play(move);
mor.play(move);
}
++k;
}
std::cout << c4 << std::endl;
int v = c4.value(0);
std::cout << mor << std::endl;
int v = mor.value(0);
cout << "value for first player " << v << endl;
c4.set_state(state);
openings_.update(c4, moves, v);
c4.set_state(state);
mor.set_state(state);
openings_.update(mor, moves, v);
mor.set_state(state);
for (uint16_t m : moves)
{
c4.play(m);
mor.play(m);
v = -v;
set<int> input_vector = std::move(c4.to_input_vector());
set<int> input_vector = std::move(mor.to_input_vector());
auto it = learning_examples.find(input_vector);
if (it == learning_examples.end())
{
......@@ -164,26 +164,26 @@ namespace mcts
void test_mcts_two_players::self_play(int n, bool with_openings)
{
connect4 c4;
auto state = c4.get_state();
auto the_turk_v1 = make_mcts_two_players(c4, 1000, 0.6, 2);
auto the_turk_v2 = make_mcts_two_players(c4, 1000, 0.6, 2);
morpion mor;
auto state = mor.get_state();
auto the_turk_v1 = make_mcts_two_players(mor, 1000, 0.6, 2);
auto the_turk_v2 = make_mcts_two_players(mor, 1000, 0.6, 2);
int nb_win_v1 = 0, nb_win_v2 = 0, nb_draw = 0;
for (int i = 0; i < n; ++i)
{
cout << i << endl;
c4.set_state(state);
mor.set_state(state);
the_turk_v1.reset();
the_turk_v2.reset();
if (with_openings) the_turk_v2.init_with_openings(openings_);
int the_turk_v1_last_move = -1, the_turk_v2_last_move = -1;
int k = 0;
while (!c4.end_of_game())
while (!mor.end_of_game())
{
if (with_openings && k == 1 && i % 2 == 0) the_turk_v2.last_move(the_turk_v1_last_move);
++k;
// cout << c4 << endl;
if ((i % 2 == 0 && c4.current_player() == 0) || (i % 2 == 1 && c4.current_player() == 1))
// cout << mor << endl;
if ((i % 2 == 0 && mor.current_player() == 0) || (i % 2 == 1 && mor.current_player() == 1))
{
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
{
......@@ -191,7 +191,7 @@ namespace mcts
}
uint16_t move = the_turk_v1.select_move();
the_turk_v1_last_move = move;
c4.play(move);
mor.play(move);
}
else
{
......@@ -201,10 +201,10 @@ namespace mcts
}
uint16_t move = the_turk_v2.select_move();
the_turk_v2_last_move = move;
c4.play(move);
mor.play(move);
}
}
if (c4.value(0) == 1)
if (mor.value(0) == 1)
{
if (i % 2 == 0)
{
......@@ -215,7 +215,7 @@ namespace mcts
/*cout << "v2 won" << endl;*/ ++nb_win_v2;
}
}
else if (c4.value(1) == 1)
else if (mor.value(1) == 1)
{
if (i % 2 == 0)
{
......@@ -236,18 +236,18 @@ namespace mcts
void test_mcts_two_players::self_play()
{
connect4 c4;
auto the_turk_v1 = make_mcts_two_players(c4, 1000, 1.2, 2);
auto the_turk_v2 = make_mcts_two_players(c4, 1000, 1.2, 2);
morpion mor;
auto the_turk_v1 = make_mcts_two_players(mor, 1000, 1.2, 2);
auto the_turk_v2 = make_mcts_two_players(mor, 1000, 1.2, 2);
cout << "play one game" << endl;
cout << "who's first? the_turk_(v1)/the_turk_(v2) ";
string ans;
getline(cin, ans);
cout << c4 << endl;
cout << mor << endl;
int the_turk_v1_last_move = -1, the_turk_v2_last_move = -1;
while (!c4.end_of_game())
while (!mor.end_of_game())
{
if ((ans == "v1" && c4.current_player() == 0) || (ans == "v2" && c4.current_player() == 1))
if ((ans == "v1" && mor.current_player() == 0) || (ans == "v2" && mor.current_player() == 1))
{
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
{
......@@ -255,8 +255,8 @@ namespace mcts
}
uint16_t move = the_turk_v1.select_move();
the_turk_v1_last_move = move;
cout << c4.player_to_string(c4.current_player()) << " move: " << c4.move_to_string(move) << endl;
c4.play(move);
cout << mor.player_to_string(mor.current_player()) << " move: " << mor.move_to_string(move) << endl;
mor.play(move);
}
else
{
......@@ -266,13 +266,13 @@ namespace mcts
}
uint16_t move = the_turk_v2.select_move();
the_turk_v2_last_move = move;
cout << c4.player_to_string(c4.current_player()) << " move: " << c4.move_to_string(move) << endl;
c4.play(move);
cout << mor.player_to_string(mor.current_player()) << " move: " << mor.move_to_string(move) << endl;
mor.play(move);
}
cout << c4 << endl;
cout << mor << 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";
if (mor.value(0) == 1) cout << mor.player_to_string(0) << " won";
else if (mor.value(1) == 1) cout << mor.player_to_string(1) << " won";
else cout << "draw";
cout << endl;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment