From 89b75ea608983ce3bb34fd2a811cbd13a7400ac6 Mon Sep 17 00:00:00 2001
From: Francesco Bariatti <francesco.bariatti@insa-rennes.fr>
Date: Tue, 17 May 2016 18:20:31 +0200
Subject: [PATCH] Changed implementation of penguin_that_moves for penguin
 arrays. Deleted the function and integrated the code in play function

---
 AI/src/game/penguin.cpp | 110 ++++++++++------------------------------
 AI/src/game/penguin.hpp |  23 ++++-----
 2 files changed, 39 insertions(+), 94 deletions(-)

diff --git a/AI/src/game/penguin.cpp b/AI/src/game/penguin.cpp
index a5e2a14..bec187b 100644
--- a/AI/src/game/penguin.cpp
+++ b/AI/src/game/penguin.cpp
@@ -135,84 +135,6 @@ namespace game
 		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:
-	 *		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
@@ -331,13 +253,36 @@ namespace game
 	//Play the mth move in the possible moves list.
 	void penguin::play(uint16_t m)
 	{
+		//CAN WE PLAY?
+		// 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)
 		if ((state.current_player_red == true && state.canPlay_red) || ((state.current_player_red == false) && state.canPlay_blue))
 		{
-			//Find which penguin will move
-			uint32_t* p = penguin_that_moves(m);
-			uint8_t position = (*p) & 63;
+			//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 */
+				#define TOT_MOVES(penguin) ((penguin >> 6) & 63)
+				for(i = 0; (i < 3) && (TOT_MOVES(state.peng_red[i]) <= rel_move); i ++) //While we didn't find the penguin
+					rel_move -= 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
+			{
+				#define TOT_MOVES(penguin) ((penguin >> 6) & 63)
+				for(i = 0; (i < 3) && (TOT_MOVES(state.peng_blue[i]) <= rel_move); i ++) //While we didn't find the penguin
+					rel_move -= TOT_MOVES(state.peng_blue[i]);
+				peng = &state.peng_blue[i];
+			}
+
+			// ADD PENGUIN TILE TO THE SCORE
 
-			//Find the value of the tile the penguin is on and update score
+			/*
+			//TODO: implements methods with arrays
 			if ((state.one_fish >> position) & 1)
 			{
 				if(current_player() == RED)
@@ -369,6 +314,7 @@ namespace game
 
 			//Move the current penguin
 			move_penguin(p);
+			*/
 		}
 
 		//Update moves on all penguins of the next player
diff --git a/AI/src/game/penguin.hpp b/AI/src/game/penguin.hpp
index 2309b7f..1ec2fec 100644
--- a/AI/src/game/penguin.hpp
+++ b/AI/src/game/penguin.hpp
@@ -4,7 +4,7 @@
 #include "game.hpp"
 #include "json.hpp"
 using json = nlohmann::json;
-#include <random> 
+#include <random>
 #include <array>
 #include <iostream>
 #include <memory>
@@ -13,10 +13,10 @@ namespace game
 {
 	struct penguin_state
 	{
-		uint64_t one_fish = 1152921504606846975; //Position of one-fish tiles (bitboard) 
+		uint64_t one_fish = 1152921504606846975; //Position of one-fish tiles (bitboard)
 		uint64_t two_fish = 0; //Position of two-fish tiles (bitboard)
 		uint64_t three_fish = 0; //Position of three-fish tiles (bitboard)
-		
+
 		//Penguins
 		uint32_t peng_red[4] = {0, 1, 6, 7};
 		uint32_t peng_blue[4] = {59, 58, 53, 54};
@@ -29,19 +29,19 @@ namespace game
 		uint32_t p2_blue = 58;
 		uint32_t p3_blue = 53;
 		uint32_t p4_blue = 54;
-		
+
 		int score_red = 0;
 		int score_blue = 0;
-		
+
 		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_blue = 0;
-		
+
 		bool canPlay_red = true;
 		bool canPlay_blue = true;
 	};
-	
+
 	class penguin : public game<penguin_state>
 	{
 		public:
@@ -68,17 +68,16 @@ namespace game
 			std::shared_ptr<game<penguin_state>> do_copy() const;
 			std::uint64_t hash(std::uint16_t m) const;
 			std::uint64_t hash() const;
-			
+
 		private:
 			//TODO: modify/delete functions
 			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);
-			
+
 			const uint8_t RED = 0;
 			const uint8_t BLUE = 1;
-			
+
 	};
 	std::ostream& operator<<(std::ostream& os, const penguin& pen);
 }
-- 
GitLab