public IGameState GetNextState(List <IGameState> gameStates, Intent intentTrigger) { int x = gameState.GetPos().x; int y = gameState.GetPos().y; switch (intentTrigger) { case Intent.WantToGoBot: y -= 1; break; case Intent.WantToGoLeft: x -= 1; break; case Intent.WantToGoRight: x += 1; break; case Intent.WantToGoTop: y += 1; break; } return(gameStates.Find(state => { float epsilon = 0.00001f; Vector2Int statePos = state.GetPos(); return statePos.x == x && statePos.y == y; })); }
public TicTacTardState(TicTacTardState state, Vector2Int newToken, string tokenToPlace, bool updateDisplay) { visits = state.visits; winScore = state.winScore; List <List <ICell> > oldGridBoard = state.Grid; gridBoard = new List <List <ICell> >(); nbActionPlayed = state.nbActionPlayed + 1; for (int i = 0; i < oldGridBoard.Count; ++i) { gridBoard.Add(new List <ICell>()); for (int j = 0; j < oldGridBoard[i].Count; ++j) { gridBoard[i].Add(new TicTacTardCell(oldGridBoard[i][j] as TicTacTardCell, updateDisplay)); if (i == newToken.x && j == newToken.y) { ((TicTacTardCell)gridBoard[i][j]).token = tokenToPlace; } } } if (updateDisplay) { gridBoard[newToken.x][newToken.y].GetCellGameObject().transform.GetChild(0).GetComponent <TextMeshPro>().text = tokenToPlace; } }
public TicTacTardCell(TicTacTardCell cell, bool updateDisplay) { position = cell.position; CellType = cell.CellType; token = cell.token; playerId = cell.playerId; if (updateDisplay) { gameObject = cell.GetCellGameObject(); } }
public void PolicyEvaluation() { float delta; float gamma = 0.9f; float tetha = 0.1f; int safeLoopIteration = 0; ICell cell; do { delta = 0; ++safeLoopIteration; foreach (GameStateWithAction gameStateWithAction in gameStateWithActions) { Vector2Int pos = gameStateWithAction.gameState.GetPos(); cell = worldCells[pos.x][pos.y]; if ((goalX == pos.x && goalY == pos.y) || cell.GetCellType() == CellType.Obstacle) { continue; } float temp = gameStateWithAction.gameState.GetValue(); float newValue = 0; IGameState nextGameState = gameStateWithAction.GetNextState(gameStates, gameStateWithAction.intent); float nextReward = worldCells[nextGameState.GetPos().x][nextGameState.GetPos().y].GetReward(); newValue += 1 * (nextReward + gamma * nextGameState.GetValue()); gameStateWithAction.gameState.SetValue(newValue); delta = Math.Max(delta, Math.Abs(temp - gameStateWithAction.gameState.GetValue())); } } while (delta >= tetha && safeLoopIteration < 5000); if (safeLoopIteration >= 5000) { Debug.LogError("Safe loop iteration trigger, exit policyEvaluation"); } }
public bool PolicyImprovement() { bool policyStable = true; IPlayer fakePlayer = new GridWoldPlayer(); foreach (GameStateWithAction gameStateWithAction in gameStateWithActions) { Vector2Int currentPos = gameStateWithAction.gameState.GetPos(); ICell cell = worldCells[currentPos.x][currentPos.y]; if ((goalX == currentPos.x && goalY == currentPos.y) || cell.GetCellType() == CellType.Obstacle) { continue; } fakePlayer.SetCell(worldCells[currentPos.x][currentPos.y]); Intent intentToPlay = gameStateWithAction.intent; int maxValue = 0; Intent intentWithBestValue = GetIntentWithBestValue(gameStateWithAction, fakePlayer).intent; gameStateWithAction.intent = intentWithBestValue; if (intentToPlay != intentWithBestValue) { Debug.Log("State " + gameStateWithAction.gameState.GetPos() + " has " + intentToPlay + " redirect to " + intentWithBestValue); policyStable = false; } } if (!policyStable) { Debug.Log(">>>>>>>>> Call PolicyEvaluation"); PolicyEvaluation(); } return(policyStable); }
// return true if intent is correct public static TicTacTardState PlayAction(TicTacTardState state, TicTacTardPlayer player, Intent intent, bool updateDisplay) { Vector2Int vector2Int = new Vector2Int(0, 0); bool endGame = false; List <Direction> directions = new List <Direction>(); switch (intent) { case Intent.BotCenter: vector2Int.x = 1; vector2Int.y = 0; directions.Add(Direction.Line1); directions.Add(Direction.Column2); break; case Intent.BotLeft: vector2Int.x = 0; vector2Int.y = 0; directions.Add(Direction.Line1); directions.Add(Direction.Column1); directions.Add(Direction.Diagonal1); break; case Intent.BotRight: vector2Int.x = 2; vector2Int.y = 0; directions.Add(Direction.Line1); directions.Add(Direction.Column3); directions.Add(Direction.Diagonal2); break; case Intent.MidCenter: vector2Int.x = 1; vector2Int.y = 1; directions.Add(Direction.Line2); directions.Add(Direction.Column2); directions.Add(Direction.Diagonal1); directions.Add(Direction.Diagonal2); break; case Intent.MidLeft: vector2Int.x = 0; vector2Int.y = 1; directions.Add(Direction.Line2); directions.Add(Direction.Column1); break; case Intent.MidRight: vector2Int.x = 2; vector2Int.y = 1; directions.Add(Direction.Line2); directions.Add(Direction.Column3); break; case Intent.TopCenter: vector2Int.x = 1; vector2Int.y = 2; directions.Add(Direction.Line3); directions.Add(Direction.Column2); break; case Intent.TopLeft: vector2Int.x = 0; vector2Int.y = 2; directions.Add(Direction.Line3); directions.Add(Direction.Column1); directions.Add(Direction.Diagonal2); break; case Intent.TopRight: vector2Int.x = 2; vector2Int.y = 2; directions.Add(Direction.Line3); directions.Add(Direction.Column3); directions.Add(Direction.Diagonal1); break; } TicTacTardCell currentCell = state.Grid[vector2Int.x][vector2Int.y] as TicTacTardCell; if (currentCell?.token == "-1") { TicTacTardState newState = new TicTacTardState(state, vector2Int, player.Token, updateDisplay); player.IncrementScore(directions); return(newState); } else { if (updateDisplay) { Debug.Log("Token déjà placé"); } } return(null); }
public TicTacTardCell(Vector2Int position, CellType CellType) { this.position = position; this.CellType = CellType; token = "-1"; }
public void SetPostion(Vector2Int position) { this.position = position; }
public SooooookolatCell(float reward, CellType cellType, Vector2Int position) { this.reward = reward; this.cellType = cellType; this.position = position; }
public void ValueIteration() { IPlayer fakePlayer = new GridWoldPlayer(); float tetha = 0.1f; float delta; float gamma = 0.8f; int safeLoopIteration = 0; do { ++safeLoopIteration; delta = 0; foreach (GameStateWithAction gameStateWithAction in gameStateWithActions) { Vector2Int currentPos = gameStateWithAction.gameState.GetPos(); ICell currentCell = worldCells[currentPos.x][currentPos.y]; fakePlayer.SetCell(currentCell); if ((goalX == currentPos.x && goalY == currentPos.y) || currentCell.GetCellType() == CellType.Obstacle) { continue; } float temp = gameStateWithAction.gameState.GetValue(); float newValue = 0; for (int i = 1; i < 5; ++i) { if (GridWORDOGame.CanMove(fakePlayer, worldCells, (Intent)i)) { IGameState nextGameState = gameStateWithAction.GetNextState(gameStates, (Intent)i); float nextReward = worldCells[nextGameState.GetPos().x][nextGameState.GetPos().y].GetReward(); float tempValue = 1 * nextReward + (gamma * nextGameState.GetValue()); if (tempValue > newValue) { newValue = tempValue; } } } gameStateWithAction.gameState.SetValue(newValue); delta = Math.Max(delta, Math.Abs(temp - gameStateWithAction.gameState.GetValue())); } } while (delta >= tetha && safeLoopIteration < 5000); if (safeLoopIteration >= 5000) { Debug.LogError("Safe loop iteration trigger, exit valueIteration"); return; } foreach (GameStateWithAction gameStateWithAction in gameStateWithActions) { Vector2Int currentPos = gameStateWithAction.gameState.GetPos(); fakePlayer.SetCell(worldCells[currentPos.x][currentPos.y]); gameStateWithAction.intent = GetIntentWithBestValue(gameStateWithAction, fakePlayer).intent; } }
public void SetPostion(Vector2Int position) { throw new System.NotImplementedException(); }
public GridWorldCell(Vector2Int pos, CellType type, float reward) { position = pos; cellType = type; this.reward = reward; }