Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • francesco-bariatti/pingouins
  • Samuel.Felton/pingouins
  • Lucas.Clement/pingouins
3 results
Show changes
#include "penguin.hpp"
#include <sstream>
using namespace std;
namespace game
{
penguin::penguin()
{
}
shared_ptr<game<penguin_state>> penguin::do_copy() const
{
return shared_ptr<penguin>(new penguin(*this));
}
penguin_state penguin::get_state()
{
return state;
}
void penguin::set_state(const penguin_state& s)
{
state = s;
}
bool penguin::end_of_game() const
{
return false;
//return state.first_player_win || state.second_player_win || state.total_moves == 9;
}
bool penguin::won(std::uint8_t player) const
{
return false;
//if (player == CROSS) return state.first_player_win;
//return state.second_player_win;
}
bool penguin::lost(std::uint8_t player) const
{
return false;
/*if (player == CIRCLE) return state.first_player_win;
return state.second_player_win;*/
}
bool penguin::draw(std::uint8_t player) const
{
return false;
/*if (state.first_player_win || state.second_player_win) return false;
return state.total_moves == 9;*/
}
uint8_t penguin::current_player() const
{
return 0;
/*return state.total_moves & 1 ? CIRCLE : CROSS; // CROSS even, CIRCLE odd*/
}
int penguin::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;*/
return 0;
}
/* Number of moves that you can play */
uint16_t penguin::number_of_moves() const
{
//return 9 - state.total_moves;
return 0;
}
//Play the mth move in the possible moves list.
void penguin::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;*/
}
string penguin::player_to_string(uint8_t player) const
{
//return player == CROSS ? "X" : (player == CIRCLE ? "O" : " ");
return "TODO";
}
string penguin::move_to_string(uint16_t m) const
{
//return std::to_string((state.possible_moves >> (4 * m)) & 0xf);
return "TODO";
}
set<int> penguin::to_input_vector() const
{
return set<int>();
}
void penguin::from_input_vector(const std::set<int>& input)
{
}
string penguin::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;
*/
return "TODO";
}
std::uint64_t penguin::hash() const
{
return 0;
}
std::uint64_t penguin::hash(std::uint16_t m) const
{
return 0;
}
ostream& operator<<(ostream& os, const penguin& pen)
{
os << pen.to_string() << endl;
return os;
}
}
#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;
}
}
#ifndef __TEST_CONNECT4_HPP__
#define __TEST_CONNECT4_HPP__
namespace game
{
class test_connect4
{
void playout();
void play();
public:
test_connect4();
};
}
#endif
#include "test_connect4.hpp"
#include "connect4.hpp"
#include "morpion.hpp"
#include "penguin.hpp"
#include "test_two_players_game.hpp"
#include "test_monte_carlo.hpp"
#include "test_fast_log.hpp"
#include "test_allocator.hpp"
#include "test_mcts_two_players.hpp"
#include "test_minmax.hpp"
#include "test_bits.hpp"
#include "learning.hpp"
#include <omp.h>
using namespace std;
int main(int argc, char *argv[])
{
// game::test_connect4();
// util::test_fast_log(100000000);
// mcts::test_allocator(10, 2);
// omp_set_num_threads(8);
// game::run_test_two_players_game(game::connect4());
//mcts::run_test_mcts_two_players(game::connect4());
//game::run_test_two_players_game(game::morpion());
//mcts::run_test_mcts_two_players(game::morpion());
game::run_test_two_players_game(game::penguin());
//mcts::run_test_mcts_two_players(game::penguin());
// minmax::test_minmax();
//util::test_bits(200000000);
//game::connect4 c4;
// util::learning::display_file(c4, "learning_examples.txt");
return 0;
}
#include "connect4_heuristic.hpp"
namespace minmax
{
double connect4_heuristic::value(const connect4& c4) const
{
const connect4_state& state = c4.get_state();
return 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
#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
#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
#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;
}
}
#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