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
Commits on Source (97)
Showing
with 10713 additions and 29 deletions
bin/ AI/bin/
__pycache__/ __pycache__/
.metadata
GUI/.classpath
GUI/bin
GUI/.project
GUI/.settings
GUI/out
GUI/.idea
GUI/GUI.iml
#Latex generated files
*.log
*.out
*.synctex.gz
*.aux
*.tox
*.toc
*.dvi
*.bbl
*.blg
*.nav
*.snm
File moved
...@@ -5,35 +5,63 @@ using namespace std; ...@@ -5,35 +5,63 @@ using namespace std;
namespace game namespace game
{ {
/**
* Creates the game: load the state from standard input.
* Penguins in state can be composed of just their position: the moves will be updated automatically.
**/
penguin::penguin() penguin::penguin()
{ {
//Update moves on all penguins cout << "Enter penguin game state as JSON on one line" << endl;
uint64_t obstacles = (~(state.one_fish | state.two_fish | state.three_fish)); string line;
obstacles |= ((uint64_t) 1) << (state.p1_red & 63); getline(cin, line);
obstacles |= ((uint64_t) 1) << (state.p2_red & 63); json json_state = json::parse(line);
obstacles |= ((uint64_t) 1) << (state.p3_red & 63); //Charging every element of the state if it exists
obstacles |= ((uint64_t) 1) << (state.p4_red & 63); if(json_state.count("bitboards"))
obstacles |= ((uint64_t) 1) << (state.p1_blue & 63); {
obstacles |= ((uint64_t) 1) << (state.p2_blue & 63); if(json_state["bitboards"].count("onefish")) {state.one_fish = json_state["bitboards"]["onefish"];}
obstacles |= ((uint64_t) 1) << (state.p3_blue & 63); if(json_state["bitboards"].count("twofish")) {state.two_fish = json_state["bitboards"]["twofish"];}
obstacles |= ((uint64_t) 1) << (state.p4_blue & 63); if(json_state["bitboards"].count("threefish")) {state.three_fish = json_state["bitboards"]["threefish"];}
}
if(json_state.count("current_player"))
state.current_player_red = json_state["current_player"] == "Red" ? true : false;
if(json_state.count("penguins"))
{
if(json_state["penguins"].count("red"))
{
for(int i = 0; i < 4; i++)
state.peng_red[i] = json_state["penguins"]["red"][i];
}
if(json_state["penguins"].count("blue"))
{
for(int i = 0; i < 4; i++)
state.peng_blue[i] = json_state["penguins"]["blue"][i];
}
}
if(json_state.count("score"))
{
if(json_state["score"].count("red")) { state.score_red = json_state["score"]["red"]; }
if(json_state["score"].count("blue")) { state.score_blue = json_state["score"]["blue"]; }
}
// We compute the moves for all penguin
uint64_t obstacles = create_obstacles_bitboard();
state.nb_moves_red = 0; state.nb_moves_red = 0;
state.nb_moves_blue = 0; state.nb_moves_blue = 0;
state.nb_moves_red += update_moves(&state.p1_red, obstacles);
state.nb_moves_red += update_moves(&state.p2_red, obstacles); for(int i = 0; i < 4; i++)
state.nb_moves_red += update_moves(&state.p3_red, obstacles); {
state.nb_moves_red += update_moves(&state.p4_red, obstacles); state.nb_moves_red += update_penguin_moves(&state.peng_red[i], obstacles);
state.nb_moves_blue += update_moves(&state.p1_blue, obstacles); state.nb_moves_blue += update_penguin_moves(&state.peng_blue[i], obstacles);
state.nb_moves_blue += update_moves(&state.p2_blue, obstacles); }
state.nb_moves_blue += update_moves(&state.p3_blue, obstacles); if (state.nb_moves_red == 0)
state.nb_moves_blue += update_moves(&state.p4_blue, obstacles); {
state.canPlay_red = false;
//Change player if the other one can play state.nb_moves_red = 1; //We create an artificial move so that the mcts works
if(state.current_player_red && state.nb_moves_blue > 0) }
state.current_player_red = false; if (state.nb_moves_blue == 0)
else if(state.current_player_red == false && state.nb_moves_red > 0) {
state.current_player_red = true; state.canPlay_blue = false;
state.nb_moves_blue = 1; //We create an artificial move so that the mcts works
}
} }
shared_ptr<game<penguin_state>> penguin::do_copy() const shared_ptr<game<penguin_state>> penguin::do_copy() const
...@@ -53,7 +81,7 @@ namespace game ...@@ -53,7 +81,7 @@ namespace game
bool penguin::end_of_game() const bool penguin::end_of_game() const
{ {
return state.nb_moves_red == 0 && state.nb_moves_blue == 0; return state.canPlay_red == false && state.canPlay_blue == false;
} }
bool penguin::won(std::uint8_t player) const bool penguin::won(std::uint8_t player) const
...@@ -94,140 +122,81 @@ namespace game ...@@ -94,140 +122,81 @@ namespace game
return state.current_player_red ? state.nb_moves_red : state.nb_moves_blue; return state.current_player_red ? state.nb_moves_red : state.nb_moves_blue;
} }
/* The penguin that will move if we want to play the #move_number move in the list of possible moves. /*
* What this function does: Moves the penguin p (modify its position value), making it do its rel_move move.
* Find the penguin that will move. At the end of the function the penguin will be composed of just its new position (every other bit is at 0)
* Change its total number of moves so that it is relative to that penguin's possible moves and not relative to ALL the penguins' moves. */
* Return a pointer to that penguin void penguin::move_penguin(uint32_t* p, uint16_t rel_move)
* */
uint32_t* penguin::penguin_that_moves(uint16_t move_number)
{ {
if(state.current_player_red)
{
if(((state.p1_red >> 6) & 63) > move_number)
{
uint32_t* p = &state.p1_red;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p1_red >> 6) & 63;
if(((state.p2_red >> 6) & 63) > move_number)
{
uint32_t* p = &state.p2_red;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p2_red >> 6) & 63;
if(((state.p3_red >> 6) & 63) > move_number)
{
uint32_t* p = &state.p3_red;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p3_red >> 6) & 63;
uint32_t* p = &state.p4_red;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
else
{
if(((state.p1_blue >> 6) & 63) > move_number)
{
uint32_t* p = &state.p1_blue;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p1_blue >> 6) & 63;
if(((state.p2_blue >> 6) & 63) > move_number)
{
uint32_t* p = &state.p2_blue;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p2_blue >> 6) & 63;
if(((state.p3_blue >> 6) & 63) > move_number)
{
uint32_t* p = &state.p3_blue;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
move_number -= (state.p3_blue >> 6) & 63;
uint32_t* p = &state.p4_blue;
(*p) = (*p) & 0xFFFFF03F; //Reset move number for the penguin to 0
(*p) = (*p) | ((uint32_t) move_number) << 6;
return p;
}
}
void penguin::move_penguin(uint32_t* p)
{
uint8_t move_number = ((*p) >> 6) & 63; //Move number for the current penguin
uint32_t penguin_copy = (*p) >> 12;
//Direction A //Direction A
if((penguin_copy & 7) >= move_number) if(PENGUIN_MOVES_A(*p) > rel_move) //If the penguin total moves in this direction are greater than the move we want to do for it (not equal because moves start at 0)
{ {
//Move direction A //Move direction A
(*p) = (7 * move_number +1) + ((*p) & 63); (*p) = (7 * (rel_move +1)) + ((*p) & 63);
return; return;
} }
move_number -= penguin_copy & 7; rel_move -= PENGUIN_MOVES_A(*p);
penguin_copy = penguin_copy >> 3; if(PENGUIN_MOVES_B(*p) > rel_move)
if((penguin_copy & 7) >= move_number)
{ {
//Move direction B //Move direction B
(*p) = (-1 * move_number +1) + ((*p) & 63); (*p) = (-1 * (rel_move +1)) + ((*p) & 63);
return; return;
} }
move_number -= penguin_copy & 7; rel_move -= PENGUIN_MOVES_B(*p);
penguin_copy = penguin_copy >> 3; if(PENGUIN_MOVES_C(*p) > rel_move)
if((penguin_copy & 7) >= move_number)
{ {
//Move direction C //Move direction C
(*p) = (-8 * move_number +1) + ((*p) & 63); (*p) = (-8 * (rel_move +1)) + ((*p) & 63);
return; return;
} }
move_number -= penguin_copy & 7; rel_move -= PENGUIN_MOVES_C(*p);
penguin_copy = penguin_copy >> 3; if(PENGUIN_MOVES_D(*p) > rel_move)
if((penguin_copy & 7) >= move_number)
{ {
//Move direction D //Move direction D
(*p) = (-7 * move_number +1) + ((*p) & 63); (*p) = (-7 * (rel_move +1)) + ((*p) & 63);
return; return;
} }
move_number -= penguin_copy & 7; rel_move -= PENGUIN_MOVES_D(*p);
penguin_copy = penguin_copy >> 3; if(PENGUIN_MOVES_E(*p) > rel_move)
if((penguin_copy & 7) >= move_number)
{ {
//Move direction E //Move direction E
(*p) = (1 * move_number +1) + ((*p) & 63); (*p) = (1 * (rel_move +1)) + ((*p) & 63);
return; return;
} }
move_number -= penguin_copy & 7; rel_move -= PENGUIN_MOVES_E(*p);
penguin_copy = penguin_copy >> 3;
//Move direction F //Move direction F
(*p) = (8 * move_number +1) + ((*p) & 63); (*p) = (8 * (rel_move +1)) + ((*p) & 63);
} }
int penguin::update_moves(uint32_t* p, uint64_t obstacles) /* Create bitboard of obstacles: 1 if there is an obstacle, 0 if the penguin can
move freely on the tile
*/
uint64_t penguin::create_obstacles_bitboard()
{ {
#define IsFree(i) (((obstacles >> (i)) & 1) == 0) uint64_t obstacles = (~(state.one_fish | state.two_fish | state.three_fish));
int pos = (*p) & 63; for(int i = 0; i < 4; i++)
{
obstacles |= ((uint64_t) 1) << PENGUIN_POS(state.peng_red[i]);
obstacles |= ((uint64_t) 1) << PENGUIN_POS(state.peng_blue[i]);
}
return obstacles;
}
/* Updates the moves of a signle penguin.
This computes the moves in every direction according to the penguin position and the obstacles.
Parameters:
- p: a penguin that will be updated. Only his position is used and the rest is computed
- obstacles: a bitboard of obstacles: 1 means an obstacle in that tile
Returns:
Total moves of this penguin.
*/
int penguin::update_penguin_moves(uint32_t* p, uint64_t obstacles)
{
#define IsFree(i) (((obstacles >> (i)) & 1) == 0)
int pos = PENGUIN_POS(*p);
(*p) = pos; //Reset the penguin to all zeros except the position (*p) = pos; //Reset the penguin to all zeros except the position
int i = pos; int i = pos;
uint32_t nbmoves = 0; uint32_t nbmoves = 0; //Nb of moves in one direction
uint32_t total_moves = 0; uint32_t total_moves = 0;
//Direction A //Direction A
...@@ -249,7 +218,7 @@ namespace game ...@@ -249,7 +218,7 @@ namespace game
//Direction C //Direction C
nbmoves = 0; nbmoves = 0;
i = pos; i = pos;
while((i-8 > 0) && (i%15 != 0) && IsFree(i-8)) while((i-8 >= 0) && (i%15 != 0) && IsFree(i-8))
{ {
i -= 8; i -= 8;
nbmoves++; total_moves++; nbmoves++; total_moves++;
...@@ -290,75 +259,104 @@ namespace game ...@@ -290,75 +259,104 @@ namespace game
//Play the mth move in the possible moves list. //Play the mth move in the possible moves list.
void penguin::play(uint16_t m) void penguin::play(uint16_t m)
{ {
//Find which penguin will move //CAN WE PLAY?
uint32_t* p = penguin_that_moves(m); // We check if we can effectively play: if yes, the move is parsed and player, otherwise we do nothing (the move can be whatever, we won't look at it, so the player actually skip the turn)
uint8_t position = (*p) & 63; if ((state.current_player_red == true && state.canPlay_red) || ((state.current_player_red == false) && state.canPlay_blue))
//Find the value of the tile the penguin is on and update score
if ((state.one_fish >> position) & 1)
{
if(current_player() == RED)
state.score_red += 1;
else
state.score_blue += 1;
//We replace this tile with an empty one (0 in the bitboard)
state.one_fish = state.one_fish & ~(((uint64_t) 1) << position);
}
else if ((state.two_fish >> position) & 1)
{ {
//WHICH PENGUIN WILL MOVE?
uint32_t* peng; // The penguin that will move
uint16_t rel_move = m; // Move number relative to this penguin
int i = 0;
if(state.current_player_red)
{
/* We search for the first penguin that can make the move. If a penguin can't, we will decrese the move number
by the number of moves that he can do */
for(i = 0; (i < 3) && (PENGUIN_TOT_MOVES(state.peng_red[i]) <= rel_move); i ++) //While we didn't find the penguin
rel_move -= PENGUIN_TOT_MOVES(state.peng_red[i]);
// Now i is the number of the penguin that will move and rel_move is the move relative to this penguin (because we decreased it)
peng = &state.peng_red[i];
}
else //If blue
{
for(i = 0; (i < 3) && (PENGUIN_TOT_MOVES(state.peng_blue[i]) <= rel_move); i ++) //While we didn't find the penguin
rel_move -= PENGUIN_TOT_MOVES(state.peng_blue[i]);
peng = &state.peng_blue[i];
}
if(current_player() == RED) // ADD PENGUIN TILE TO THE SCORE
state.score_red += 2; if((state.one_fish >> PENGUIN_POS(*peng)) & 1) //If there is a one fish on this position
else {
state.score_blue += 2; if(state.current_player_red)
//We replace this tile with an empty one (0 in the bitboard) state.score_red += 1;
state.two_fish = state.two_fish & ~(((uint64_t) 1) << position); else
} state.score_blue += 1;
else //We replace this tile with an empty one (0 in the bitboard)
{ state.one_fish = state.one_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
if(current_player() == RED) }
state.score_red += 3; else if((state.two_fish >> PENGUIN_POS(*peng)) & 1)
{
if(state.current_player_red)
state.score_red += 2;
else
state.score_blue += 2;
//We replace this tile with an empty one (0 in the bitboard)
state.two_fish = state.two_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
}
else else
state.score_blue += 3; {
//We replace this tile with an empty one (0 in the bitboard) if(state.current_player_red)
state.three_fish = state.three_fish & ~(((uint64_t) 1) << position); state.score_red += 3;
} else
state.score_blue += 3;
//Move the current penguin //We replace this tile with an empty one (0 in the bitboard)
move_penguin(p); state.three_fish = state.three_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
}
cout << "Penguin p :" << *p << endl;
//Update moves on all penguins
uint64_t obstacles = (~(state.one_fish | state.two_fish | state.three_fish));
obstacles |= ((uint64_t) 1) << (state.p1_red & 63);
obstacles |= ((uint64_t) 1) << (state.p2_red & 63);
obstacles |= ((uint64_t) 1) << (state.p3_red & 63);
obstacles |= ((uint64_t) 1) << (state.p4_red & 63);
obstacles |= ((uint64_t) 1) << (state.p1_blue & 63);
obstacles |= ((uint64_t) 1) << (state.p2_blue & 63);
obstacles |= ((uint64_t) 1) << (state.p3_blue & 63);
obstacles |= ((uint64_t) 1) << (state.p4_blue & 63);
cout << obstacles << endl; // MOVE THE PENGUIN
move_penguin(peng, rel_move);
}
// END CAN_WE PLAY. We will now compute the moves for every penguin and for the player.
uint64_t obstacles = create_obstacles_bitboard();
state.nb_moves_red = 0; state.nb_moves_red = 0;
state.nb_moves_blue = 0; state.nb_moves_blue = 0;
state.nb_moves_red += update_moves(&state.p1_red, obstacles);
state.nb_moves_red += update_moves(&state.p2_red, obstacles); if (state.current_player_red) //Red just played
state.nb_moves_red += update_moves(&state.p3_red, obstacles); {
state.nb_moves_red += update_moves(&state.p4_red, obstacles); if(state.canPlay_blue) //If blue couldn't play last turn there is no way he could play this new turn
state.nb_moves_blue += update_moves(&state.p1_blue, obstacles); {
state.nb_moves_blue += update_moves(&state.p2_blue, obstacles); for(int i = 0; i < 4; i++)
state.nb_moves_blue += update_moves(&state.p3_blue, obstacles); state.nb_moves_blue += update_penguin_moves(&state.peng_blue[i], obstacles);
state.nb_moves_blue += update_moves(&state.p4_blue, obstacles); if (state.nb_moves_blue == 0)
{
//Change player if the other one can play state.canPlay_blue = false;
if(state.current_player_red && state.nb_moves_blue > 0) state.nb_moves_blue = 1; //We create an artificial move so that the mcts works
}
}
else
{
state.nb_moves_blue = 1; //We create an artificial move so that the mcts works
}
state.current_player_red = false; state.current_player_red = false;
else if(state.current_player_red == false && state.nb_moves_red > 0) }
else //Blue just played
{
if(state.canPlay_red)
{
for(int i = 0; i < 4; i++)
state.nb_moves_red += update_penguin_moves(&state.peng_red[i], obstacles);
if (state.nb_moves_red == 0)
{
state.canPlay_red = false;
state.nb_moves_red = 1;
}
}
else
{
state.nb_moves_red = 1;
}
state.current_player_red = true; state.current_player_red = true;
}
} }
string penguin::player_to_string(uint8_t player) const string penguin::player_to_string(uint8_t player) const
...@@ -381,34 +379,31 @@ namespace game ...@@ -381,34 +379,31 @@ namespace game
{ {
} }
Json::Value penguin::to_JSON() const json penguin::to_JSON() const
{ {
Json::Value json; json json_state;
json["bitboards"]["onefish"] = state.one_fish; json_state["bitboards"]["onefish"] = state.one_fish;
json["bitboards"]["twofish"] = state.two_fish; json_state["bitboards"]["twofish"] = state.two_fish;
json["bitboards"]["threefish"] = state.three_fish; json_state["bitboards"]["threefish"] = state.three_fish;
json["penguins"]["red"][0] = state.p1_red; for(int i = 0; i < 4; i++)
json["penguins"]["red"][1] = state.p2_red; {
json["penguins"]["red"][2] = state.p3_red; json_state["penguins"]["red"][i] = state.peng_red[i];
json["penguins"]["red"][3] = state.p4_red; json_state["penguins"]["blue"][i] = state.peng_blue[i];
json["penguins"]["blue"][0] = state.p1_blue; }
json["penguins"]["blue"][1] = state.p2_blue;
json["penguins"]["blue"][2] = state.p3_blue; json_state["score"]["red"] = state.score_red;
json["penguins"]["blue"][3] = state.p4_blue; json_state["score"]["blue"] = state.score_blue;
json["score"]["red"] = state.score_red; json_state["possible_moves"]["red"] = state.nb_moves_red;
json["score"]["blue"] = state.score_blue; json_state["possible_moves"]["blue"] = state.nb_moves_blue;
json["possible_moves"]["red"] = state.nb_moves_red; json_state["current_player"] = state.current_player_red ? "Red" : "Blue";
json["possible_moves"]["blue"] = state.nb_moves_blue;
json_state["can_play"]["red"] = state.canPlay_red;
json["current_player"] = state.current_player_red ? "Red" : "Blue"; json_state["can_play"]["blue"] = state.canPlay_blue;
json["nb_moves"]["red"] = state.nb_moves_red; return json_state;
json["nb_moves"]["blue"] = state.nb_moves_blue;
return json;
} }
string penguin::to_string() const string penguin::to_string() const
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
#define __PENGUIN_HPP__ #define __PENGUIN_HPP__
#include "game.hpp" #include "game.hpp"
#include "json.h" #include "json.hpp"
using json = nlohmann::json;
#include <random> #include <random>
#include <array> #include <array>
#include <iostream> #include <iostream>
...@@ -12,29 +13,36 @@ namespace game ...@@ -12,29 +13,36 @@ namespace game
{ {
struct penguin_state struct penguin_state
{ {
uint64_t one_fish = 0x7F59398348146BD; //Position of one-fish tiles (bitboard) uint64_t one_fish = 1152921504606846975; //Position of one-fish tiles (bitboard)
uint64_t two_fish = 0x86C628366B102; //Position of two-fish tiles (bitboard) uint64_t two_fish = 0; //Position of two-fish tiles (bitboard)
uint64_t three_fish = 0x802000548180840; //Position of three-fish tiles (bitboard) uint64_t three_fish = 0; //Position of three-fish tiles (bitboard)
//Penguins //Penguins
uint32_t p1_red = 0; uint32_t peng_red[4] = {0, 1, 6, 7};
uint32_t p2_red = 1; uint32_t peng_blue[4] = {59, 58, 53, 54};
uint32_t p3_red = 8;
uint32_t p4_red = 9;
uint32_t p1_blue = 51;
uint32_t p2_blue = 52;
uint32_t p3_blue = 58;
uint32_t p4_blue = 59;
int score_red = 0; int score_red = 0;
int score_blue = 0; int score_blue = 0;
bool current_player_red = false; //True if red must play now bool current_player_red = true; //True if red must play now. Red always starts
int nb_moves_red = 0; //Number of moves the red player can play int nb_moves_red = 0; //Number of moves the red player can play
int nb_moves_blue = 0; int nb_moves_blue = 0;
bool canPlay_red = true;
bool canPlay_blue = true;
}; };
// Useful macros to get values out of penguins
#define PENGUIN_POS(penguin) ((penguin) & 63)
#define PENGUIN_TOT_MOVES(penguin) (((penguin) >> 6) & 63)
#define PENGUIN_MOVES_A(penguin) (((penguin) >> 12) & 7)
#define PENGUIN_MOVES_B(penguin) (((penguin) >> 15) & 7)
#define PENGUIN_MOVES_C(penguin) (((penguin) >> 18) & 7)
#define PENGUIN_MOVES_D(penguin) (((penguin) >> 21) & 7)
#define PENGUIN_MOVES_E(penguin) (((penguin) >> 24) & 7)
#define PENGUIN_MOVES_F(penguin) (((penguin) >> 27) & 7)
class penguin : public game<penguin_state> class penguin : public game<penguin_state>
{ {
public: public:
...@@ -52,7 +60,7 @@ namespace game ...@@ -52,7 +60,7 @@ namespace game
void undo(std::uint16_t m) {} void undo(std::uint16_t m) {}
std::string player_to_string(std::uint8_t player) const; //String representation of a player 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 move_to_string(std::uint16_t m) const; //String representation of a move (for example, A1)
Json::Value to_JSON() const; json to_JSON() const;
std::string to_string() const; //String representation of the entire game std::string to_string() const; //String representation of the entire game
std::set<int> to_input_vector() const; std::set<int> to_input_vector() const;
void from_input_vector(const std::set<int>& input); void from_input_vector(const std::set<int>& input);
...@@ -61,16 +69,16 @@ namespace game ...@@ -61,16 +69,16 @@ namespace game
std::shared_ptr<game<penguin_state>> do_copy() const; std::shared_ptr<game<penguin_state>> do_copy() const;
std::uint64_t hash(std::uint16_t m) const; std::uint64_t hash(std::uint16_t m) const;
std::uint64_t hash() const; std::uint64_t hash() const;
private: private:
penguin_state state; penguin_state state;
uint32_t* penguin_that_moves(uint16_t move_number); void move_penguin(uint32_t* p, uint16_t rel_move);
void move_penguin(uint32_t* p); uint64_t create_obstacles_bitboard();
int update_moves(uint32_t* p, uint64_t obstacles); int update_penguin_moves(uint32_t* p, uint64_t obstacles);
const uint8_t RED = 0; const uint8_t RED = 0;
const uint8_t BLUE = 1; const uint8_t BLUE = 1;
}; };
std::ostream& operator<<(std::ostream& os, const penguin& pen); std::ostream& operator<<(std::ostream& os, const penguin& pen);
} }
......
...@@ -64,7 +64,7 @@ namespace game ...@@ -64,7 +64,7 @@ namespace game
std::string move; std::string move;
std::cin >> move; std::cin >> move;
g.play(m[move]); g.play(m[move]);
player = 1 - player; player = g.current_player();
} }
std::cout << g.to_string() << std::endl; std::cout << g.to_string() << std::endl;
if (g.won(0)) std::cout << g.player_to_string(0) << " won"; if (g.won(0)) std::cout << g.player_to_string(0) << " won";
......
This diff is collapsed.
/**
* Artificial Intelligence for the Penguin Game project.
* https://gitlab.insa-rennes.fr/francesco-bariatti/pingouins
* This AI, with the exception of game/penguin.hpp and game/penguin.cpp has been written by Pascal Garcia
* Copyright (C) 2016 Pascal Garcia
* It is licensed under the MIT license: you can find a copy in the file LICENSE.txt shipped with the whole project.
* ------------------------------------------------------------------------------------------------------------------------
* game/penguin.hpp and game/penguin.cpp have been written by Francesco Bariatti, Adrien Gasté, Mikael Le, Romain Lebouc.
* Copyright (C) 2016 Francesco Bariatti < francesco.bariatti@insa-rennes.fr >, Adrien Gasté < adrien.gaste@insa-rennes.fr >, Mikael Le < mikael.le@insa-rennes.fr >, Romain Lebouc < romain.lebouc@insa-rennes.fr >
* They are also licensed under the MIT license: you can find a copy in the file LICENSE.txt shipped with the whole project.
* -------------------------------------------------------------------------------------------------------------------------------------
* This program uses the jsoncpp library.
* You can find a copy of the library at https://github.com/open-source-parsers/jsoncpp
* The library is licensed under MIT license.
* Copyright (c) 2007-2010 Baptiste Lepilleur
*/
#include "penguin.hpp"
#include "test_two_players_game.hpp"
#include "test_fast_log.hpp"
#include "test_allocator.hpp"
#include "test_mcts_two_players.hpp"
#include "test_bits.hpp"
#include "learning.hpp"
#include <omp.h>
using namespace std;
int main(int argc, char *argv[])
{
// util::test_fast_log(100000000);
// mcts::test_allocator(10, 2);
// omp_set_num_threads(8);
//game::run_test_two_players_game(game::penguin());
mcts::run_test_mcts_two_players(game::penguin());
//util::test_bits(200000000);
return 0;
}
#ifndef __MCTS_SETTINGS_HPP__
#define __MCTS_SETTINGS_HPP__
// Allocated memory for the mcts. If not enough the program may crash
#define MCTS_ALLOCATOR_SIZE 1000000U
// Reflection time for every turn of the mcts (in ms)
#define MCTS_TURN_TIME 5000
#endif
File moved
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __ALLOCATOR_HPP__ #define __ALLOCATOR_HPP__
#include "node.hpp" #include "node.hpp"
#include "MCTS_SETTINGS.hpp"
namespace mcts namespace mcts
{ {
...@@ -15,7 +16,7 @@ namespace mcts ...@@ -15,7 +16,7 @@ namespace mcts
void copy(node* n1, node* n2, unsigned int prunning = 0); void copy(node* n1, node* n2, unsigned int prunning = 0);
public: public:
allocator(unsigned int size = 10000000U); allocator(unsigned int size = MCTS_ALLOCATOR_SIZE);
~allocator(); ~allocator();
node* allocate(unsigned int size); node* allocate(unsigned int size);
void clear(); void clear();
......
File moved
...@@ -265,7 +265,7 @@ namespace mcts ...@@ -265,7 +265,7 @@ namespace mcts
} }
else else
{ {
this->root = alloc_.move(&this->root->get_children()[move]); this->root = alloc_.move(&this->root->get_children()[move], 20);
} }
} }
......
File moved
File moved