private void Dfs(Map map, List<Directions> history) { var maxPrefixForDir = new Tuple<int, int>[dirs.Length]; for (int i = 0; i < dirs.Length; i++) maxPrefixForDir[i] = Tuple.Create(-1, i); for (int i = 0; i < 1; i++) { var directions = phrases.AsDirections[i]; for (int j = Math.Min(directions.Length - 1, history.Count); j >= 0; j--) { bool eq = true; for (int k = 0; k < j && eq; k++) if (directions[k] != history[history.Count - j + k]) eq = false; if (eq && map.IsGoodPath(directions.Skip(j))) { int index = (int)directions[j]; var pair = maxPrefixForDir[index]; if (j >= pair.Item1) maxPrefixForDir[index] = Tuple.Create(j, pair.Item2); break; } } } var dirsOrder = Enumerable.Range(0, dirs.Length).OrderByDescending(i => maxPrefixForDir[i]); foreach (var d in dirsOrder) DfsStep(map, (Directions)d, history); }
public Tuple<int, IEnumerable<Directions>> GetSpellLengthAndPath(Map map, UnitPosition target) { Tuple<int, IEnumerable<Directions>> best = null; int bestCost = -1; foreach (var sequence in GenerateSpellsSequences()) { var midPositions = new UnitPosition[sequence.Count]; var finish = target; for (int i = 0; i < sequence.Count; i++) midPositions[i] = finish = GetMidPositionByPhrase(finish, sequence[i], map.Unit.Unit.Period); var path = dfsFinder.GetSpellLengthAndPath(map, finish); if (path?.Item2 == null) continue; var maps = midPositions.Select(p => new Map(map.Id, map.Filled, new PositionedUnit(map.Unit.Unit, p), map.NextUnits, map.UsedPositions, map.Scores)).ToArray(); bool ok = true; for (int i = 0; i < sequence.Count && ok; i++) ok &= maps[i].IsGoodPath(sequence[i]); if (!ok) continue; var result = path.Item2.Concat(((IEnumerable<Directions[]>)sequence).Reverse().SelectMany(s => s)).ToArray(); if (map.IsGoodPath(result)) { if (!ChooseCarefully) return Tuple.Create<int, IEnumerable<Directions>>(0, result); var originalPhrase = phrases.ToOriginalPhrase(result.ToPhrase()); int cost = phrases.GetPowerScoreWithoutUniqueBonus(originalPhrase); if (cost > bestCost) { bestCost = cost; best = Tuple.Create<int, IEnumerable<Directions>>(0, result); } } } if (best == null) best = dfsFinder.GetSpellLengthAndPath(map, target); return best; }