コード例 #1
0
        public static IEnumerable <Method.Path> Process(double[][] matrix)
        {
            var obj  = new TSPSolver();
            var step = obj.solve(matrix.Length, cloneFull(matrix));

            if (obj.route.Count <= 0)
            {
                yield break;
            }
            var first = obj.route.Keys.Min();
            var prev  = first;
            var next  = 0;
            var found = false;

            while ((next = obj.getNextRoute(prev, out found)) != first && found)
            {
                yield return(new Method.Path {
                    From = prev, To = next, Distance = (int)matrix[prev][next]
                });

                prev = next;
            }
            if (found)
            {
                yield return new Method.Path {
                           From = prev, To = next, Distance = (int)matrix[prev][next]
                }
            }
            ;
        }
コード例 #2
0
        public static string Test()
        {
            var m0 = new int[5, 5] {
                { -1, 20, 18, 12, 8 }, { 5, -1, 14, 7, 11 }, { 12, 18, -1, 6, 11 }, { 11, 17, 11, -1, 12 }, { 5, 5, 5, 5, -1 }
            };
            var m1 = new double[m0.GetLength(0)][];

            for (var i = 0; i < m1.Length; i++)
            {
                m1[i] = new double[m1.Length];
                for (var j = 0; j < m1.Length; j++)
                {
                    m1[i][j] = m0[i, j] > 0 ? m0[i, j] : int.MaxValue;
                }
            }
            var obj  = new TSPSolver();
            var step = obj.solve(5, m1);

            return(obj.getSortedPath("a b c d e f"));
        }
