2026-02-02 16:43:43 +05:30
using TMPro ;
2026-01-22 20:50:41 +05:30
using System ;
2026-01-21 20:27:45 +05:30
using System.Linq ;
2026-01-29 18:13:07 +05:30
using DG.Tweening ;
2026-01-21 20:27:45 +05:30
using UnityEngine ;
2026-02-02 16:43:43 +05:30
using System.Collections.Generic ;
2026-01-21 20:27:45 +05:30
2026-01-27 20:55:55 +05:30
public enum BotMove
{
FinishingPathMove = 0 ,
SafeMove = 1 ,
AttackMove = 2 ,
NormalMove = 3 ,
NoMoves = 4
}
2026-01-21 20:27:45 +05:30
public class GameplayManager : MonoBehaviour , IBase , IBootLoader , IDataLoader
{
2026-01-31 20:33:50 +05:30
[SerializeField] private bool isDebugTest = false ;
public bool IsDebugTest = > isDebugTest ;
2026-01-30 09:35:31 +05:30
[SerializeField] DiceRollHandler diceRollHandler ;
2026-01-28 20:57:35 +05:30
[SerializeField] private int diceValue = 0 ;
2026-01-31 20:33:50 +05:30
[SerializeField] private int maxDiceSixRollCounter = 2 ;
2026-02-02 16:06:29 +05:30
[SerializeField] private int totalStepsForCharacter = 57 ;
2026-01-28 20:57:35 +05:30
2026-01-26 19:48:55 +05:30
[SerializeField] private TextMeshProUGUI diceText ;
2026-02-04 12:09:04 +05:30
#if UNITY_EDITOR
2026-01-21 20:27:45 +05:30
[SerializeField] private Transform pointerDebug ;
[SerializeField] private MeshRenderer pointerMeshRend ;
[SerializeField] private Material turnMat ;
[SerializeField] private Material selectMat ;
2026-02-04 12:09:04 +05:30
#endif
2026-01-21 20:27:45 +05:30
[SerializeField] private PlayerGameData [ ] playerGameDatas ;
2026-01-23 15:32:48 +05:30
[SerializeField] private PlayerBaseHandler playerBaseHandler ;
2026-01-21 20:27:45 +05:30
2026-01-30 22:17:18 +05:30
public PlayerType CurrentPlayerTypeTurn = > currentPlayerTypeTurn ;
2026-02-02 19:27:17 +05:30
public PlayerBaseHandler PlayerBaseHandler = > playerBaseHandler ;
private PlayerType currentPlayerTypeTurn ;
2026-01-21 20:27:45 +05:30
private int currentPlayerTurnIndex = 0 ;
2026-01-30 21:51:33 +05:30
2026-01-27 20:55:55 +05:30
private List < PlayerType > allPlayerTypes = new List < PlayerType > ( ) ;
private List < PlayerType > botTypesInGame = new List < PlayerType > ( ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 21:51:33 +05:30
private List < PlayerData > playerDatas = new List < PlayerData > ( ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 21:51:33 +05:30
private Dictionary < PlayerType , PlayerGameData > playerGameDatasDict = new Dictionary < PlayerType , PlayerGameData > ( ) ;
2026-01-30 19:04:14 +05:30
private Dictionary < PlayerType , Dictionary < int , BotMove > > botRuntimeMovementData = new Dictionary < PlayerType , Dictionary < int , BotMove > > ( ) ;
2026-01-27 20:55:55 +05:30
2026-02-02 20:12:00 +05:30
public TilesManager TilesManager
{
get ; private set ;
}
2026-01-30 22:17:18 +05:30
private UIManager uIManager ;
2026-01-30 21:51:33 +05:30
private GameManager gameManager ;
2026-02-02 17:21:38 +05:30
private GameModeHandler gameModeHandler ;
2026-01-21 20:27:45 +05:30
private int diceRolledValue ;
2026-01-22 20:50:41 +05:30
private bool CanRollDiceAgain = false ; // used for when you get a 6 or when you reach the finish point
2026-01-29 21:15:48 +05:30
private int diceSixRollCounter = 0 ;
2026-01-21 20:27:45 +05:30
2026-01-30 09:35:31 +05:30
private List < PlayerPawn > availPlayers = new List < PlayerPawn > ( ) ;
private bool canSwitchPlayer = false ;
2026-01-30 11:30:40 +05:30
public bool CanRollDiceForUser
2026-01-30 09:35:31 +05:30
{
get ; private set ;
}
2026-01-30 21:51:33 +05:30
public int TotalPlayersInGame
{
get ; private set ;
}
public List < PlayerData > PlayerDatas = > playerDatas ;
2026-01-30 09:35:31 +05:30
public List < PlayerType > PlayerTypesCollection = > allPlayerTypes ;
2026-01-30 19:04:14 +05:30
2026-01-21 20:27:45 +05:30
public void Initialize ( )
{
InterfaceManager . Instance ? . RegisterInterface < GameplayManager > ( this ) ;
2026-01-29 18:13:07 +05:30
DOTween . useSafeMode = false ;
2026-01-21 20:27:45 +05:30
}
public void InitializeData ( )
{
2026-02-02 20:12:00 +05:30
TilesManager = InterfaceManager . Instance . GetInterfaceInstance < TilesManager > ( ) ;
2026-01-30 22:17:18 +05:30
uIManager = InterfaceManager . Instance . GetInterfaceInstance < UIManager > ( ) ;
2026-01-30 21:51:33 +05:30
gameManager = InterfaceManager . Instance . GetInterfaceInstance < GameManager > ( ) ;
2026-02-02 17:21:38 +05:30
gameModeHandler = InterfaceManager . Instance . GetInterfaceInstance < GameModeHandler > ( ) ;
2026-01-26 19:48:55 +05:30
}
2026-01-30 21:51:33 +05:30
public void InitPlayerTypesForPVP ( List < PlayerType > types , List < string > names )
2026-01-26 19:48:55 +05:30
{
2026-01-30 11:30:40 +05:30
allPlayerTypes = new List < PlayerType > ( types ) ;
2026-02-02 17:21:38 +05:30
playerDatas = new List < PlayerData > ( ) ;
2026-01-30 21:51:33 +05:30
TotalPlayersInGame = types . Count ;
for ( int i = 0 ; i < types . Count ; i + + )
{
playerDatas . Add ( new PlayerData
{
playerType = types [ i ] ,
playerName = names [ i ] ,
} ) ;
}
2026-01-23 15:32:48 +05:30
2026-02-02 20:12:00 +05:30
TilesManager . InitTilesData ( ) ;
2026-01-30 22:06:51 +05:30
2026-01-27 20:55:55 +05:30
playerBaseHandler . InitPlayerTypes ( allPlayerTypes ) ;
2026-01-23 15:32:48 +05:30
InitCurrentGamePlayerInfo ( ) ;
2026-01-30 12:54:43 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-30 21:51:33 +05:30
public void InitPlayerTypesForBotMatch ( PlayerData selectedPlayerData , int botCount )
2026-01-26 19:48:55 +05:30
{
2026-01-30 22:06:51 +05:30
playerDatas = new List < PlayerData > ( ) ;
botTypesInGame = new List < PlayerType > ( ) ;
allPlayerTypes = new List < PlayerType > ( ) ;
2026-01-27 20:55:55 +05:30
2026-01-30 21:51:33 +05:30
TotalPlayersInGame = botCount + 1 ;
AssignBotTypes ( selectedPlayerData . playerType , botCount ) ;
foreach ( PlayerType playerType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( botTypesInGame . Contains ( playerType ) )
{
allPlayerTypes . Add ( playerType ) ;
2026-01-31 00:05:18 +05:30
playerDatas . Add ( new PlayerData { playerType = playerType , playerName = $"{playerType}" } ) ;
2026-01-30 21:51:33 +05:30
}
2026-01-30 22:29:00 +05:30
else if ( selectedPlayerData . playerType = = playerType )
2026-01-30 21:51:33 +05:30
{
allPlayerTypes . Add ( selectedPlayerData . playerType ) ;
playerDatas . Add ( new PlayerData { playerType = selectedPlayerData . playerType , playerName = $"{selectedPlayerData.playerName}" } ) ;
}
}
2026-01-27 20:55:55 +05:30
2026-02-02 20:12:00 +05:30
TilesManager . InitTilesData ( ) ;
2026-01-27 20:55:55 +05:30
playerBaseHandler . InitPlayerTypes ( allPlayerTypes ) ;
InitCurrentGamePlayerInfo ( ) ;
2026-01-28 16:57:27 +05:30
InitBotRuntimeData ( ) ;
2026-01-30 21:51:33 +05:30
AssignPlayerAndBotStates ( selectedPlayerData . playerType ) ;
2026-01-30 19:04:14 +05:30
2026-01-30 21:51:33 +05:30
SetCanRollDiceForUser ( ! botTypesInGame . Contains ( allPlayerTypes [ 0 ] ) ) ;
if ( botTypesInGame . Contains ( allPlayerTypes [ 0 ] ) )
Invoke ( nameof ( HandleDiceRoll ) , 1f ) ;
2026-01-27 20:55:55 +05:30
}
private void InitBotRuntimeData ( )
{
2026-01-30 22:06:51 +05:30
botRuntimeMovementData = new Dictionary < PlayerType , Dictionary < int , BotMove > > ( ) ;
2026-01-27 20:55:55 +05:30
foreach ( var botType in botTypesInGame )
{
PlayerGameData playerGameData = playerGameDatasDict [ botType ] ;
if ( ! botRuntimeMovementData . ContainsKey ( botType ) )
{
botRuntimeMovementData . Add ( botType , new Dictionary < int , BotMove > ( ) ) ;
}
foreach ( var pawn in playerGameData . playerPawnsDict )
{
2026-01-28 16:57:27 +05:30
botRuntimeMovementData [ botType ] . Add ( pawn . Value . PlayerId , BotMove . NoMoves ) ;
2026-01-27 20:55:55 +05:30
}
}
}
private void AssignPlayerAndBotStates ( PlayerType selectedPlayerType )
{
PlayerBase playerBase = playerBaseHandler . GetPlayerBase ( selectedPlayerType ) ;
playerBase . AssignBotState ( PawnType . User ) ;
foreach ( PlayerType playerType in botTypesInGame )
{
playerBase = playerBaseHandler . GetPlayerBase ( playerType ) ;
playerBase . AssignBotState ( PawnType . Bot ) ;
}
}
private void AssignBotTypes ( PlayerType selectedPlayerType , int botCount )
{
int addedBots = 0 ;
2026-01-26 19:48:55 +05:30
if ( botCount = = 1 )
{
2026-01-27 20:55:55 +05:30
var playerType = ( PlayerType ) ( ( int ) selectedPlayerType + 2 < Enum . GetValues ( typeof ( PlayerType ) ) . Length ?
2026-01-26 19:48:55 +05:30
( int ) selectedPlayerType + 2 : ( int ) selectedPlayerType - 2 ) ;
2026-01-27 20:55:55 +05:30
botTypesInGame . Add ( playerType ) ;
}
else if ( botCount = = 2 )
{
foreach ( PlayerType enumType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( enumType = = selectedPlayerType ) continue ;
botTypesInGame . Add ( enumType ) ;
addedBots + + ;
if ( addedBots = = botCount ) break ;
}
2026-01-26 19:48:55 +05:30
}
else
{
2026-01-27 20:55:55 +05:30
foreach ( PlayerType enumType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( enumType = = selectedPlayerType ) continue ;
botTypesInGame . Add ( enumType ) ;
}
2026-01-26 19:48:55 +05:30
}
}
2026-01-23 15:32:48 +05:30
public void InitCurrentGamePlayerInfo ( )
2026-01-21 20:27:45 +05:30
{
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-31 20:33:50 +05:30
Debug . Log ( $"currentPlayerTypeTurn: {currentPlayerTypeTurn}" ) ;
2026-02-04 12:09:04 +05:30
#if UNITY_EDITOR
2026-01-31 20:33:50 +05:30
SetCurrentSelectedPointer ( ) ;
2026-02-04 12:09:04 +05:30
#endif
2026-01-21 20:27:45 +05:30
// initialize the board based on the player types
2026-01-30 22:06:51 +05:30
playerGameDatasDict = new Dictionary < PlayerType , PlayerGameData > ( ) ;
2026-01-30 21:51:33 +05:30
2026-01-21 20:27:45 +05:30
foreach ( PlayerGameData playerGameData in playerGameDatas )
{
2026-01-27 20:55:55 +05:30
if ( ! allPlayerTypes . Contains ( playerGameData . playerType ) )
2026-01-23 15:32:48 +05:30
continue ;
2026-01-21 20:27:45 +05:30
2026-01-27 20:55:55 +05:30
Debug . Log ( $"playerGameData.playerType: {playerGameData.playerType}" ) ;
2026-01-30 19:14:08 +05:30
2026-02-02 21:20:41 +05:30
playerGameDatasDict . Add (
playerGameData . playerType ,
new PlayerGameData
{
playerType = playerGameData . playerType ,
startIndex = playerGameData . startIndex ,
endIndex = playerGameData . endIndex ,
playersParent = playerGameData . playersParent ,
playerPawnsDict = new Dictionary < int , PlayerPawn > ( ) ,
totalPawnsInHome = playerGameData . totalPawnsInHome ,
totalPawnsFinished = playerGameData . totalPawnsFinished
} ) ;
2026-01-23 15:32:48 +05:30
foreach ( Transform playerPawnChild in playerGameData . playersParent )
{
if ( ! playerPawnChild . gameObject . activeInHierarchy ) continue ;
2026-01-30 19:04:14 +05:30
2026-01-27 20:55:55 +05:30
var pawn = playerPawnChild . GetComponent < PlayerPawn > ( ) ;
playerGameDatasDict [ playerGameData . playerType ] . playerPawnsDict . Add ( pawn . PlayerId , pawn ) ;
2026-01-21 20:27:45 +05:30
}
2026-02-02 21:20:41 +05:30
2026-01-28 20:57:35 +05:30
playerGameDatasDict [ playerGameData . playerType ] . totalPawnsInHome = playerGameDatasDict [ playerGameData . playerType ] . playerPawnsDict . Count ;
2026-01-21 20:27:45 +05:30
}
}
public void EnablePlayerSelectionStates ( bool state )
{
2026-01-23 12:46:59 +05:30
foreach ( var playerPawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
2026-01-21 20:27:45 +05:30
{
2026-01-27 20:55:55 +05:30
if ( playerPawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath ) continue ;
2026-01-21 20:27:45 +05:30
2026-01-27 20:55:55 +05:30
playerPawn . Value . SetPlayerSelectionState ( state ) ;
2026-01-21 20:27:45 +05:30
}
}
2026-01-30 09:35:31 +05:30
public void OnDiceInteracted ( )
2026-01-28 16:57:27 +05:30
{
2026-01-30 11:30:40 +05:30
diceRollHandler . HandleDiceViewForUser ( ) ;
2026-01-30 09:35:31 +05:30
}
2026-01-28 20:57:35 +05:30
2026-01-30 09:35:31 +05:30
public void RollDiceForPlayer ( int rolledVal )
{
2026-01-28 16:57:27 +05:30
OnDiceRolled ( rolledVal ) ;
2026-01-29 21:15:48 +05:30
OnNoMovesLeft ( ) ;
2026-01-28 16:57:27 +05:30
}
2026-01-29 21:15:48 +05:30
// Summary :: Function will be called and effective when a dice is rolled and no selection of pawns is made.
private void OnNoMovesLeft ( )
2026-01-28 16:57:27 +05:30
{
if ( canSwitchPlayer & & ! CanRollDiceAgain )
{
Debug . Log ( $"Switching player" ) ;
SwitchPlayer ( ) ;
}
2026-01-29 21:15:48 +05:30
}
private bool CheckForMaxDiceRollAttempt ( )
{
2026-01-31 20:33:50 +05:30
if ( diceSixRollCounter > maxDiceSixRollCounter ) // TODO :: Reset after test
2026-01-29 21:15:48 +05:30
{
CanRollDiceAgain = false ;
SwitchPlayer ( ) ;
return true ;
}
return false ;
2026-01-28 16:57:27 +05:30
}
2026-01-30 11:30:40 +05:30
private void RollDiceForBot ( int rolledVal )
2026-01-28 16:57:27 +05:30
{
Debug . Log ( $"CallTest: RollDiceForBot" ) ;
2026-01-28 20:57:35 +05:30
// OnDiceRolled(diceValue == 0 ? UnityEngine.Random.Range(1, Ludo_3D_Constants.Max_Dice_Rolls + 1) : diceValue);
2026-01-30 11:30:40 +05:30
OnDiceRolled ( rolledVal ) ;
2026-01-28 16:57:27 +05:30
SelectPawnFromBotBase ( ) ;
2026-01-29 21:15:48 +05:30
OnNoMovesLeft ( ) ;
2026-01-28 16:57:27 +05:30
}
// TODO :: Call right after the dice is rolled with the animation
// What happens when you get a 6
private void SelectPawnFromBotBase ( )
{
2026-01-30 19:04:14 +05:30
if ( canSwitchPlayer | | availPlayers . Count ( ) < 1 & & ! CanRollDiceAgain | | ! botTypesInGame . Contains ( currentPlayerTypeTurn ) )
2026-01-30 12:54:43 +05:30
{
Debug . Log ( $"returning from SelectPawnFromBotBase" ) ;
return ; // Have a better check here
}
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CallTest: SelectPawnFromBotBase: {currentPlayerTypeTurn}" ) ;
var botPawnsDictForCurrentPlayer = botRuntimeMovementData [ currentPlayerTypeTurn ] ; // set the data inside this dict
2026-01-30 19:04:14 +05:30
2026-01-28 16:57:27 +05:30
int savedPlayerId = - 1 ;
PlayerPawn pawn = null ;
2026-01-28 17:34:06 +05:30
Debug . Log ( $"SelectPawnFromBotBase: availPlayers.Count(): {availPlayers.Count()}, CanRollDiceAgain: {CanRollDiceAgain}" ) ;
2026-01-28 20:57:35 +05:30
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsInHome = = 0 )
{
2026-02-02 19:49:16 +05:30
UpdateActivePlayersAndSetDisplay ( true ) ;
2026-01-28 20:57:35 +05:30
}
2026-01-28 16:57:27 +05:30
if ( availPlayers . Count ( ) < 1 & & CanRollDiceAgain ) // got a 6 roll value
{
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Values . FirstOrDefault ( pawn = > pawn . GetPlayerState ( ) = = PlayerState . InHome ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"SelectedPawn: {pawn.name}" ) ;
2026-01-28 16:57:27 +05:30
OnPawnSelected ( pawn ) ;
return ;
}
2026-01-30 19:04:14 +05:30
2026-01-28 16:57:27 +05:30
// TODO :: Double check
2026-01-29 16:17:19 +05:30
foreach ( var key in botPawnsDictForCurrentPlayer . Keys )
{
2026-01-31 20:33:50 +05:30
Debug . Log ( $"b :: botPawnsDictForCurrentPlayer[key]: {key}, {botPawnsDictForCurrentPlayer[key]}" ) ;
2026-01-29 16:17:19 +05:30
// botPawnsDictForCurrentPlayer[key] = BotMove.NoMoves;
}
2026-01-28 16:57:27 +05:30
2026-01-29 16:17:19 +05:30
Debug . Log ( $"Before Iterating" ) ;
2026-01-28 16:57:27 +05:30
foreach ( var playerPawn in availPlayers )
{
2026-01-31 20:33:50 +05:30
int possibleSteps = 0 ;
Tile possibleTileData = null ;
2026-01-28 20:57:35 +05:30
2026-01-31 20:33:50 +05:30
if ( playerPawn . GetPlayerState ( ) ! = PlayerState . InFinishingPath )
FindPossibleTileData ( playerPawn , out possibleSteps , out possibleTileData ) ;
2026-01-28 20:57:35 +05:30
2026-01-31 20:33:50 +05:30
if ( playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath | | possibleSteps > playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex ) // TODO :: have a better second check
2026-01-28 16:57:27 +05:30
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: inFinishingPath :: canSelectPlayer: {playerPawn.CanSelectPlayer}" ) ;
2026-01-29 15:45:49 +05:30
if ( playerPawn . CanSelectPlayer )
{
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . FinishingPathMove ;
savedPlayerId = playerPawn . PlayerId ;
break ;
}
else
{
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . NoMoves ;
}
2026-01-28 16:57:27 +05:30
}
2026-01-31 20:33:50 +05:30
else if ( possibleTileData ! = null & & possibleTileData . IsSafeZone )
2026-01-28 16:57:27 +05:30
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: safeMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . SafeMove ;
}
2026-01-31 20:33:50 +05:30
else if ( possibleTileData ! = null & & possibleTileData . HasPawnsAvailable & & possibleTileData . CurrentHoldingPlayerType ! = playerPawn . PlayerType )
2026-01-28 16:57:27 +05:30
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: attackMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . AttackMove ;
}
else
{
2026-01-29 15:45:49 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: normalMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . NormalMove ;
}
}
List < int > playerIds = new List < int > ( ) ;
2026-01-29 15:45:49 +05:30
if ( savedPlayerId ! = - 1 )
Debug . Log ( $"SavedPlayerId: {savedPlayerId}, CanSelectPlayer: {playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict[savedPlayerId].CanSelectPlayer}" ) ;
if ( savedPlayerId ! = - 1 & & playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] . CanSelectPlayer )
2026-01-28 16:57:27 +05:30
{
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ; // chances are when one of the character reaches towards the finishing point
}
else
{
if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . SafeMove ) & & botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . AttackMove ) )
{
InitPlayerIdsBasedOnState ( ( val ) = > val = = BotMove . AttackMove | | val = = BotMove . SafeMove ) ;
savedPlayerId = playerIds [ UnityEngine . Random . Range ( 0 , playerIds . Count ) ] ;
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . SafeMove ) )
{
InitPawnBasedOnState ( BotMove . SafeMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . AttackMove ) )
{
InitPawnBasedOnState ( BotMove . AttackMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . NormalMove ) )
{
InitPawnBasedOnState ( BotMove . NormalMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
}
2026-01-31 01:05:28 +05:30
if ( pawn ! = null )
2026-01-31 20:33:50 +05:30
{
Debug . Log ( $"AI playerPawn :: {pawn.name} :: SelectedPawn: {pawn.name}" ) ;
2026-01-31 01:05:28 +05:30
OnPawnSelected ( pawn ) ;
2026-01-31 20:33:50 +05:30
}
2026-01-31 01:05:28 +05:30
else
{
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-01-31 20:33:50 +05:30
if ( CanRollDiceAgain )
HandleDiceRoll ( ) ;
else
SwitchPlayer ( ) ;
2026-01-31 01:05:28 +05:30
}
2026-01-28 16:57:27 +05:30
void InitPawnBasedOnState ( BotMove botMove )
{
InitPlayerIdsBasedOnState ( ( val ) = > val = = botMove ) ;
ReturnPlayerWithMaxSteps ( ref savedPlayerId ) ;
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ;
}
void InitPlayerIdsBasedOnState ( Predicate < BotMove > state )
{
foreach ( var botPair in botPawnsDictForCurrentPlayer )
if ( state . Invoke ( botPair . Value ) )
playerIds . Add ( botPair . Key ) ;
}
void ReturnPlayerWithMaxSteps ( ref int savedPlayerId )
{
int maxStepsTaken = - 999 ;
foreach ( var id in playerIds )
{
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ id ] . StepsTaken > maxStepsTaken )
{
maxStepsTaken = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ id ] . StepsTaken ;
savedPlayerId = id ;
}
}
}
}
2026-01-31 20:33:50 +05:30
private void FindPossibleTileData ( PlayerPawn playerPawn , out int possibleSteps , out Tile possibleTileData )
{
2026-02-02 20:12:00 +05:30
int lastStepGenTile = totalStepsForCharacter - TilesManager . GetFinishingTileDataLength ( playerPawn . PlayerType ) ; //playerGameDatasDict[playerPawn.PlayerType].endIndex;
2026-01-31 20:33:50 +05:30
int possibleTileIndex = playerPawn . CurrentTileIndex + diceRolledValue ;
2026-02-02 20:12:00 +05:30
int lastTileIndex = TilesManager . GetGeneralTilesLength ( ) - 1 ;
2026-02-02 16:06:29 +05:30
bool canGoingInsideFinishingPath = IsGoingInsideFinishingPath ( playerPawn , out possibleSteps ) ;
int index = canGoingInsideFinishingPath ? possibleSteps - lastStepGenTile - 1
: possibleTileIndex > lastTileIndex ? possibleTileIndex - lastTileIndex - 1 : possibleTileIndex ; // case for addressing the scenario when going through the last index of general tiles.
Debug . Log ( $"possibleTileIndex: {possibleTileIndex}, lastStepGenTileIdx: {lastStepGenTile}" ) ;
Debug . Log ( $"index: {index}" ) ;
2026-02-02 20:12:00 +05:30
possibleTileData = canGoingInsideFinishingPath ? TilesManager . RetrieveFinishingTileBasedOnIndex ( playerPawn . PlayerType , index ) : TilesManager . RetrieveTileBasedOnIndex ( index ) ;
2026-02-02 16:06:29 +05:30
}
2026-01-31 20:33:50 +05:30
2026-02-02 16:06:29 +05:30
public bool IsGoingInsideFinishingPath ( PlayerPawn playerPawn , out int possibleSteps )
{
possibleSteps = playerGameDatasDict [ playerPawn . PlayerType ] . playerPawnsDict [ playerPawn . PlayerId ] . StepsTaken + diceRolledValue ;
2026-02-02 20:12:00 +05:30
return possibleSteps > TilesManager . GetGeneralTilesLength ( ) - 1 ;
2026-01-31 20:33:50 +05:30
}
2026-01-21 20:27:45 +05:30
public void OnDiceRolled ( int rolledVal )
{
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( false ) ;
2026-01-21 20:27:45 +05:30
// add core dice logic here
2026-01-22 20:50:41 +05:30
Debug . Log ( $"Tile Index :: LUDO :: rolledVal: {rolledVal} :: {currentPlayerTypeTurn}" ) ;
2026-01-21 20:27:45 +05:30
diceRolledValue = rolledVal ;
2026-01-26 19:48:55 +05:30
diceText . text = $"{diceRolledValue}" ;
2026-01-30 22:06:51 +05:30
availPlayers = new List < PlayerPawn > ( ) ;
2026-01-30 19:04:14 +05:30
2026-01-21 20:27:45 +05:30
if ( rolledVal = = Ludo_3D_Constants . Max_Dice_Rolls )
{
2026-01-28 16:57:27 +05:30
canSwitchPlayer = false ;
2026-01-21 20:27:45 +05:30
// provide option to select a pawn from the list
// also play a simple animation before selecting
2026-01-22 20:50:41 +05:30
CanRollDiceAgain = true ;
2026-01-29 21:15:48 +05:30
diceSixRollCounter + + ;
2026-02-04 12:09:04 +05:30
#if UNITY_EDITOR
2026-01-29 15:45:49 +05:30
pointerMeshRend . material = selectMat ;
2026-02-04 12:09:04 +05:30
#endif
2026-01-29 15:45:49 +05:30
foreach ( var playerPawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
if ( playerPawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath )
playerPawn . Value . SetPlayerSelectionState ( false ) ;
Debug . Log ( $"### AreAllPawnsInFinishingPath" ) ;
2026-01-27 20:55:55 +05:30
if ( AreAllPawnsInFinishingPath ( ) )
2026-01-29 15:45:49 +05:30
{
2026-02-02 17:21:38 +05:30
SetCanRollDiceForUser ( gameModeHandler . CurrentGameModeType ! = GameModeType . Bot | | ! botTypesInGame . Contains ( currentPlayerTypeTurn ) ) ;
2026-01-21 20:27:45 +05:30
2026-01-29 15:45:49 +05:30
return ;
}
Debug . Log ( $"### EnablePlayerSelectionStates" ) ;
EnablePlayerSelectionStates ( true ) ;
2026-01-21 20:27:45 +05:30
// pointerMeshRend.materials[0] = selectMat;
}
else // if there are any other pawns that are in safe or moving state
{
// for player's logic
2026-02-02 19:49:16 +05:30
UpdateActivePlayersAndSetDisplay ( true ) ;
2026-01-28 16:57:27 +05:30
2026-01-22 20:50:41 +05:30
int customAvailPlayers = availPlayers . Count ( ) ;
2026-01-28 16:57:27 +05:30
Debug . Log ( $"before CustomAvailablePlayers: {customAvailPlayers}" ) ;
2026-01-29 15:45:49 +05:30
List < int > indexesToRemove = new List < int > ( ) ;
2026-01-22 20:50:41 +05:30
2026-01-29 15:45:49 +05:30
for ( int i = 0 ; i < availPlayers . Count ; i + + )
2026-01-21 20:27:45 +05:30
{
2026-01-29 15:45:49 +05:30
Debug . Log ( $"## playerPawn.GetPlayerState(): {availPlayers[i].GetPlayerState()}" ) ;
if ( availPlayers [ i ] . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-21 20:27:45 +05:30
{
2026-02-02 20:12:00 +05:30
Debug . Log ( $"diceRolledValue: {diceRolledValue}, FinishingDataLen: {TilesManager.GetFinishingTileDataLength(currentPlayerTypeTurn)}, playerPawn.CurrentTileIndex: {availPlayers[i].CurrentTileIndex}" ) ;
if ( diceRolledValue < = TilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - ( availPlayers [ i ] . CurrentTileIndex + 1 ) )
2026-01-22 20:50:41 +05:30
{
2026-01-29 15:45:49 +05:30
availPlayers [ i ] . SetPlayerSelectionState ( true ) ;
2026-01-28 20:57:35 +05:30
}
2026-01-22 20:50:41 +05:30
else
{
2026-01-29 15:45:49 +05:30
indexesToRemove . Add ( i ) ;
availPlayers [ i ] . SetPlayerSelectionState ( false ) ;
2026-01-22 20:50:41 +05:30
customAvailPlayers - - ;
}
continue ;
2026-01-21 20:27:45 +05:30
}
2026-01-22 20:50:41 +05:30
2026-01-29 15:45:49 +05:30
availPlayers [ i ] . SetPlayerSelectionState ( true ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-31 20:33:50 +05:30
for ( int idx = indexesToRemove . Count - 1 ; idx > = 0 ; idx - - )
availPlayers . RemoveAt ( idx ) ;
2026-01-29 15:45:49 +05:30
2026-01-22 20:50:41 +05:30
// if (availPlayers.Count() < 1)
Debug . Log ( $"CustomAvailablePlayers: {customAvailPlayers}" ) ;
2026-01-28 16:57:27 +05:30
canSwitchPlayer = customAvailPlayers < 1 ;
2026-01-22 20:50:41 +05:30
CanRollDiceAgain = false ;
2026-01-21 20:27:45 +05:30
}
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CanRollDiceAgain: {CanRollDiceAgain}, canSwitchPlayer: {canSwitchPlayer}" ) ;
2026-01-21 20:27:45 +05:30
}
2026-02-02 19:49:16 +05:30
private void UpdateActivePlayersAndSetDisplay ( bool state )
2026-01-28 20:57:35 +05:30
{
availPlayers = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Values . Select ( pawn = > pawn )
. Where ( pawn = > pawn . GetPlayerState ( ) = = PlayerState . InSafeZone | |
pawn . GetPlayerState ( ) = = PlayerState . Moving | |
pawn . GetPlayerState ( ) = = PlayerState . InFinishingPath ) . ToList ( ) ;
2026-01-30 19:04:14 +05:30
2026-02-02 19:49:16 +05:30
SetDisplayCountForAllAvailPlayers ( state ) ;
2026-01-28 20:57:35 +05:30
}
2026-01-27 20:55:55 +05:30
private bool AreAllPawnsInFinishingPath ( )
{
bool areAllPawnsInFinishingPath = false ;
foreach ( var pawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
{
2026-01-29 15:45:49 +05:30
if ( pawn . Value . GetPlayerState ( ) = = PlayerState . HasFinished ) continue ;
if ( pawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-27 20:55:55 +05:30
{
areAllPawnsInFinishingPath = true ;
continue ;
}
areAllPawnsInFinishingPath = false ;
break ;
}
return areAllPawnsInFinishingPath ;
}
2026-01-28 16:57:27 +05:30
private void UpdatePlayerState ( PlayerPawn playerPawn , PlayerState playerState )
{
2026-01-30 19:04:14 +05:30
Debug . Log ( $"#### UpdatePlayerState " ) ;
2026-01-28 16:57:27 +05:30
playerGameDatasDict [ playerPawn . PlayerType ] . playerPawnsDict [ playerPawn . PlayerId ] = playerPawn ;
playerGameDatasDict [ playerPawn . PlayerType ] . playerPawnsDict [ playerPawn . PlayerId ] . SetPlayerState ( playerState ) ;
playerPawn . SetPlayerState ( playerState ) ;
}
2026-01-31 20:33:50 +05:30
private void CheckDiceRollForBot ( )
2026-01-28 17:34:06 +05:30
{
if ( CanRollDiceAgain )
2026-01-30 11:30:40 +05:30
{
HandleDiceRoll ( ) ;
}
}
private void HandleDiceRoll ( )
{
2026-01-31 20:33:50 +05:30
if ( isDebugTest )
diceRollHandler . HandleDiceViewForBot ( ( rollVal ) = > RollDiceForBot ( rollVal ) , diceValue = = 0 ? UnityEngine . Random . Range ( 1 , Ludo_3D_Constants . Max_Dice_Rolls + 1 ) : diceValue ) ;
else
diceRollHandler . HandleDiceViewForBot ( ( rollVal ) = > RollDiceForBot ( rollVal ) ) ;
2026-01-28 17:34:06 +05:30
}
2026-02-02 15:10:51 +05:30
public void OnPawnSelected ( PlayerPawn selectedPawn )
2026-01-21 20:27:45 +05:30
{
EnablePlayerSelectionStates ( false ) ;
2026-01-22 20:50:41 +05:30
PlayerGameData playerGameData = playerGameDatasDict [ currentPlayerTypeTurn ] ;
2026-02-02 15:10:51 +05:30
Debug . Log ( $"playerPawn.GetPlayerState(): {selectedPawn.GetPlayerState()}" ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 19:04:14 +05:30
2026-02-02 15:10:51 +05:30
if ( selectedPawn . GetPlayerState ( ) = = PlayerState . InHome )
2026-01-21 20:27:45 +05:30
{
2026-02-02 20:12:00 +05:30
Tile targetTile = TilesManager . RetrieveTileBasedOnIndex ( playerGameData . startIndex ) ;
2026-01-23 12:46:59 +05:30
2026-02-02 16:43:43 +05:30
selectedPawn . ShowPlayerCountCanvas ( false ) ;
2026-02-02 15:10:51 +05:30
selectedPawn . MoveToTile (
2026-02-02 20:12:00 +05:30
TilesManager . GetAndInitPositionInsideSafeZone ( selectedPawn , targetTile , currentPlayerTypeTurn ) ,
2026-01-21 20:27:45 +05:30
onComplete : ( ) = >
{
2026-01-28 20:57:35 +05:30
playerGameDatasDict [ playerGameData . playerType ] . totalPawnsInHome - - ;
2026-02-02 15:10:51 +05:30
UpdatePlayerState ( selectedPawn , PlayerState . InSafeZone ) ;
2026-02-02 16:43:43 +05:30
ShowUpdatedPlayerCountOnTile ( selectedPawn ) ;
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-02-02 15:10:51 +05:30
if ( selectedPawn . IsBotPlayer )
2026-01-31 20:33:50 +05:30
CheckDiceRollForBot ( ) ;
2026-01-29 21:15:48 +05:30
else
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-28 17:34:06 +05:30
2026-01-21 20:27:45 +05:30
} , playerGameData . startIndex ) ;
return ;
}
2026-02-02 15:10:51 +05:30
else if ( selectedPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-22 20:50:41 +05:30
{
2026-02-02 20:12:00 +05:30
Tile currentSittingTile = TilesManager . RetrieveFinishingTileBasedOnIndex ( selectedPawn . PlayerType , selectedPawn . CurrentTileIndex ) ;
2026-02-02 16:43:43 +05:30
currentSittingTile . ResetPlayerPawn ( selectedPawn ) ;
if ( currentSittingTile . HasPawnsAvailable )
{
var playerPawns = currentSittingTile . GetPlayerPawns ( ) ;
foreach ( var pawn in playerPawns )
ShowUpdatedPlayerCountOnTile ( pawn ) ;
}
2026-02-02 15:10:51 +05:30
ApplyFinishingPathLogic ( selectedPawn ) ;
2026-01-29 19:48:25 +05:30
}
2026-02-02 15:10:51 +05:30
else if ( selectedPawn . CurrentTileIndex = = playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex )
2026-01-29 19:48:25 +05:30
{
2026-02-02 20:12:00 +05:30
TilesManager . RetrieveTileBasedOnIndex ( selectedPawn . CurrentTileIndex ) . ResetPlayerPawn ( selectedPawn ) ;
2026-02-02 15:10:51 +05:30
ApplyFinishingPathLogic ( selectedPawn ) ;
2026-01-22 20:50:41 +05:30
}
2026-02-02 15:10:51 +05:30
else if ( selectedPawn . GetPlayerState ( ) = = PlayerState . InSafeZone | | selectedPawn . GetPlayerState ( ) = = PlayerState . Moving )
2026-01-21 20:27:45 +05:30
{
// move based on the dice value
2026-02-02 15:10:51 +05:30
Debug . Log ( $"Tile Index :: currentTileIndex: {selectedPawn.CurrentTileIndex}" ) ;
2026-02-02 20:12:00 +05:30
int nextTileIdx = TilesManager . GetNextGeneralTileIndex ( selectedPawn . CurrentTileIndex ) ;
2026-02-02 15:10:51 +05:30
int targetIdx = selectedPawn . CurrentTileIndex + diceRolledValue ;
2026-01-21 20:27:45 +05:30
2026-01-22 20:50:41 +05:30
if ( nextTileIdx = = 0 )
2026-02-02 15:10:51 +05:30
targetIdx = ( targetIdx - selectedPawn . CurrentTileIndex ) - 1 ;
2026-01-30 19:04:14 +05:30
2026-02-02 20:12:00 +05:30
Tile currentSittingTile = TilesManager . RetrieveTileBasedOnIndex ( selectedPawn . CurrentTileIndex ) ;
2026-01-22 20:50:41 +05:30
if ( currentSittingTile . IsSafeZone )
{
2026-01-23 13:33:16 +05:30
SafeTile safeTile = ( SafeTile ) currentSittingTile ;
2026-02-02 15:10:51 +05:30
safeTile . UpdateSafeZonePlayerData ( currentPlayerTypeTurn , selectedPawn ) ;
if ( safeTile . ContainsPlayerType ( selectedPawn . PlayerType ) )
2026-01-23 13:33:16 +05:30
{
2026-02-02 15:10:51 +05:30
var playerPawns = safeTile . GetPlayerPawns ( selectedPawn . PlayerType ) ;
2026-01-23 15:32:48 +05:30
2026-02-02 15:10:51 +05:30
if ( safeTile . PlayerTypesCount = = 1 )
{
PlayerType playerType = safeTile . GetFirstPlayerType ( ) ;
foreach ( var pawn in playerPawns )
pawn . MoveToCustomTilePosition ( safeTile . CenterPlacementPosition ) ;
}
if ( safeTile . ContainsPlayerType ( selectedPawn . PlayerType ) )
{
foreach ( var pawn in playerPawns )
2026-02-02 16:43:43 +05:30
ShowUpdatedPlayerCountOnTile ( pawn ) ;
2026-02-02 15:10:51 +05:30
}
2026-01-23 13:33:16 +05:30
}
2026-01-22 20:50:41 +05:30
}
2026-01-26 13:03:50 +05:30
else
{
2026-02-02 15:10:51 +05:30
currentSittingTile . ResetPlayerPawn ( selectedPawn ) ;
if ( currentSittingTile . HasPawnsAvailable )
{
var playerPawns = currentSittingTile . GetPlayerPawns ( ) ;
foreach ( var pawn in playerPawns )
2026-02-02 16:43:43 +05:30
ShowUpdatedPlayerCountOnTile ( pawn ) ;
2026-02-02 15:10:51 +05:30
}
2026-01-26 13:03:50 +05:30
}
2026-01-22 20:50:41 +05:30
2026-02-02 15:10:51 +05:30
MoveThroughTiles ( selectedPawn , nextTileIdx , targetIndex : targetIdx ) ;
2026-01-21 20:27:45 +05:30
}
}
2026-01-29 19:48:25 +05:30
private void ApplyFinishingPathLogic ( PlayerPawn playerPawn )
{
2026-02-02 20:12:00 +05:30
int finishingPathIndex = TilesManager . GetNextFinishingTileIndex ( playerPawn . CurrentTileIndex , playerPawn . PlayerType ) ;
int targetIdx = finishingPathIndex + diceRolledValue > TilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 ?
TilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 : finishingPathIndex + diceRolledValue ;
2026-01-29 19:48:25 +05:30
Debug . Log ( $"TargetIdx: {targetIdx}, finishingPathIndex: {finishingPathIndex}" ) ;
2026-02-02 16:43:43 +05:30
playerPawn . ShowPlayerCountCanvas ( false ) ;
2026-01-29 19:48:25 +05:30
MoveThroughFinishingPath ( playerPawn , finishingPathIndex , targetIdx ) ;
}
2026-02-02 20:12:00 +05:30
// TODO :: move to tiles manager
2026-01-22 20:50:41 +05:30
private void SwitchPlayer ( PlayerPawn playerPawn = null )
2026-01-21 20:27:45 +05:30
{
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CallTest: SwitchPlayer" ) ;
2026-01-30 19:04:14 +05:30
if ( playerPawn )
2026-02-02 20:12:00 +05:30
UpdatePlayerState ( playerPawn , TilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) . IsSafeZone ? PlayerState . InSafeZone : PlayerState . Moving ) ;
2026-01-28 16:57:27 +05:30
2026-01-22 20:50:41 +05:30
if ( ! CanRollDiceAgain )
2026-01-21 20:27:45 +05:30
{
2026-01-22 20:50:41 +05:30
Debug . Log ( $"currentPlayerTurn: {currentPlayerTypeTurn}" ) ;
Debug . Log ( $"currentPlayerTurnIndex: {currentPlayerTurnIndex}" ) ;
2026-01-30 19:04:14 +05:30
Debug . Log ( $"before SwitchPlayer availPlayers: {availPlayers.Count}, playerPawn: {playerPawn}" ) ;
2026-02-02 16:43:43 +05:30
2026-02-02 19:49:16 +05:30
UpdateActivePlayersAndSetDisplay ( false ) ;
2026-01-30 19:04:14 +05:30
Debug . Log ( $"after SwitchPlayer availPlayers: {availPlayers.Count}, playerPawn: {playerPawn}" ) ;
2026-02-02 21:20:41 +05:30
Debug . Log ( $"after allPlayerTypes.Count: {allPlayerTypes.Count}" ) ;
2026-01-30 19:04:14 +05:30
2026-02-02 20:12:00 +05:30
if ( allPlayerTypes . Count = = 0 )
2026-01-22 20:50:41 +05:30
{
Debug . LogError ( $"GAME IS OVER" ) ;
return ;
}
2026-02-02 12:31:26 +05:30
currentPlayerTurnIndex = allPlayerTypes . FindIndex ( type = > type = = currentPlayerTypeTurn ) ;
2026-01-27 20:55:55 +05:30
if ( currentPlayerTypeTurn = = allPlayerTypes [ allPlayerTypes . Count - 1 ] )
2026-01-21 20:27:45 +05:30
{
currentPlayerTurnIndex = 0 ;
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-21 20:27:45 +05:30
}
else
{
currentPlayerTurnIndex + + ;
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-21 20:27:45 +05:30
}
2026-01-26 19:48:55 +05:30
2026-01-30 22:17:18 +05:30
uIManager . UpdatePlayerTurnText ( currentPlayerTypeTurn ) ;
2026-01-29 21:15:48 +05:30
diceSixRollCounter = 0 ;
2026-01-26 19:48:55 +05:30
diceText . text = $"{0}" ;
2026-01-30 19:04:14 +05:30
2026-02-02 19:49:16 +05:30
UpdateActivePlayersAndSetDisplay ( true ) ;
2026-01-21 20:27:45 +05:30
}
2026-02-02 17:21:38 +05:30
2026-02-02 21:20:41 +05:30
Debug . Log ( $"currentPlayerTurnIndex: {currentPlayerTurnIndex}" ) ;
2026-01-26 13:03:50 +05:30
Debug . Log ( $"CurrentPlayerTurn: {currentPlayerTypeTurn}" ) ;
2026-02-02 17:21:38 +05:30
SetCanRollDiceForUser ( gameModeHandler . CurrentGameModeType ! = GameModeType . Bot | | ! botTypesInGame . Contains ( currentPlayerTypeTurn ) ) ;
2026-01-21 20:27:45 +05:30
2026-02-02 20:12:00 +05:30
#if UNITY_EDITOR
SetCurrentSelectedPointer ( ) ;
2026-01-21 20:27:45 +05:30
pointerMeshRend . material = turnMat ;
// pointerMeshRend.materials[0] = turnMat;
2026-02-02 20:12:00 +05:30
#endif
2026-01-22 20:50:41 +05:30
2026-02-02 17:21:38 +05:30
// Debug.Log($"botTypesInGame.Contains(currentPlayerTypeTurn): {botTypesInGame.Contains(currentPlayerTypeTurn)}");
2026-01-27 20:55:55 +05:30
2026-02-02 17:21:38 +05:30
if ( gameModeHandler . CurrentGameModeType = = GameModeType . Bot & & botTypesInGame . Contains ( currentPlayerTypeTurn ) ) // TODO :: Double check calling of the function
2026-01-27 20:55:55 +05:30
{
2026-01-28 16:57:27 +05:30
Debug . Log ( $"Invoking RollDiceForBot" ) ;
2026-01-30 11:30:40 +05:30
Invoke ( nameof ( HandleDiceRoll ) , 1f ) ;
2026-01-27 20:55:55 +05:30
}
}
2026-02-02 20:12:00 +05:30
#if UNITY_EDITOR
2026-01-31 20:33:50 +05:30
private void SetCurrentSelectedPointer ( )
{
var tempPos = playerBaseHandler . GetPlayerBase ( currentPlayerTypeTurn ) . transform . position ;
pointerDebug . position = new Vector3 ( tempPos . x , 3f , tempPos . z ) ;
}
2026-02-02 20:12:00 +05:30
#endif
2026-01-31 20:33:50 +05:30
public void SetDisplayCountForAllAvailPlayers ( bool state )
{
2026-02-02 16:43:43 +05:30
if ( state )
{
availPlayers . ForEach ( pawn = > ShowUpdatedPlayerCountOnTile ( pawn ) ) ;
}
else
2026-02-02 15:10:51 +05:30
{
2026-02-02 16:43:43 +05:30
availPlayers . ForEach ( pawn = > pawn . ShowPlayerCountCanvas ( false ) ) ;
2026-02-02 15:10:51 +05:30
}
2026-01-31 20:33:50 +05:30
}
2026-01-21 20:27:45 +05:30
private void MoveThroughTiles ( PlayerPawn playerPawn , int index , int targetIndex )
{
2026-02-02 20:12:00 +05:30
Tile nextTile = TilesManager . RetrieveTileBasedOnIndex ( index ) ;
2026-01-23 12:46:59 +05:30
Vector3 targetPosition = nextTile . CenterPlacementPosition ;
2026-01-22 20:50:41 +05:30
2026-01-23 12:46:59 +05:30
Debug . Log ( $"Tile Index :: nextIndex: {index}, targetIndex: {targetIndex}, nextTileName: {nextTile.name}" ) ;
if ( index = = targetIndex ) // if the target index is the safe zone only then apply the logic for rearranging pawns
2026-01-22 20:50:41 +05:30
{
2026-02-02 20:12:00 +05:30
Tile targetTile = TilesManager . RetrieveTileBasedOnIndex ( targetIndex ) ;
2026-01-22 20:50:41 +05:30
if ( targetTile . IsSafeZone )
2026-01-21 20:27:45 +05:30
{
2026-02-02 20:12:00 +05:30
targetPosition = TilesManager . GetAndInitPositionInsideSafeZone ( playerPawn , targetTile , currentPlayerTypeTurn ) ;
2026-01-22 20:50:41 +05:30
}
}
2026-01-23 12:46:59 +05:30
Debug . Log ( $"tile targetPosition: {targetPosition}" ) ;
2026-02-02 16:43:43 +05:30
playerPawn . ShowPlayerCountCanvas ( false ) ;
2026-01-23 12:46:59 +05:30
2026-01-22 20:50:41 +05:30
playerPawn . MoveToTile (
targetPosition ,
onComplete : ( ) = >
{
diceRolledValue - - ;
2026-01-23 12:46:59 +05:30
Debug . Log ( $"DiceRolledValue: {diceRolledValue}" ) ;
2026-01-22 20:50:41 +05:30
if ( diceRolledValue > 0 )
{
2026-02-02 20:12:00 +05:30
int nextTileIndex = TilesManager . GetNextGeneralTileIndex ( playerPawn . CurrentTileIndex ) ;
2026-01-23 12:46:59 +05:30
Debug . Log ( $"currentTileIndex: {playerPawn.CurrentTileIndex}, nextTileIndex: {nextTileIndex}, targetIndex: {targetIndex}" ) ;
2026-01-22 20:50:41 +05:30
if ( playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath | | index = = playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex )
2026-01-21 20:27:45 +05:30
{
2026-01-22 20:50:41 +05:30
// MoveThroughTiles(playerPawn, index, targetIndex);
Debug . Log ( $"TargetIdx: {targetIndex - index}" ) ;
MoveThroughFinishingPath ( playerPawn , 0 , targetIndex - index ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-22 20:50:41 +05:30
else if ( nextTileIndex < = targetIndex )
{
if ( nextTileIndex = = 0 )
2026-01-23 12:46:59 +05:30
targetIndex = ( targetIndex - playerPawn . CurrentTileIndex ) - 1 ;
2026-01-21 20:27:45 +05:30
2026-01-22 20:50:41 +05:30
MoveThroughTiles ( playerPawn , nextTileIndex , targetIndex ) ;
}
}
else
{
2026-01-30 19:04:14 +05:30
// TODO :: Improve this logic, use a collection
2026-01-26 13:03:50 +05:30
Debug . Log ( $"nextTile.IsSafeZone: {nextTile.IsSafeZone}" ) ;
2026-01-30 19:04:14 +05:30
if ( CanRollDiceAgain )
2026-02-02 16:43:43 +05:30
ShowUpdatedPlayerCountOnTile ( playerPawn ) ;
2026-01-30 19:04:14 +05:30
2026-01-23 12:46:59 +05:30
if ( ! nextTile . IsSafeZone )
{
2026-01-29 18:13:07 +05:30
Debug . Log ( $"nextTile.HasPawnsAvailable: {nextTile.HasPawnsAvailable}" ) ;
if ( nextTile . HasPawnsAvailable & & playerPawn . PlayerType ! = nextTile . CurrentHoldingPlayerType )
2026-01-23 12:46:59 +05:30
{
2026-01-29 18:13:07 +05:30
Debug . Log ( $"nextTile.PlayerPawn: {nextTile.CurrentHoldingPlayerType}, {nextTile.transform.name}" ) ;
Debug . Log ( $"nextTile.TotalPawnsInTile: {nextTile.TotalPawnsInTile}" ) ;
2026-01-26 13:03:50 +05:30
// play animation for moving back to base.
2026-01-23 12:46:59 +05:30
// TODO :: Send existing pawn back to base.
// means there's already a pawn there, move him back to the base.
2026-01-29 19:48:25 +05:30
int counter = nextTile . TotalPawnsInTile ;
2026-01-29 18:13:07 +05:30
for ( int i = counter ; i > 0 ; i - - )
{
var pawn = nextTile . GetPlayerPawn ( ) ;
playerGameDatasDict [ pawn . PlayerType ] . totalPawnsInHome + + ;
2026-02-02 19:27:17 +05:30
playerBaseHandler . SendPlayerToHome ( pawn ) ;
2026-01-29 18:13:07 +05:30
}
2026-01-29 19:48:25 +05:30
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
nextTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
2026-02-02 15:10:51 +05:30
// UpdatePlayerCountOnTile(playerPawn, true);
2026-02-02 11:19:44 +05:30
2026-01-29 21:15:48 +05:30
return ;
}
2026-01-29 19:48:25 +05:30
CanRollDiceAgain = true ;
2026-01-31 20:33:50 +05:30
if ( ! playerPawn . IsBotPlayer )
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-23 12:46:59 +05:30
}
nextTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
2026-02-02 16:43:43 +05:30
ShowUpdatedPlayerCountOnTile ( playerPawn ) ;
2026-02-02 11:19:44 +05:30
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
}
else
{
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-01-23 12:46:59 +05:30
}
2026-01-29 19:59:17 +05:30
SwitchPlayer ( playerPawn ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-30 19:04:14 +05:30
} ,
2026-01-21 20:27:45 +05:30
index ) ;
}
private void MoveThroughFinishingPath ( PlayerPawn playerPawn , int index , int targetIndex )
{
2026-01-28 16:57:27 +05:30
UpdatePlayerState ( playerPawn , PlayerState . InFinishingPath ) ;
2026-01-30 19:14:08 +05:30
2026-01-21 20:27:45 +05:30
playerPawn . MoveToTile (
2026-02-02 20:12:00 +05:30
TilesManager . RetrieveFinishingTileBasedOnIndex ( currentPlayerTypeTurn , index ) . transform . position ,
2026-01-21 20:27:45 +05:30
onComplete : ( ) = >
{
2026-01-22 20:50:41 +05:30
diceRolledValue - - ;
Debug . Log ( $"DiceRolledValue: {diceRolledValue}" ) ;
if ( diceRolledValue > 0 )
2026-01-21 20:27:45 +05:30
{
2026-02-02 20:12:00 +05:30
int tileIndex = TilesManager . GetNextFinishingTileIndex ( playerPawn . CurrentTileIndex , playerPawn . PlayerType ) ;
2026-01-22 20:50:41 +05:30
Debug . Log ( $"tileIndex: {tileIndex}, targetIndex: {targetIndex}" ) ;
if ( tileIndex < = targetIndex )
{
// MoveThroughTiles(playerPawn, index, targetIndex);
MoveThroughFinishingPath ( playerPawn , tileIndex , targetIndex ) ;
}
2026-01-21 20:27:45 +05:30
}
else
{
2026-02-02 20:12:00 +05:30
if ( playerPawn . CurrentTileIndex = = TilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 )
2026-01-22 20:50:41 +05:30
{
2026-02-02 20:12:00 +05:30
Tile tile = TilesManager . RetrieveFinishingTileBasedOnIndex ( playerPawn . PlayerType , playerPawn . CurrentTileIndex ) ;
2026-02-02 19:27:17 +05:30
tile . InitPlayerPawn ( playerPawn , playerPawn . PlayerType ) ;
2026-02-02 21:22:39 +05:30
// ShowUpdatedPlayerCountOnTile(playerPawn);
2026-02-02 19:27:17 +05:30
2026-01-28 16:57:27 +05:30
UpdatePlayerState ( playerPawn , PlayerState . HasFinished ) ;
2026-01-22 20:50:41 +05:30
playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsFinished + + ;
2026-02-02 21:20:41 +05:30
Debug . Log ( $"playerGameDatasDict[currentPlayerTypeTurn].totalPawnsFinished: {playerGameDatasDict[currentPlayerTypeTurn].totalPawnsFinished}" ) ;
Debug . Log ( $"playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict.Count: {playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict.Count}" ) ;
2026-01-23 12:46:59 +05:30
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsFinished = = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Count )
2026-01-22 20:50:41 +05:30
{
CanRollDiceAgain = false ;
2026-01-29 19:48:25 +05:30
2026-02-02 12:31:26 +05:30
var playerTypeToRemove = currentPlayerTypeTurn ;
2026-02-02 21:20:41 +05:30
allPlayerTypes . ForEach ( type = > Debug . Log ( $"before allPlayerTypes: {type}" ) ) ;
2026-02-02 12:31:26 +05:30
SwitchPlayer ( ) ;
2026-02-02 21:20:41 +05:30
allPlayerTypes . ForEach ( type = > Debug . Log ( $"after allPlayerTypes: {type}" ) ) ;
2026-02-02 12:31:26 +05:30
if ( allPlayerTypes . Contains ( playerTypeToRemove ) )
2026-01-30 09:35:31 +05:30
{
2026-02-02 12:31:26 +05:30
allPlayerTypes . Remove ( playerTypeToRemove ) ;
playerDatas . FirstOrDefault ( data = > data . playerType = = playerTypeToRemove ) . ranking = TotalPlayersInGame - allPlayerTypes . Count ;
2026-01-30 09:35:31 +05:30
}
if ( allPlayerTypes . Count = = 1 )
{
// Game is over
2026-02-02 12:31:26 +05:30
var lastUnfinishingPlayerType = allPlayerTypes [ 0 ] ;
2026-01-30 21:51:33 +05:30
allPlayerTypes . RemoveAt ( 0 ) ;
2026-02-02 12:31:26 +05:30
playerDatas . FirstOrDefault ( data = > data . playerType = = lastUnfinishingPlayerType ) . ranking = TotalPlayersInGame - allPlayerTypes . Count ;
2026-01-30 09:35:31 +05:30
// Show Game Over panel
2026-01-30 21:51:33 +05:30
gameManager . OnGameStateChanged ( GameState . GameOver ) ;
2026-01-30 09:35:31 +05:30
return ;
}
2026-01-22 20:50:41 +05:30
}
else
{
CanRollDiceAgain = true ;
2026-01-28 20:57:35 +05:30
if ( playerPawn . IsBotPlayer )
2026-01-31 20:33:50 +05:30
CheckDiceRollForBot ( ) ;
2026-01-30 19:04:14 +05:30
else
2026-01-30 12:54:43 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-22 20:50:41 +05:30
}
}
else
{
2026-01-30 19:14:08 +05:30
// activate here
2026-02-02 20:12:00 +05:30
TilesManager . RetrieveFinishingTileBasedOnIndex ( currentPlayerTypeTurn , playerPawn . CurrentTileIndex ) . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
2026-02-02 16:43:43 +05:30
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-02-02 16:43:43 +05:30
if ( CanRollDiceAgain )
ShowUpdatedPlayerCountOnTile ( playerPawn ) ;
2026-01-22 20:50:41 +05:30
SwitchPlayer ( ) ;
}
2026-01-21 20:27:45 +05:30
}
2026-01-30 19:04:14 +05:30
} ,
2026-01-21 20:27:45 +05:30
index ) ;
}
2026-01-29 19:48:25 +05:30
2026-01-29 22:16:54 +05:30
private void SetCanRollDiceForUser ( bool state )
2026-01-29 19:48:25 +05:30
{
2026-01-30 11:30:40 +05:30
CanRollDiceForUser = state ;
2026-01-30 12:54:43 +05:30
Debug . Log ( $"CAnRollDiceForUser: {CanRollDiceForUser}" ) ;
2026-01-29 19:48:25 +05:30
}
2026-01-30 19:04:14 +05:30
2026-02-02 16:43:43 +05:30
private void ShowUpdatedPlayerCountOnTile ( PlayerPawn playerPawn )
2026-01-30 19:04:14 +05:30
{
2026-01-30 23:27:56 +05:30
Tile tile = playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath ?
2026-02-02 20:12:00 +05:30
TilesManager . RetrieveFinishingTileBasedOnIndex ( playerPawn . PlayerType , playerPawn . CurrentTileIndex )
: TilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) ;
2026-01-30 23:27:56 +05:30
2026-02-02 16:43:43 +05:30
playerPawn . ShowPlayerCountCanvas ( true ) ;
2026-01-30 19:04:14 +05:30
int count = 0 ;
if ( tile . IsSafeZone )
{
count = ( tile as SafeTile ) . GetPlayerPawnsCountInTile ( playerPawn . PlayerType ) ;
}
else
{
count = tile . TotalPawnsInTile ;
}
2026-02-02 16:43:43 +05:30
Debug . Log ( $"ShowUpdatedPlayerCountOnTile: {count}" ) ;
2026-02-02 16:37:43 +05:30
playerPawn . PlayerCountCanvas . SetPlayerCount ( count ) ;
2026-01-30 19:04:14 +05:30
}
2026-02-02 19:27:17 +05:30
public void ResetTileDatasForPlayers ( )
{
foreach ( PlayerData data in playerDatas )
{
var pawns = playerGameDatasDict [ data . playerType ] . playerPawnsDict . Values ;
foreach ( var pawn in pawns )
{
2026-02-02 19:49:16 +05:30
if ( pawn . GetPlayerState ( ) = = PlayerState . InHome ) continue ;
2026-02-02 19:27:17 +05:30
2026-02-02 20:12:00 +05:30
TilesManager . ResetTileData ( pawn . PlayerType , pawn . CurrentTileIndex , pawn . GetPlayerState ( ) ) ;
2026-02-02 19:27:17 +05:30
}
}
}
2026-01-30 21:51:33 +05:30
public void ResetData ( )
{
2026-01-31 20:33:50 +05:30
ResetGameRestartData ( ) ;
2026-01-30 21:51:33 +05:30
playerDatas = null ;
allPlayerTypes = null ;
playerGameDatasDict = null ;
playerDatas = null ;
availPlayers = null ;
2026-02-02 17:21:38 +05:30
botTypesInGame = null ;
botRuntimeMovementData = null ;
2026-01-30 21:51:33 +05:30
}
2026-01-31 20:33:50 +05:30
public void ResetGameRestartData ( )
{
currentPlayerTurnIndex = 0 ;
}
2026-01-21 20:27:45 +05:30
}