From d1cbcd4ea78e6f4ba14f581c820ad087434ef656 Mon Sep 17 00:00:00 2001 From: Francesco Bariatti <francesco.bariatti@insa-rennes.fr> Date: Mon, 29 Feb 2016 16:15:14 +0100 Subject: [PATCH] Created function play --- src/game/penguin.cpp | 296 +++++++++++++++++++++++++++++++++++++++++-- src/game/penguin.hpp | 9 +- 2 files changed, 289 insertions(+), 16 deletions(-) diff --git a/src/game/penguin.cpp b/src/game/penguin.cpp index b454264..421dce6 100644 --- a/src/game/penguin.cpp +++ b/src/game/penguin.cpp @@ -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 diff --git a/src/game/penguin.hpp b/src/game/penguin.hpp index c9c8c0a..a74bb82 100644 --- a/src/game/penguin.hpp +++ b/src/game/penguin.hpp @@ -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); -- GitLab