コード例 #3
0
        public char play(string[] screen, World world0)
        {
            if (_path.Count != 0)
            {
                return(_path.Dequeue().Control);
            }

            var player = screen.FindItem("A").FirstOrDefault();

            var diamonds = screen.FindItem("*").ToList();

            if (diamonds.Count == 0)
            {
                return('q');
            }
            if (_diamondsTotal == -1)
            {
                _diamondsTotal = diamonds.Count;
            }
            var  collected       = _diamondsTotal - diamonds.Count;
            bool startFromPlayer = world0.streak > 5 || collected > 0;

            //if (startFromPlayer)
            //    diamonds = diamonds
            //        .OrderBy(x => Math.Abs(x[0] - player[0]) + Math.Abs(x[1] - player[1]))
            //        .Take(30)
            //        .ToList();
            if (startFromPlayer)
            {
                diamonds.Insert(0, player);
            }

            var waves = diamonds
                        .Select(pos => new
            {
                Coord = pos,
                Fall  = CalcFalling(screen, pos[0], pos[1]),
                //Scored = Wave.CreatePaths(screen, pos[0], pos[1], startFromPlayer ? "A*" : "*", ":", true, 0, 0, null, Move.Moves2),
                Scored = Wave.CreatePaths(screen, pos[0], pos[1], "", ":*", true, 0, 0, diamonds.ToArray(), Move.Moves2),
            })
                        //.Where(x => x.Scored.Length != 0)
                        .ToArray();
            var dict = waves.Select((x, i) => new { Id = i, Key = x.Coord[0] + ":" + x.Coord[1] })
                       .ToDictionary(x => x.Key, x => x.Id);

            var matrix = Enumerable.Range(0, waves.Length)
                         .Select(y => Enumerable.Range(0, waves.Length).Select(x => double.PositiveInfinity).ToArray())
                         .ToArray();

            var solution = default(List <Method.Path>);

            if (matrix.Length > 2)
            {
                foreach (var item in waves)
                {
                    var fromId = dict[item.Coord[0] + ":" + item.Coord[1]];
                    foreach (var scored in item.Scored)
                    {
                        var toId  = dict[scored.Y + ":" + scored.X];
                        var steps = scored.StepsCount + waves[toId].Fall;
                        //if (!startFromPlayer || (fromId != 0 && toId != 0)) // ???????
                        //steps = steps < 10 && (!startFromPlayer || toId != 0) ? steps : 10000 + steps;
                        //if (steps > 20) steps *= 4;
                        matrix[fromId][toId] = steps;
                    }
                }
                solution = TSPSolver.Process(matrix).ToList();
                if (!startFromPlayer && collected == 0)// && solution.Any(x => x.Distance > 20))
                {
                    //if (solution.Any(x => x.Distance > 19))
                    //    while (solution[solution.Count - 1].Distance <= 19)
                    //    {
                    //        var last = solution[solution.Count - 1];
                    //        solution.RemoveAt(solution.Count - 1);
                    //        solution.Insert(0, last);
                    //    }

                    //var idx = CalcRing(solution.Select(x => x.Distance).ToArray());
                    //while (idx-- > 0)
                    //{
                    //    var fst = solution[0];
                    //    solution.RemoveAt(0);
                    //    solution.Add(fst);
                    //}

                    foreach (var id in new[] { solution[0].From }.Concat(solution.Select(x => x.To)))
                    {
                        var scored = Wave.CreatePaths(screen, player[0], player[1], "", ":", true, 0, 0, new[] { waves[id].Coord }, Move.Moves2).FirstOrDefault();
                        if (scored != null)
                        {
                            var path = scored.GetPath().Reverse().Select(x => x.Move).ToArray();
                            if (KillerFallingAI.ValidatePath(path, world0.Clone(), 3, false, "CollectorAI"))
                            {
                                _path = new Queue <Move>(path);
                                return(_path.Dequeue().Control);
                            }
                        }
                    }
                }
            }

            if (dict.Count != 0)
            {
                var toId   = solution != null && solution.Count != 0 ? solution[0].To : dict.Values.Max();
                var to     = waves[toId].Coord;
                var scored = waves[0].Scored.FirstOrDefault(item => item.Y == to[0] && item.X == to[1]);
                if (scored != null)
                {
                    if (scored.StepsCount >= 20)
                    {
                        var best = waves[0].Scored.OrderBy(x => x.StepsCount).First();
                        if (best.StepsCount < 20)
                        {
                            scored = best;
                        }
                    }
                    var path = scored.GetPath().Reverse().Select(x => x.Move).ToArray();
                    if (KillerFallingAI.ValidatePath(path, world0.Clone(), 3, false, "CollectorAI"))
                    {
                        _path = new Queue <Move>(path);
                        return(_path.Dequeue().Control);
                    }
                }
            }

            {
                foreach (var scored in Wave.CreatePathsFull(world0, player[0], player[1], "*", ":", true, 2, false, 0, null))
                {
                    var path  = scored.GetPath().Reverse().Take(3).ToArray();
                    var moves = path.Select(x => x.Move).ToArray();
                    var last  = (Step2)path.Last();
                    if (KillerFallingAI.ValidatePath(moves, last.World.Clone(), 3, false, "CollectorAI"))
                    {
                        _path = new Queue <Move>(moves);
                        return(_path.Dequeue().Control);
                    }
                }
            }

            return(Move.None.Control);
        }
