diff --git a/AI/src/game/penguin.cpp b/AI/src/game/penguin.cpp
index 29c6f7478ab4d69608a0b480c93187c903c24523..4eabcfcb948900bd2bdf54a779a8dcef4b71314d 100644
--- a/AI/src/game/penguin.cpp
+++ b/AI/src/game/penguin.cpp
@@ -28,17 +28,13 @@ namespace game
 		{
 			if(json_state["penguins"].count("red"))
 			{
-				state.p1_red = json_state["penguins"]["red"][0];
-				state.p2_red = json_state["penguins"]["red"][1];
-				state.p3_red = json_state["penguins"]["red"][2];
-				state.p4_red = json_state["penguins"]["red"][3];
+				for(int i = 0; i < 4; i++)
+					state.peng_red[i] = json_state["penguins"]["red"][i];
 			}
 			if(json_state["penguins"].count("blue"))
 			{
-				state.p1_blue = json_state["penguins"]["blue"][0];
-				state.p2_blue = json_state["penguins"]["blue"][1];
-				state.p3_blue = json_state["penguins"]["blue"][2];
-				state.p4_blue = json_state["penguins"]["blue"][3];
+				for(int i = 0; i < 4; i++)
+					state.peng_blue[i] = json_state["penguins"]["blue"][i];
 			}
 		}
 		if(json_state.count("score"))
@@ -46,29 +42,16 @@ namespace game
 			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"]; }
 		}
-
-		//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);
-
+		// We compute the moves for all penguin
+		uint64_t obstacles = create_obstacles_bitboard();
 		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);
 
+		for(int i = 0; i < 4; i++)
+		{
+			state.nb_moves_red += update_penguin_moves(&state.peng_red[i], obstacles);
+			state.nb_moves_blue += update_penguin_moves(&state.peng_blue[i], obstacles);
+		}
 		if (state.nb_moves_red == 0)
 		{
 			state.canPlay_red = false;
@@ -139,140 +122,81 @@ 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)
+	/*
+		Moves the penguin p (modify its position value), making it do its rel_move move.
+		At the end of the function the penguin will be composed of just its new position (every other bit is at 0)
+	*/
+	void penguin::move_penguin(uint32_t* p, uint16_t rel_move)
 	{
-		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)
+		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
-			(*p) = (7 * (move_number +1)) + ((*p) & 63);
+			(*p) = (7 * (rel_move +1)) + ((*p) & 63);
 			return;
 		}
-		move_number -= penguin_copy & 7;
-		penguin_copy = penguin_copy >> 3;
-		if((penguin_copy & 7) > move_number)
+		rel_move -= PENGUIN_MOVES_A(*p);
+		if(PENGUIN_MOVES_B(*p) > rel_move)
 		{
 			//Move direction B
-			(*p) = (-1 * (move_number +1)) + ((*p) & 63);
+			(*p) = (-1 * (rel_move +1)) + ((*p) & 63);
 			return;
 		}
-		move_number -= penguin_copy & 7;
-		penguin_copy = penguin_copy >> 3;
-		if((penguin_copy & 7) > move_number)
+		rel_move -= PENGUIN_MOVES_B(*p);
+		if(PENGUIN_MOVES_C(*p) > rel_move)
 		{
 			//Move direction C
-			(*p) = (-8 * (move_number +1)) + ((*p) & 63);
+			(*p) = (-8 * (rel_move +1)) + ((*p) & 63);
 			return;
 		}
-		move_number -= penguin_copy & 7;
-		penguin_copy = penguin_copy >> 3;
-		if((penguin_copy & 7) > move_number)
+		rel_move -= PENGUIN_MOVES_C(*p);
+		if(PENGUIN_MOVES_D(*p) > rel_move)
 		{
 			//Move direction D
-			(*p) = (-7 * (move_number +1)) + ((*p) & 63);
+			(*p) = (-7 * (rel_move +1)) + ((*p) & 63);
 			return;
 		}
-		move_number -= penguin_copy & 7;
-		penguin_copy = penguin_copy >> 3;
-		if((penguin_copy & 7) > move_number)
+		rel_move -= PENGUIN_MOVES_D(*p);
+		if(PENGUIN_MOVES_E(*p) > rel_move)
 		{
 			//Move direction E
-			(*p) = (1 * (move_number +1)) + ((*p) & 63);
+			(*p) = (1 * (rel_move +1)) + ((*p) & 63);
 			return;
 		}
-		move_number -= penguin_copy & 7;
-		penguin_copy = penguin_copy >> 3;
+		rel_move -= PENGUIN_MOVES_E(*p);
 		//Move direction F
