private bool RecursiveCalculateSolution(LevelSimulationSnapshot state) { _numCalculationSteps++; _oldStates[state.Hash] = state; foreach (var move in state.GetMoves().ToArray().Shuffled()) { var newState = state.MakeMove(move); if (_oldStates.ContainsKey(newState.Hash)) { continue; // Already examined this tree } if (newState.IsGameOver()) { if (newState.HasWon()) { _movesToWin.Add(move); return(true); } } else if (RecursiveCalculateSolution(newState)) { _movesToWin.Add(move); return(true); } } return(false); }
public bool CalculateSolution(LevelSimulationSnapshot state) { var sw = Stopwatch.StartNew(); _oldStates = new Dictionary <string, LevelSimulationSnapshot>(); _movesToWin = new List <AIMove>(); _numCalculationSteps = 0; CanWin = RecursiveCalculateSolution(state); Debug.Log($"AI Brute: Iterations {_numCalculationSteps++} in {sw.ElapsedMilliseconds}ms"); return(true); }
private PossibleOutcomes RecursiveCalculateMoveTree(LevelSimulationSnapshot state, string stateHash) { _oldStates[stateHash] = state; _possibleOutcomes[stateHash] = PossibleOutcomes.Uncalculated; foreach (var move in state.GetMoves().ToArray().Shuffled()) { var newState = state.MakeMove(move); var newStateHash = newState.Hash; if (_oldStates.ContainsKey(newStateHash)) { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | _possibleOutcomes[newStateHash]; } else if (newState.IsGameOver()) { _numberOfWinningBranches++; var stars = newState.GetStars(); if (stars == 3) { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | PossibleOutcomes.ThreeStar; } else if (stars == 2) { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | PossibleOutcomes.TwoStar; } else { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | PossibleOutcomes.OneStar; } } else { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | RecursiveCalculateMoveTree(newState, newStateHash); } } if ((int)_possibleOutcomes[stateHash] == 0) { _numberOfDeadBranches++; } if ((int)_possibleOutcomes[stateHash] <= 1) { _possibleOutcomes[stateHash] = _possibleOutcomes[stateHash] | PossibleOutcomes.DeadEnd; } return(_possibleOutcomes[stateHash]); }
public MoveTreeData CalculateMoveTree(LevelSimulationSnapshot state) { _initialState = state.Hash; _oldStates = new Dictionary <string, LevelSimulationSnapshot>(); _possibleOutcomes = new Dictionary <string, PossibleOutcomes>(); _numberOfDeadBranches = 0; _numberOfWinningBranches = 0; RecursiveCalculateMoveTree(state, state.Hash); var data = new MoveTreeData { HasThreeStar = (_possibleOutcomes[_initialState] & PossibleOutcomes.ThreeStar) != 0, HasTwoStar = (_possibleOutcomes[_initialState] & PossibleOutcomes.TwoStar) != 0, HasOneStar = (_possibleOutcomes[_initialState] & PossibleOutcomes.OneStar) != 0, NumberOfDeadBranches = _numberOfDeadBranches, NumberOfWinningBranches = _numberOfWinningBranches }; new JsonFileStored <MoveTreeData>(Path.Combine(Application.persistentDataPath, "MoveTree.json"), () => new MoveTreeData()).Write(_ => data); return(data); }
public bool Equals(LevelSimulationSnapshot obj) => obj.Hash.Equals(Hash);