private Intent GetBestIntent(TicTacTardStateWithAction action) { float maxValue = -1; Intent intent = action.intent; TicTacTardPlayer fakePlayer = new TicTacTardPlayer(2, "1"); for (int i = 5; i < 14; ++i) { Intent tempIntent = (Intent)i; if (TicTacTardGame.CanPlayIntent(action, tempIntent)) { TicTacTardState nextState = TicTacTardGame.PlayAction(action, fakePlayer, tempIntent, false); TicTacTardState calculatedState = ticTacTardStateWithActions.Find(state => state.IsSameState(nextState)); if (calculatedState != null && calculatedState.value > maxValue) { maxValue = calculatedState.value; intent = tempIntent; } } } return(intent); }
public void InitIntent(bool isHuman) { isInit = false; if (player.Count == 0) { switch (gameType) { case TicTacTardGameType.HumanVHuman: for (int i = 0; i < 2; i++) { player.Add(new TicTacTardPlayer(i, i.ToString())); } break; case TicTacTardGameType.HumanVBot: player.Add(new TicTacTardAndroid(0, "0")); player.Add(new TicTacTardPlayer(1, "1")); TicTacTardStateWithAction currentStateWithAction = new TicTacTardStateWithAction(currentState, GetRandomPossibleMove(currentState)); int safeLoopIteration = 0; bool policyIsStable = false; while (!policyIsStable && safeLoopIteration < 100) { ++safeLoopIteration; policyIsStable = (player[0] as TicTacTardAndroid).ComputeInitIntent(currentStateWithAction, true, true); } if (safeLoopIteration >= 100) { Debug.LogError("safeLoopIteration trigger : ExitComputeIntent"); } Debug.Log("Bot generate " + (player[0] as TicTacTardAndroid).ticTacTardStateWithActions.Count + " states"); break; case TicTacTardGameType.BotVBot: for (int i = 0; i < 2; i++) { player.Add(new TicTacTardAndroid(i, i.ToString())); } break; } } ((TicTacTardPlayer)player[0]).ResetScore(); ((TicTacTardPlayer)player[1]).ResetScore(); currentPlayer = (TicTacTardPlayer)player[0]; }
public TicTacTardPlayer(TicTacTardPlayer playerToClone) { id = playerToClone.id; isHuman = playerToClone.isHuman; token = playerToClone.token; scores = new Dictionary <Direction, int>(); for (int i = 0; i < 8; ++i) { scores.Add((Direction)i, 0); } foreach (KeyValuePair <Direction, int> score in playerToClone.scores) { scores[score.Key] = score.Value; } }
private void ChangePlayer() { currentPlayer = (TicTacTardPlayer)(currentPlayer.ID == 0 ? player[1] : player[0]); }
// 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); }
private TicTacEpisode GenerateEpisodeFromState(TicTacTardStateWithAction state) { TicTacEpisode episode = new TicTacEpisode(); Intent initialIntent = EpsilonGreedy(state); TicTacTardPlayer fakeOpponent1 = new TicTacTardPlayer(0, "0"); TicTacTardPlayer fakeOpponent2 = new TicTacTardPlayer(1, "1"); TicTacTardPlayer currentPlayer = fakeOpponent1; string tokenCurrentPlayer = Token; TicTacTardStateWithAction currentState = new TicTacTardStateWithAction(state, state.intent); currentState.reward = 0; currentState.WinScore = 0; currentState.Visits = 0; int safeLoopIteration = 0; while (currentState.nbActionPlayed < 9 && !fakeOpponent1.playerWon && !fakeOpponent2.playerWon && safeLoopIteration < 200) { ++safeLoopIteration; TicTacTardState newState; if (tokenCurrentPlayer == Token) { newState = TicTacTardGame.PlayAction(currentState, currentPlayer, initialIntent, false); if (newState == null) { initialIntent = TicTacTardGame.GetRandomPossibleMove(currentState); continue; } } else { newState = TicTacTardGame.PlayAction(currentState, currentPlayer, TicTacTardGame.GetRandomPossibleMove(currentState), false); if (newState == null) { continue; } } TicTacTardStateWithAction existingState = ticTacTardStateWithActions.Find(stateSaved => newState.IsSameState(stateSaved)); if (existingState == null) { TicTacTardStateWithAction initNewState = new TicTacTardStateWithAction(newState, TicTacTardGame.GetRandomPossibleMove(newState)); initNewState.prevState = currentState; currentState = initNewState; initialIntent = currentState.intent; ticTacTardStateWithActions.Add(currentState); } else { currentState = existingState; initialIntent = currentState.intent; } episode.EpisodeStates.Add(currentState); currentPlayer = tokenCurrentPlayer == fakeOpponent1.Token ? fakeOpponent2 : fakeOpponent1; tokenCurrentPlayer = currentPlayer.Token; } if (safeLoopIteration >= 200) { Debug.LogError("Safe loopIteration trigger : exit generate episode"); } if (fakeOpponent1.playerWon) { currentState.reward = 1; } else { currentState.reward = 0; } return(episode); }