-		(*p) = (8 * (move_number +1)) + ((*p) & 63);
+		(*p) = (8 * (rel_move +1)) + ((*p) & 63);
+	}
+
+	/* 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()
+	{
+		uint64_t obstacles = (~(state.one_fish | state.two_fish | state.three_fish));
+		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;
 	}
 
-	int penguin::update_moves(uint32_t* p, uint64_t 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 = (*p) & 63;
+		#define IsFree(i) (((obstacles >> (i)) & 1) == 0)
+		int pos = PENGUIN_POS(*p);
 		(*p) = pos; //Reset the penguin to all zeros except the position
 		int i = pos;
-		uint32_t nbmoves = 0;
+		uint32_t nbmoves = 0; //Nb of moves in one direction
 		uint32_t total_moves = 0;
 
 		//Direction A
@@ -335,68 +259,74 @@ 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 */
+				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];
+			}
 
-			//Find the value of the tile the penguin is on and update score
-			if ((state.one_fish >> position) & 1)
+			// ADD PENGUIN TILE TO THE SCORE
+			if((state.one_fish >> PENGUIN_POS(*peng)) & 1) //If there is a one fish on this position
 			{
-				if(current_player() == RED)
+				if(state.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);
+				state.one_fish = state.one_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
 			}
-			else if ((state.two_fish >> position) & 1)
+			else if((state.two_fish >> PENGUIN_POS(*peng)) & 1)
 			{
-
-				if(current_player() == RED)
+				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) << position);
+				state.two_fish = state.two_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
 			}
 			else
 			{
-				if(current_player() == RED)
+				if(state.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);
+				state.three_fish = state.three_fish & ~(((uint64_t) 1) << PENGUIN_POS(*peng));
 			}
 
-			//Move the current penguin
-			move_penguin(p);
+			// MOVE THE PENGUIN
+			move_penguin(peng, rel_move);
 		}
-
-		//Update moves on all penguins of the next player
-		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);
+		// 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_blue = 0;
 
 		if (state.current_player_red) //Red just played
 		{
-			if(state.canPlay_blue)
+			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);
-				state.nb_moves_blue += update_moves(&state.p3_blue, obstacles);
-				state.nb_moves_blue += update_moves(&state.p4_blue, obstacles);
+				for(int i = 0; i < 4; i++)
+					state.nb_moves_blue += update_penguin_moves(&state.peng_blue[i], obstacles);
 				if (state.nb_moves_blue == 0)
 				{
 					state.canPlay_blue = false;
@@ -405,19 +335,16 @@ namespace game
 			}
 			else
 			{
-				state.nb_moves_blue = 1;
+				state.nb_moves_blue = 1; //We create an artificial move so that the mcts works
 			}
-
 			state.current_player_red = false;
 		}
 		else //Blue just played
 		{
 			if(state.canPlay_red)
 			{
-				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);
+				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;
@@ -428,7 +355,6 @@ namespace game
 			{
 				state.nb_moves_red = 1;
 			}
-
 			state.current_player_red = true;
 		}
 	}
@@ -460,14 +386,11 @@ namespace game
 		json_state["bitboards"]["twofish"] = state.two_fish;
 		json_state["bitboards"]["threefish"] = state.three_fish;
 
-		json_state["penguins"]["red"][0] = state.p1_red;
-		json_state["penguins"]["red"][1] = state.p2_red;
-		json_state["penguins"]["red"][2] = state.p3_red;
-		json_state["penguins"]["red"][3] = state.p4_red;
-		json_state["penguins"]["blue"][0] = state.p1_blue;
-		json_state["penguins"]["blue"][1] = state.p2_blue;
-		json_state["penguins"]["blue"][2] = state.p3_blue;
-		json_state["penguins"]["blue"][3] = state.p4_blue;
+		for(int i = 0; i < 4; i++)
+		{
+			json_state["penguins"]["red"][i] = state.peng_red[i];
+			json_state["penguins"]["blue"][i] = state.peng_blue[i];
+		}
 
 		json_state["score"]["red"] = state.score_red;
 		json_state["score"]["blue"] = state.score_blue;
diff --git a/AI/src/game/penguin.hpp b/AI/src/game/penguin.hpp
index e1364fc8ffec7d84809fb8fba33859fbeea41855..50d2e91fe784e064bbdf828339b4d7dfd57b1193 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,32 +13,36 @@ 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 p1_red = 0;
-		uint32_t p2_red = 1;
-		uint32_t p3_red = 6;
-		uint32_t p4_red = 7;
-		uint32_t p1_blue = 59;
-		uint32_t p2_blue = 58;
-		uint32_t p3_blue = 53;
-		uint32_t p4_blue = 54;
-		
+		uint32_t peng_red[4] = {0, 1, 6, 7};
+		uint32_t peng_blue[4] = {59, 58, 53, 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;
 	};
-	
+
+	// 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>
 	{
 		public:
@@ -65,16 +69,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:
 			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);
-			
+			void move_penguin(uint32_t* p, uint16_t rel_move);
+			uint64_t create_obstacles_bitboard();
+			int update_penguin_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);
 }