public string Solve(Problem problem, int seed, string[] powerPhrases) { var finalPowerPhraseBuilder = new SimplePowerPhraseBuilder(powerPhrases); var spelledPhrases = new bool[powerPhrases.Length]; var solution = new List<MoveType>(); var game = new SolverGame(problem, seed, powerPhrases); while (true) { switch (game.state) { case GameBase.State.WaitUnit: game.Step(); break; case GameBase.State.UnitInGame: var reachablePositions = new ReachablePositionsWithWords(game.map, powerPhrases, spelledPhrases); var evaluatePositions = new EvaluatePositions2(game.map); var endPositions = reachablePositions.EndPositions(game.currentUnit); var estimated = new Dictionary<Unit, double>(); var bestPosition = endPositions.ArgMax(p => { double value; if (estimated.TryGetValue(p.Item1, out value)) return value; return estimated[p.Item1] = evaluatePositions.Evaluate(p.Item1); }); var score = evaluatePositions.Evaluate(bestPosition.Item1); var wayToBestPosition = bestPosition.Item2; var unitSolution = staticPowerPhraseBuilder.Build(wayToBestPosition.path); SolutionAdded(game, unitSolution); game.ApplyUnitSolution(unitSolution); spelledPhrases = wayToBestPosition.spelledWords; solution.AddRange(wayToBestPosition.path); break; case GameBase.State.EndInvalidCommand: case GameBase.State.EndPositionRepeated: throw new InvalidOperationException(string.Format("Invalid state: {0}", game.state)); case GameBase.State.End: return finalPowerPhraseBuilder.Build(solution); default: throw new ArgumentOutOfRangeException(); } } }
private IEnumerable<State> FindNextStates(State state) { var map = state.lastmap.Clone(); map.LockUnit(state.lastUnit); map.RemoveLines(); var nextUnit = units[state.nunits]; var reachablePositions = new ReachablePositionsWithWords(map, powerPhrases, state.spelledPhrases); var evaluatePositions = new EvaluatePositions2(map); var endPositions = reachablePositions.EndPositions(nextUnit); var estimated = new Dictionary<Unit, Tuple<double, int>>(); Tuple<Unit, ReachablePositionsWithWords.VisitedInfo>[] bestPositions = endPositions.OrderByDescending( p => { Tuple<double, int> value; var unit = p.Item1; if (!estimated.TryGetValue(unit, out value)) value = estimated[p.Item1] = evaluatePositions._Evaluate(p.Item1); return value.Item1; }).Take(100).ToArray(); foreach (var position in bestPositions) { var unit = position.Item1; var ndropped = estimated[unit].Item2; var move_score = CountPoints(unit.members.Count, state.lastDroopedLines, estimated[unit].Item2); var score = state.score + move_score; yield return new State() { lastmap = map, lastUnit = unit, nunits = state.nunits + 1, lastDroopedLines = ndropped, score = score, solution = state.solution.Concat(position.Item2.path).ToArray(), spelledPhrases = position.Item2.spelledWords, sumPositionEstimates = state.sumPositionEstimates + 10 + estimated[unit].Item1 }; } }