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

Created function play

parent 7bbf54c1
No related branches found
No related tags found
No related merge requests found
......@@ -7,6 +7,33 @@ namespace game
{
penguin::penguin()
{
//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);
state.nb_moves_red = 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);
state.nb_moves_red += update_moves(&state.p3_red, obstacles);
state.nb_moves_red += update_moves(&state.p4_red, obstacles);
state.nb_moves_blue += update_moves(&state.p1_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p2_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p3_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p4_blue, obstacles);
//Change player if the other one can play
if(state.current_player_red && state.nb_moves_blue > 0)
state.current_player_red = false;
else if(state.current_player_red == false && state.nb_moves_red > 0)
state.current_player_red = true;
}
shared_ptr<game<penguin_state>> penguin::do_copy() const
......@@ -68,24 +95,267 @@ namespace game
return 0;
}
/* The penguin that will move if we want to play the #move_number move in the list of possible moves.
* What this function does:
* Find the penguin that will move.
* 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
* */
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
if((penguin_copy & 7) >= move_number)
{
//Move direction A
(*p) = (7 * move_number) + ((*p) & 63);
return;
}
move_number -= penguin_copy & 7;
penguin_copy = penguin_copy >> 3;
if((penguin_copy & 7) >= move_number)
{
//Move direction B
(*p) = (-1 * move_number) + ((*p) & 63);
return;
}
move_number -= penguin_copy & 7;
penguin_copy = penguin_copy >> 3;
if((penguin_copy & 7) >= move_number)
{
//Move direction C
(*p) = (-8 * move_number) + ((*p) & 63);
return;
}
move_number -= penguin_copy & 7;
penguin_copy = penguin_copy >> 3;
if((penguin_copy & 7) >= move_number)
{
//Move direction D
(*p) = (-7 * move_number) + ((*p) & 63);
return;
}
move_number -= penguin_copy & 7;
penguin_copy = penguin_copy >> 3;
if((penguin_copy & 7) >= move_number)
{
//Move direction E
(*p) = (1 * move_number) + ((*p) & 63);
return;
}
move_number -= penguin_copy & 7;
penguin_copy = penguin_copy >> 3;
//Move direction F
(*p) = (8 * move_number) + ((*p) & 63);
}
int penguin::update_moves(uint32_t* p, uint64_t obstacles)
{
#define IsFree(i) (((obstacles >> (i)) & 1) == 0)
int pos = (*p) & 63;
(*p) = pos; //Reset the penguin to all zeros except the position
int i = pos;
uint32_t nbmoves = 0;
uint32_t total_moves = 0;
//Direction A
while(((i+7) < 60) && (i%15 != 0) && IsFree(i+7))
{
i += 7;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 12;
//Direction B
nbmoves = 0;
i = pos;
while((i%15 != 0) && (i%15 != 8) && IsFree(i-1))
{
i --;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 15;
//Direction C
nbmoves = 0;
i = pos;
while((i-8 > 0) && (i%15 != 0) && IsFree(i-8))
{
i -= 8;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 18;
//Direction D
nbmoves = 0;
i = pos;
while((i-7 > 0) && (i%15 != 7) && IsFree(i-7))
{
i -= 7;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 21;
//Direction E
nbmoves = 0;
i = pos;
while((i%15 != 7) && (i%15 != 14) && IsFree(i+1))
{
i ++;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 24;
//Direction F
nbmoves = 0;
i = pos;
while((i+8 < 60) && (i%15 != 7) && IsFree(i+8))
{
i += 8;
nbmoves++; total_moves++;
}
(*p) = (*p) | nbmoves << 27;
(*p) = (*p) | total_moves << 6;
return total_moves;
}
//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);
//Find which penguin will move
uint32_t* p = penguin_that_moves(m);
uint8_t position = (*p) & 63;
//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)
{
if(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) << position);
}
else
state.circle_bitboard |= (((uint16_t) 1) << move);
{
if(current_player() == RED)
state.score_red += 3;
else
state.score_blue += 3;
//We replace this tile with an empty one (0 in the bitboard)
state.three_fish = state.three_fish & ~(((uint64_t) 1) << position);
}
//Move the current penguin
move_penguin(p);
//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);
state.nb_moves_red = 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);
state.nb_moves_red += update_moves(&state.p3_red, obstacles);
state.nb_moves_red += update_moves(&state.p4_red, obstacles);
state.nb_moves_blue += update_moves(&state.p1_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p2_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p3_blue, obstacles);
state.nb_moves_blue += update_moves(&state.p4_blue, obstacles);
//Change player if the other one can play
if(state.current_player_red && state.nb_moves_blue > 0)
state.current_player_red = false;
else if(state.current_player_red == false && state.nb_moves_red > 0)
state.current_player_red = true;
//State update
state.total_moves++;
update_win();
update_moves();
return;*/
}
string penguin::player_to_string(uint8_t player) const
......
......@@ -28,7 +28,7 @@ namespace game
int score_red = 0;
int score_blue = 0;
bool current_player_red = true; //True if red must play now
bool current_player_red = false; //True if red must play now
int nb_moves_red = 0; //Number of moves the red player can play
int nb_moves_blue = 0;
......@@ -62,9 +62,12 @@ namespace game
private:
penguin_state state;
uint32_t* penguin_that_moves(uint16_t move_number);
void move_penguin(uint32_t* p);
int update_moves(uint32_t* p, uint64_t obstacles);
uint8_t RED = 0;
uint8_t BLUE = 1;
const uint8_t RED = 0;
const uint8_t BLUE = 1;
};
std::ostream& operator<<(std::ostream& os, const penguin& pen);
......
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