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); }
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); }