Newer
Older
#ifndef __TEST_MCTS_TWO_PLAYERS_HPP__
#define __TEST_MCTS_TWO_PLAYERS_HPP__
#include "openings.hpp"
#include <string>
#include <iostream>
#include <map>
#include <iomanip>
#include <set>
#include <fstream>
template <typename Game>
class test_mcts_two_players
{
void play(Game g, const heuristic<Game>& h);
void self_play(Game g, const heuristic<Game>& h1 = zero_knowledge<Game>(), const heuristic<Game>& h2 = zero_knowledge<Game>());
void test_openings(Game g, int nb_learning, int nb_testing);
void save_board(const Game& game, int move);
public:
test_mcts_two_players(const Game& g, const heuristic<Game>& h1 = zero_knowledge<Game>(), const heuristic<Game>& h2 = zero_knowledge<Game>());
};
test_mcts_two_players<Game>::test_mcts_two_players(const Game& g, const heuristic<Game>& h, const heuristic<Game>& h2)
game::config& config = game::config::get_config();
if(config.is_ai_vs_ai())
{
self_play(g, h,h2);
}
else
{
play(g, h);
}
template <typename Game>
void run_test_mcts_two_players(const Game& g, const heuristic<Game>& h = zero_knowledge<Game>(),const heuristic<Game>& h2 = zero_knowledge<Game>())
{
test_mcts_two_players<Game> {g, h, h2};
}
template <typename Game>
void test_mcts_two_players<Game>::test_openings(Game g, int nb_learning, int nb_testing)
{
//self_play(g, nb_testing);
self_play_learn_openings(g, nb_learning);
self_play(g, nb_testing, true);
template <typename Game>
int test_mcts_two_players<Game>::select_move(Game& game)
{
std::cout << game.player_to_string(game.current_player()) << " move: ";
std::map<std::string, int> m;
for (int i = 0; i < game.number_of_moves(); ++i)
std::string move;
getline(std::cin, move);
game.play(m[move]);
return m[move];
template <typename Game>
void test_mcts_two_players<Game>::save_board(const Game& game, int move){
std::shared_ptr<game::penguin> g = game::copy(game);
game::penguin_state state = g->get_state();
uint32_t pos = g->move_to_pos(move);
uint16_t peng_pos = (uint16_t)(pos >> 16);
savefile << state.one_fish << ";" << state.two_fish << ";" << state.three_fish << ";" << g->penguin_board(false) << ";" << g->penguin_board(true) << ";" << peng_pos << ";" << dest << std::endl;
template <typename Game>
void test_mcts_two_players<Game>::play(Game g, const heuristic<Game>& h)
{
auto the_turk = make_mcts_two_players(g, MCTS_TURN_TIME, 0.4, 8, h);
std::cout << "play one game" << std::endl;
std::cout << "who's first? (h)uman/(c)omputer ";
std::string ans;
getline(std::cin, ans);
std::cout << g.to_string() << std::endl;
int human_last_move = -1, computer_last_move = -1;
while (!g.end_of_game())
Felton Samuel
committed
if ((ans == "h" && g.current_player() == 0) || (ans == "c" && g.current_player() == 1))
if (human_last_move != -1 && computer_last_move != -1)
the_turk.last_moves(computer_last_move, human_last_move);
uint16_t move = the_turk.select_move();
computer_last_move = move;
std::cout << g.player_to_string(g.current_player()) << " move: " << g.move_to_string(move) << std::endl;
g.play(move);
if (g.won(0)) std::cout << g.player_to_string(0) << " won";
else if (g.won(1)) std::cout << g.player_to_string(1) << " won";
else std::cout << "draw";
std::cout << std::endl;
// ProfilerStop();
template <typename Game>
void test_mcts_two_players<Game>::self_play_learn_openings(Game g, int n)
{
std::vector<uint16_t> moves(200);
auto state = g.get_state();
auto the_turk_1 = make_mcts_two_players(g, 1000, 0.6, 2);
auto the_turk_2 = make_mcts_two_players(g, 1000, 0.6, 2);
std::cout << "DZMALJDFOPZAIHFOAZHFOZUHAOFHZAO" << std::endl;
std::map<std::set<int>, std::pair<std::uint32_t, double>> learning_examples;
for (int i = 0; i < n; ++i)
std::cout << (*openings_) << std::endl << std::endl;
moves.clear();
g.set_state(state);
the_turk_1.reset();
the_turk_1.init_with_openings(*openings_);
the_turk_2.init_with_openings(*openings_);
int the_turk_1_last_move = -1, the_turk_2_last_move = -1;
int k = 0;
while (!g.end_of_game())
if (k == 1) the_turk_2.last_move(the_turk_1_last_move);
if (k % 2 == 0)
the_turk_1.last_moves(the_turk_1_last_move, the_turk_2_last_move);
std::uint16_t move = the_turk_1.select_move();
moves.push_back(move);
the_turk_1_last_move = move;
g.play(move);
the_turk_2.last_moves(the_turk_2_last_move, the_turk_1_last_move);
std::uint16_t move = the_turk_2.select_move();
moves.push_back(move);
the_turk_2_last_move = move;
g.play(move);
int v = g.value(0);
std::cout << "value for first player " << v << std::endl;
g.set_state(state);
openings_->update(g, moves, v);
g.set_state(state);
for (std::uint16_t m : moves)
{
g.play(m);
v = -v;
std::set<int> input_vector = std::move(g.to_input_vector());
auto it = learning_examples.find(input_vector);
if (it == learning_examples.end())
{
learning_examples[input_vector] = std::make_pair(1, v);
}
else
{
it->second.second = (it->second.second * it->second.first + v) / (it->second.first + 1);
it->second.first += 1;
}
}
}
std::cout << "number of learning examples: " << learning_examples.size() << std::endl;
std::ofstream output("learning_examples.txt");
for (const auto& example : learning_examples)
{
output << example.second.second;
for (int index : example.first)
{
output << " " << index << ":" << 1;
}
output << std::endl;
}
template <typename Game>
void test_mcts_two_players<Game>::self_play(Game g, const heuristic<Game>& h1, const heuristic<Game>& h2)
{
//std::cout << getFilePath() << std::endl;
game::config& c = game::config::get_config();
auto the_turk_v1 = make_mcts_two_players(g, c.get_think_time(), 0.6, 2, h1);
auto the_turk_v2 = make_mcts_two_players(g, c.get_think_time(), 0.6, 2, h2);
std::string result_directory(get_test_results_directory());
int nb_win_v1 = 0, nb_win_v2 = 0, nb_draw = 0;
for (unsigned int i = 0; i < c.get_game_count(); ++i)
{
g.set_state(state);
the_turk_v1.reset();
the_turk_v2.reset();
int the_turk_v1_last_move = -1, the_turk_v2_last_move = -1;
if ((i % 2 == 0 && g.current_player() == 0) || (i % 2 == 1 && g.current_player() == 1))
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
the_turk_v1.last_moves(the_turk_v1_last_move, the_turk_v2_last_move);
std::uint16_t move = the_turk_v1.select_move();
the_turk_v1_last_move = move;
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
the_turk_v2.last_moves(the_turk_v2_last_move, the_turk_v1_last_move);
std::uint16_t move = the_turk_v2.select_move();
the_turk_v2_last_move = move;
}
if(c.should_send_game_to_gui())
std::cout << g;
}
std::cout << "v1 won" << std::endl;
++nb_win_v1;
std::cout << "v2 won" << std::endl;
++nb_win_v2;
save_stats(result_directory,nb_win_v1,nb_win_v2,nb_draw);
std::cout << std::setw(10) << "v1 nb wins: " << nb_win_v1 << " v2 nb wins: " << nb_win_v2 << " nb draws: " << nb_draw << std::endl;
template <typename Game>
void test_mcts_two_players<Game>::self_play(Game g)
{
auto the_turk_v1 = make_mcts_two_players(g, 1000, 1.2, 2);
auto the_turk_v2 = make_mcts_two_players(g, 1000, 1.2, 2);
std::cout << "play one game" << std::endl;
std::cout << "who's first? the_turk_(v1)/the_turk_(v2) ";
std::string ans;
getline(std::cin, ans);
std::cout << g << std::endl;
int the_turk_v1_last_move = -1, the_turk_v2_last_move = -1;
while (!g.end_of_game())
if ((ans == "v1" && g.current_player() == 0) || (ans == "v2" && g.current_player() == 1))
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
the_turk_v1.last_moves(the_turk_v1_last_move, the_turk_v2_last_move);
std::uint16_t move = the_turk_v1.select_move();
the_turk_v1_last_move = move;
std::cout << g.player_to_string(g.current_player()) << " move: " << g.move_to_string(move) << std::endl;
g.play(move);
if (the_turk_v1_last_move != -1 && the_turk_v2_last_move != -1)
the_turk_v2.last_moves(the_turk_v2_last_move, the_turk_v1_last_move);
std::uint16_t move = the_turk_v2.select_move();
the_turk_v2_last_move = move;
std::cout << g.player_to_string(g.current_player()) << " move: " << g.move_to_string(move) << std::endl;
g.play(move);
if (g.won(0)) std::cout << g.player_to_string(0) << " won";
else if (g.won(1)) std::cout << g.player_to_string(1) << " won";
else std::cout << "draw";
std::cout << std::endl;