Changes for bot logic.
This commit is contained in:
parent
a9af5d1d17
commit
bfa63f0e8f
@ -9,8 +9,7 @@ public enum PlayerType
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
Player3 = 2,
|
||||
Player4 = 3,
|
||||
Bot
|
||||
Player4 = 3
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
@ -20,17 +19,26 @@ public class PlayerGameData
|
||||
public int startIndex;
|
||||
public int endIndex;
|
||||
public Transform playersParent;
|
||||
public List<PlayerPawn> playerPawnsDict;
|
||||
public Dictionary<int, PlayerPawn> playerPawnsDict;
|
||||
public int totalPawnsFinished = 0;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public enum MatchType
|
||||
{
|
||||
LAN,
|
||||
PVP,
|
||||
Bot
|
||||
}
|
||||
|
||||
public enum BotMove
|
||||
{
|
||||
FinishingPathMove = 0,
|
||||
SafeMove = 1,
|
||||
AttackMove = 2,
|
||||
NormalMove = 3,
|
||||
NoMoves = 4
|
||||
}
|
||||
|
||||
public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
{
|
||||
[SerializeField] private TextMeshProUGUI diceText;
|
||||
@ -45,13 +53,17 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
|
||||
private PlayerType currentPlayerTypeTurn;
|
||||
private int currentPlayerTurnIndex = 0;
|
||||
private List<PlayerType> playerTypes = new List<PlayerType>();
|
||||
private List<PlayerType> allPlayerTypes = new List<PlayerType>();
|
||||
private List<PlayerType> botTypesInGame = new List<PlayerType>();
|
||||
|
||||
public List<PlayerType> PlayerTypesCollection => playerTypes;
|
||||
public List<PlayerType> PlayerTypesCollection => allPlayerTypes;
|
||||
|
||||
// private Dictionary<PlayerTypes, > playerPawnsDict = new Dictionary<PlayerTypes, List<PlayerPawn>>();
|
||||
private Dictionary<PlayerType, PlayerGameData> playerGameDatasDict = new Dictionary<PlayerType, PlayerGameData>();
|
||||
|
||||
// botRuntimeMovementData: where can the bot move if a particular dice value is thrown, and based on the value set the bot move for each using a predictive approach and select based on the the priority
|
||||
private Dictionary<PlayerType, Dictionary<int, BotMove>> botRuntimeMovementData = new Dictionary<PlayerType, Dictionary<int, BotMove>>();
|
||||
|
||||
private TilesManager tilesManager;
|
||||
|
||||
private int diceRolledValue;
|
||||
@ -74,53 +86,119 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
CanRollDice = true;
|
||||
|
||||
// initialize the player list from UI.
|
||||
InitPlayerTypesForLAN(null);
|
||||
// InitPlayerTypesForLAN(null);
|
||||
InitPlayerTypesForBotMatch(PlayerType.Player1, 1);
|
||||
}
|
||||
|
||||
// TODO :: Call when the UI selection is made and game starts
|
||||
public void InitPlayerTypesForLAN(List<PlayerType> types)
|
||||
{
|
||||
// TODO :: 2P, 3P, 4P
|
||||
playerTypes = new List<PlayerType> { PlayerType.Player1, PlayerType.Player2, PlayerType.Player3, PlayerType.Player4 };
|
||||
allPlayerTypes = new List<PlayerType> { PlayerType.Player1, PlayerType.Player2, PlayerType.Player3, PlayerType.Player4 };
|
||||
|
||||
playerBaseHandler.InitPlayerTypes(playerTypes);
|
||||
playerBaseHandler.InitPlayerTypes(allPlayerTypes);
|
||||
InitCurrentGamePlayerInfo();
|
||||
}
|
||||
|
||||
public void InitPlayerTypesForBotMatch(PlayerType selectedPlayerType, int botCount)
|
||||
{
|
||||
// test data
|
||||
botTypesInGame.Clear();
|
||||
allPlayerTypes.Clear();
|
||||
AssignBotTypes(selectedPlayerType, botCount);
|
||||
InitBotRuntimeData();
|
||||
|
||||
allPlayerTypes.Add(selectedPlayerType);
|
||||
allPlayerTypes.AddRange(botTypesInGame);
|
||||
|
||||
playerBaseHandler.InitPlayerTypes(allPlayerTypes);
|
||||
InitCurrentGamePlayerInfo();
|
||||
AssignPlayerAndBotStates(selectedPlayerType);
|
||||
}
|
||||
|
||||
private void InitBotRuntimeData()
|
||||
{
|
||||
botRuntimeMovementData.Clear();
|
||||
|
||||
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)
|
||||
{
|
||||
botRuntimeMovementData[botType].Add(pawn.Value.PlayerId, BotMove.SafeMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
if (botCount == 1)
|
||||
{
|
||||
var playerType = (PlayerType)((int)selectedPlayerType + 2 < Enum.GetValues(typeof(PlayerType)).Length ?
|
||||
var playerType = (PlayerType)((int)selectedPlayerType + 2 < Enum.GetValues(typeof(PlayerType)).Length ?
|
||||
(int)selectedPlayerType + 2 : (int)selectedPlayerType - 2);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
foreach (PlayerType enumType in Enum.GetValues(typeof(PlayerType)))
|
||||
{
|
||||
if (enumType == selectedPlayerType) continue;
|
||||
|
||||
botTypesInGame.Add(enumType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO :: Call based on 2P/3P/4P
|
||||
public void InitCurrentGamePlayerInfo()
|
||||
{
|
||||
currentPlayerTypeTurn = playerTypes[currentPlayerTurnIndex];
|
||||
currentPlayerTypeTurn = allPlayerTypes[currentPlayerTurnIndex];
|
||||
|
||||
// initialize the board based on the player types
|
||||
foreach (PlayerGameData playerGameData in playerGameDatas)
|
||||
{
|
||||
if (!playerTypes.Contains(playerGameData.playerType))
|
||||
if (!allPlayerTypes.Contains(playerGameData.playerType))
|
||||
continue;
|
||||
|
||||
Debug.Log($"playerGameData.playerType: {playerGameData.playerType}");
|
||||
playerGameDatasDict.Add(playerGameData.playerType, playerGameData);
|
||||
playerGameDatasDict[playerGameData.playerType].playerPawnsDict = new List<PlayerPawn>();
|
||||
playerGameDatasDict[playerGameData.playerType].playerPawnsDict = new Dictionary<int, PlayerPawn>();
|
||||
|
||||
foreach (Transform playerPawnChild in playerGameData.playersParent)
|
||||
{
|
||||
if (!playerPawnChild.gameObject.activeInHierarchy) continue;
|
||||
|
||||
playerGameDatasDict[playerGameData.playerType].playerPawnsDict.Add(playerPawnChild.GetComponent<PlayerPawn>());
|
||||
var pawn = playerPawnChild.GetComponent<PlayerPawn>();
|
||||
playerGameDatasDict[playerGameData.playerType].playerPawnsDict.Add(pawn.PlayerId, pawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,9 +207,9 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
{
|
||||
foreach (var playerPawn in playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict)
|
||||
{
|
||||
if (playerPawn.GetPlayerState() == PlayerState.InFinishingPath) continue;
|
||||
if (playerPawn.Value.GetPlayerState() == PlayerState.InFinishingPath) continue;
|
||||
|
||||
playerPawn.SetPlayerSelectionState(state);
|
||||
playerPawn.Value.SetPlayerSelectionState(state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,23 +227,9 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
// provide option to select a pawn from the list
|
||||
// also play a simple animation before selecting
|
||||
EnablePlayerSelectionStates(true);
|
||||
|
||||
CanRollDiceAgain = true;
|
||||
|
||||
bool AreAllPawnsInFinishingPath = false;
|
||||
foreach (var pawn in playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict)
|
||||
{
|
||||
if (pawn.GetPlayerState() == PlayerState.InFinishingPath && pawn.GetPlayerState() != PlayerState.HasFinished)
|
||||
{
|
||||
AreAllPawnsInFinishingPath = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
AreAllPawnsInFinishingPath = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (AreAllPawnsInFinishingPath)
|
||||
if (AreAllPawnsInFinishingPath())
|
||||
CanRollDice = true;
|
||||
|
||||
pointerMeshRend.material = selectMat;
|
||||
@ -174,7 +238,7 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
else // if there are any other pawns that are in safe or moving state
|
||||
{
|
||||
// for player's logic
|
||||
IEnumerable<PlayerPawn> availPlayers = playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict.Select(pawn => pawn)
|
||||
IEnumerable<PlayerPawn> availPlayers = playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict.Values.Select(pawn => pawn)
|
||||
.Where(pawn => pawn.GetPlayerState() == PlayerState.InSafeZone ||
|
||||
pawn.GetPlayerState() == PlayerState.Moving ||
|
||||
pawn.GetPlayerState() == PlayerState.InFinishingPath);
|
||||
@ -204,6 +268,7 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
Debug.Log($"CustomAvailablePlayers: {customAvailPlayers}");
|
||||
if (customAvailPlayers < 1)
|
||||
{
|
||||
// TODO :: Switch the player once the dice rolling has completed
|
||||
SwitchPlayer();
|
||||
CanRollDice = true;
|
||||
}
|
||||
@ -212,6 +277,24 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
}
|
||||
}
|
||||
|
||||
private bool AreAllPawnsInFinishingPath()
|
||||
{
|
||||
bool areAllPawnsInFinishingPath = false;
|
||||
foreach (var pawn in playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict)
|
||||
{
|
||||
if (pawn.Value.GetPlayerState() == PlayerState.InFinishingPath && pawn.Value.GetPlayerState() != PlayerState.HasFinished)
|
||||
{
|
||||
areAllPawnsInFinishingPath = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
areAllPawnsInFinishingPath = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return areAllPawnsInFinishingPath;
|
||||
}
|
||||
|
||||
public void OnPawnSelected(PlayerPawn playerPawn)
|
||||
{
|
||||
EnablePlayerSelectionStates(false);
|
||||
@ -294,21 +377,21 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
Debug.Log($"currentPlayerTurn: {currentPlayerTypeTurn}");
|
||||
Debug.Log($"currentPlayerTurnIndex: {currentPlayerTurnIndex}");
|
||||
|
||||
if (playerTypes.Count == 1)
|
||||
if (allPlayerTypes.Count == 1)
|
||||
{
|
||||
Debug.LogError($"GAME IS OVER");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentPlayerTypeTurn == playerTypes[playerTypes.Count - 1])
|
||||
if (currentPlayerTypeTurn == allPlayerTypes[allPlayerTypes.Count - 1])
|
||||
{
|
||||
currentPlayerTurnIndex = 0;
|
||||
currentPlayerTypeTurn = playerTypes[currentPlayerTurnIndex];
|
||||
currentPlayerTypeTurn = allPlayerTypes[currentPlayerTurnIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPlayerTurnIndex++;
|
||||
currentPlayerTypeTurn = playerTypes[currentPlayerTurnIndex];
|
||||
currentPlayerTypeTurn = allPlayerTypes[currentPlayerTurnIndex];
|
||||
}
|
||||
|
||||
diceText.text = $"{0}";
|
||||
@ -323,6 +406,64 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
|
||||
if (playerPawn)
|
||||
playerPawn.SetPlayerState(tilesManager.RetrieveTileBasedOnIndex(playerPawn.CurrentTileIndex).IsSafeZone ? PlayerState.InSafeZone : PlayerState.Moving);
|
||||
|
||||
Debug.Log($"botTypesInGame.Contains(currentPlayerTypeTurn): {botTypesInGame.Contains(currentPlayerTypeTurn)}");
|
||||
|
||||
if (!CanRollDiceAgain && botTypesInGame.Contains(currentPlayerTypeTurn)) // TODO :: Double check calling of the function
|
||||
{
|
||||
Invoke(nameof(RollDiceForBot), 1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void RollDiceForBot()
|
||||
{
|
||||
Debug.Log($"RollDiceForBot");
|
||||
|
||||
OnDiceRolled(UnityEngine.Random.Range(1, Ludo_3D_Constants.Max_Dice_Rolls + 1));
|
||||
}
|
||||
|
||||
// TODO :: Call right after the dice is rolled with the animation
|
||||
// What happens when you get a 6
|
||||
private void SelectPawnFromBotBase()
|
||||
{
|
||||
var botPawnsDict = botRuntimeMovementData[currentPlayerTypeTurn]; // set the data inside this dict
|
||||
|
||||
// check the data from the playerGameDataDict
|
||||
// change playerPawnsDict to list
|
||||
|
||||
// only select the pawns that are active
|
||||
// if no pawns have left the home select the first pawn inside the base
|
||||
//
|
||||
foreach (var keyValuePair in playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict)
|
||||
{
|
||||
var playerPawn = keyValuePair.Value;
|
||||
var possibleLandingIndex = playerPawn.CurrentTileIndex + diceRolledValue;
|
||||
|
||||
if (playerPawn.GetPlayerState() == PlayerState.HasFinished)
|
||||
{
|
||||
botPawnsDict.Remove(playerPawn.PlayerId); // TODO :: Double check logic
|
||||
continue;
|
||||
}
|
||||
|
||||
Tile tileData = tilesManager.RetrieveTileBasedOnIndex(possibleLandingIndex);
|
||||
if (playerPawn.GetPlayerState() == PlayerState.InFinishingPath || possibleLandingIndex > playerGameDatasDict[currentPlayerTypeTurn].endIndex)
|
||||
{
|
||||
botPawnsDict[playerPawn.PlayerId] = BotMove.FinishingPathMove;
|
||||
continue;
|
||||
}
|
||||
else if (tileData.IsSafeZone || playerPawn.GetPlayerState() == PlayerState.InHome)
|
||||
{
|
||||
botPawnsDict[playerPawn.PlayerId] = BotMove.SafeMove;
|
||||
}
|
||||
else if (tileData.PlayerPawn != null)
|
||||
{
|
||||
botPawnsDict[playerPawn.PlayerId] = BotMove.AttackMove;
|
||||
}
|
||||
else
|
||||
{
|
||||
botPawnsDict[playerPawn.PlayerId] = BotMove.NormalMove;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveThroughTiles(PlayerPawn playerPawn, int index, int targetIndex)
|
||||
@ -486,10 +627,10 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
CanRollDiceAgain = false;
|
||||
|
||||
SwitchPlayer();
|
||||
if (playerTypes.Contains(currentPlayerTypeTurn))
|
||||
playerTypes.Remove(currentPlayerTypeTurn);
|
||||
if (allPlayerTypes.Contains(currentPlayerTypeTurn))
|
||||
allPlayerTypes.Remove(currentPlayerTypeTurn);
|
||||
|
||||
Debug.Log($"PlayerTypes: {playerTypes.Count}");
|
||||
Debug.Log($"PlayerTypes: {allPlayerTypes.Count}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -13,6 +13,11 @@ public class PlayerBase : MonoBehaviour
|
||||
[SerializeField] private BasePlacementData[] basePlacementDatas;
|
||||
[SerializeField] private PlayerPawn[] playerPawns;
|
||||
|
||||
public bool IsBotBase
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public PlayerType GetPlayerType() => playerType;
|
||||
|
||||
public void InitPlayerData()
|
||||
@ -23,6 +28,15 @@ public class PlayerBase : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignBotState(PawnType pawnType)
|
||||
{
|
||||
IsBotBase = pawnType == PawnType.Bot;
|
||||
for (int idx = 0; idx < playerPawns.Length; idx++)
|
||||
{
|
||||
playerPawns[idx].AssignBotPlayerState(IsBotBase);
|
||||
}
|
||||
}
|
||||
|
||||
public Transform GetBasePlacementDataPosition(int idx)
|
||||
{
|
||||
return basePlacementDatas[idx].placementTransform;
|
||||
|
||||
@ -11,6 +11,12 @@ public enum PlayerState
|
||||
HasFinished
|
||||
}
|
||||
|
||||
public enum PawnType
|
||||
{
|
||||
User,
|
||||
Bot
|
||||
}
|
||||
|
||||
public class PlayerPawn : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private PlayerState playerState;
|
||||
@ -33,6 +39,16 @@ public class PlayerPawn : MonoBehaviour
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public bool IsBotPlayer
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public void AssignBotPlayerState(bool state)
|
||||
{
|
||||
IsBotPlayer = state;
|
||||
}
|
||||
|
||||
public void SetPlayerSelectionState(bool state)
|
||||
{
|
||||
canSelectPlayerFromHome = state;
|
||||
@ -68,7 +84,7 @@ public class PlayerPawn : MonoBehaviour
|
||||
|
||||
private void OnMouseDown()
|
||||
{
|
||||
if (!canSelectPlayerFromHome) return;
|
||||
if (IsBotPlayer || !canSelectPlayerFromHome) return;
|
||||
|
||||
SetGameplayManager();
|
||||
gameplayManager.OnPawnSelected(this);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user