コード例 #4
0
        public char play(string[] screen, World world0)
        {
            if (world0.frame < 0)
            {
                return(' ');
            }

            var pos = screen.FindItem(Butterfly.Chars).ToArray();

            foreach (var p in pos)
            {
                _bpos.Enqueue(p);
            }
            while (_bpos.Count > 2 * pos.Length)
            {
                _bpos.Dequeue();
            }
            //_bpos = new Queue<int[]>(pos);

            var butterfliesCount = pos.Count();
            var killed           = world0.frame != 0 && _prevButterfliesCount != butterfliesCount;

            _prevButterfliesCount = butterfliesCount;
            if (killed)
            {
                _lastKillFrame = world0.frame;
            }

            if (world0.frame < 10)
            {
                return(' ');
            }
            if (pos.Length == 0 && screen.FindItem("1234").Count() == 0)
            {
                //var path = Method.Process(screen, world0).OrderBy(x => x.From).ToArray();
                var w    = new System.Diagnostics.Stopwatch();
                var path = TSPSolver.Process(screen, world0).ToArray();
                w.Stop();
                log("path len: {0}, dist: {1}, breaks: {2}, time: {3} ms",
                    path.Length, path.Sum(x => x.Distance), path.Count(x => x.Distance > 20), w.ElapsedMilliseconds);
                return('q');
            }

            var t0 = Timings.Start(0);

            if (_killPath.Count == 0 || _scanForKills)
            {
                var path = FindKillPath(screen, world0);
                if (path != null && (_killPath.Count == 0 || path.Length < _killPath.Count))// || !_isKillPath))
                {
                    log("kill path found: {0}", path.Length);
                    _killPath   = new Queue <Move>(path);
                    _isKillPath = true;
                    _time2kill  = Math.Max(3 * path.Length, _time2kill);
                    //_scanForKills = false;
                }
            }
            t0.Stop();

            if (_killPath.Count != 0)
            {
                log("{0}: {1} / {2} [{3}]", world0.frame, _killPath.Peek(), _killPath.Count, world0.get_hash());
                return(_killPath.Dequeue().Control);
            }
            _scanForKills = true;
            _num++;
            _isKillPath = false;

            if (FindOpenPath(world0) || FindEmptyPath(world0))
            {
                log("{0}: {1} / {2} [{3}]", world0.frame, _killPath.Peek(), _killPath.Count, world0.get_hash());
                return(_killPath.Dequeue().Control);
            }
            log("{0}: {1} [{2}]", world0.frame, Move.None, world0.get_hash());
            return(Move.None.Control);
        }
コード例 #5
0
        public static IEnumerable <Method.Path> Process(string[] screen, World world0)
        {
            var dict = new Dictionary <Tuple <int, int>, int>();

            for (var y = 0; y < screen.Length; y++)
            {
                for (var x = 0; x < screen[y].Length; x++)
                {
                    if (screen[y][x] == '*')
                    {
                        dict[Tuple.Create(y, x)] = dict.Count;
                    }
                }
            }
            var matrix = Enumerable.Range(0, dict.Count)
                         .Select(_ => Enumerable.Range(0, dict.Count).Select(__ => double.PositiveInfinity).ToArray())
                         .ToArray();
            var isolated = new HashSet <int>();

            foreach (var item in dict.ToArray())
            {
                var src  = item.Value;
                var wave = new WaveOld(world0.Clone(), "*", ":*", null);
                wave.Update(item.Key.Item1, item.Key.Item2, true, 0);
                foreach (var scored in wave.Scored)
                {
                    var coord = Tuple.Create(scored.Y, scored.X);
                    if (dict.ContainsKey(coord))
                    {
                        var dst = dict[coord];
                        var val = scored.StepsCount < 20 ? 20 : 10000;
                        matrix[src][dst] = val;
                    }
                }
                if (wave.Scored.Length == 0)
                {
                    dict.Remove(item.Key);
                    isolated.Add(src);
                }
            }
            if (isolated.Count != 0)
            {
                matrix = matrix.Where((x, i) => !isolated.Contains(i))
                         .Select(z => z.Where((x, i) => !isolated.Contains(i)).ToArray())
                         .ToArray();
            }

            //for (var i = 0; i < matrix.Length; i++)
            //    System.Diagnostics.Trace.WriteLine("[" + i + "] " + string.Join(" ", matrix[i]));

            var obj   = new TSPSolver();
            var step  = obj.solve(dict.Count, cloneFull(matrix));
            var first = obj.route.Keys.Min();
            var prev  = first;
            var next  = 0;
            var found = false;

            while ((next = obj.getNextRoute(prev, out found)) != first && found)
            {
                yield return(new Method.Path {
                    From = prev, To = next, Distance = (int)matrix[prev][next]
                });

                prev = next;
            }
            if (found)
            {
                yield return new Method.Path {
                           From = prev, To = next, Distance = (int)matrix[prev][next]
                }
            }
            ;
        }