예제 #1
0
        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);
        }
예제 #2
0
        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;
        }