void TestWorlds() { var w2 = LoadFromFile2(4); //var w = new WorldSlow(w2.Screen); var w = Generate.from_ascii(w2.Screen); //var ai = new WaveAI_2(); var ai = new KillerFallingAI(); var watch = new System.Diagnostics.Stopwatch(); var watch2 = new System.Diagnostics.Stopwatch(); for (var i = 0; i < 600 && w.is_playable(); i++) { var c = ai.play(w.render(), w2); var dir = Controller.char2dir(c); watch.Start(); w.control(dir); w.update(); watch.Start(); var st = 0;// w.Clone().render().Sum(x => x.Count(y => y == 'O')); watch.Stop(); textBox1.Lines = w.render(false, true).ToArray(); Application.DoEvents(); watch2.Start(); w2.control(dir); w2.update(); watch2.Start(); var st2 = 0;// w2.Clone().Screen.Sum(x => x.Count(y => y == 'O')); watch2.Stop(); var r = w.render() .Select(x => x.Replace('|', '/').Replace('\\', '/').Replace('-', '/')).ToArray(); var r2 = w2.Screen.Select(x => x.Replace('|', '/').Replace('\\', '/').Replace('-', '/').Replace('1', '*').Replace('2', '*').Replace('3', '*').Replace('4', '*')).ToArray(); var eq = r.SequenceEqual(r2); if (!eq || st != st2) { Game.log_function(i + ": " + eq); } } Game.log_function("done !!!"); Game.log_function("world #1: " + watch.ElapsedMilliseconds); Game.log_function("world #2: " + watch2.ElapsedMilliseconds); }
public char play(string[] screen, World world0) { //if (false && _frame++ == 0) //{ // var www = Wave.CreatePathsFull(world0, world0.player_y, world0.player_x, "*", ":", true, 2, false, 0, null).OrderBy(x => x.Y + x.X).Where(x => x.World.is_playable()); // foreach (var scored in www) // { // var path = scored.GetPath().Reverse().Select(x => x.Move).ToArray(); // _path = new Queue<Move>(path); // return _path.Dequeue().Control; // } //} if (_path.Count != 0) { return(_path.Dequeue().Control); } var t5 = Timings.Start(5); var player = screen.FindItem("A").FirstOrDefault(); var data = Wave.CreatePaths(screen, player[0], player[1], "*", "*:", true, 0, 0, null, Move.Moves2) .OrderBy(x => x.StepsCount) .Where(x => CollectorAI.CalcFalling(screen, x.Y, x.X) == 0) //.Take(20) .Select(step => { var count = -1; if (step.StepsCount < 20) { var scr = (string[])screen.Clone(); scr.SetAt(player[0], player[1], ' '); scr.SetAt(step.Y, step.X, 'A'); count = Wave.CreatePaths(scr, step.Y, step.X, "*", "*:", true, 0, 0, null, Move.Moves2) .Count(x => x.StepsCount < 20 && CollectorAI.CalcFalling(scr, x.Y, x.X) == 0); } return(new { Step = step, Count = count }); }) //.Where(x => x.Step.StepsCount < 19) //.OrderBy(x => world0.streak >= 3 ? x.Step.StepsCount : 0) .OrderBy(x => x.Step.StepsCount) .ThenBy(x => + x.Count) // !!!! minus - .ToArray(); //var data = Wave.CreatePaths(screen, player[0], player[1], "*", ":", true, 0, 0, null, Move.Moves2) // .OrderBy(x => x.StepsCount) // .Where(x => CollectorAI.CalcFalling(screen, x.Y, x.X) == 0) // .Take(20) // .Select(step => // { // var count = -1; // if (step.StepsCount < 20) // { // var scr = (string[])screen.Clone(); // scr.SetAt(player[0], player[1], ' '); // scr.SetAt(step.Y, step.X, 'A'); // var w2 = Wave.CreatePaths(scr, step.Y, step.X, "*", ":", true, 0, 0, null, Move.Moves2) // .Where(x => x.StepsCount <= 20 && CollectorAI.CalcFalling(scr, x.Y, x.X) == 0) // .Take(20) // .ToArray(); // count = w2.Length; // foreach (var s2 in w2) // { // var scr2 = (string[])scr.Clone(); // scr2.SetAt(step.Y, step.X, ' '); // scr2.SetAt(s2.Y, s2.X, 'A'); // count += Wave.CreatePaths(scr2, s2.Y, s2.X, "*", ":", true, 0, 0, null, Move.Moves2) // .Count(x => x.StepsCount <= 20 && CollectorAI.CalcFalling(scr, x.Y, x.X) <= 0); // } // } // return new { Step = step, Count = count }; // }) // //.Where(x => x.Step.StepsCount < 19) // .OrderBy(x => world0.streak >= 3 ? x.Step.StepsCount : 0) // .ThenBy(x => x.Count) // .ToArray(); foreach (var item in data) { var path = item.Step.GetPath().Reverse().Select(x => x.Move).ToArray(); if (KillerFallingAI.ValidatePath(path, world0.Clone(), 3, false, "CollectorAI_2")) { _path = new Queue <Move>(path); t5.Stop(); return(_path.Dequeue().Control); } } t5.Stop(); var t6 = Timings.Start(6); { foreach (var scored in Wave.CreatePathsFull(world0, player[0], player[1], "*", ":", true, 2, false, 0, null)) { var path = scored.GetPath().Reverse().Take(3000).ToArray(); var moves = path.Select(x => x.Move).ToArray(); var last = (Step2)path.Last(); if (KillerFallingAI.ValidatePath(moves, world0.Clone() /*last.World.Clone()*/, 3, false, "CollectorAI_2:empty")) { _path = new Queue <Move>(moves); t6.Stop(); return(_path.Dequeue().Control); } } } t6.Stop(); return('q'); //return Move.None.Control; }
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 (_prevScore != world0.score) { _lastScoredFrame = _frame; _divider = 1; _prevScore = world0.score; } _frame++; if (_frame > 600) { _killer = null; if (_frame - _lastScoredFrame > 40) { _divider = Math.Max(_divider, _rnd.Next(2, 15)); } } else { _lastScoredFrame = _frame; } if (screen[screen.Length - 1][0] != '#') { screen = screen.Take(screen.Length - 1).ToArray(); } var diamondsLeft = screen.Sum(row => row.Count(z => z == '*')); var butterfliesLeft = screen.Sum(row => row.Count(z => @"/|\-".Contains(z))); if (diamondsLeft == 0 && butterfliesLeft == 0) { return('q'); } if (_killer != null) { _diamondsCollected = world0.diamonds_collected; var kkk = _killer.play(screen, world0); if (kkk == 'q') { _killer = null; } else { return(kkk); } } //if (_collector != null && world0.diamonds_collected == _diamondsCollected) //var c = _collector.play(screen, world0); //if (c != Move.None.Control) return c; return(_collector2.play(screen, world0)); //return _collector.play(screen, world0); //var pos = SimpleAI.find_player(screen); var x0 = world0.player_x; //pos[0]; var y0 = world0.player_y; //pos[1]; var h = screen.Length; var w = screen[0].Length; //if (_killPath.Count == 0 && _scanForKills) //{ // var path = KillerFallingAI.FindKillPath(screen, world0); // if (path != null && (path.Length <= 5/*5*/ || diamondsLeft <= 3 || world0.streak <= 3/*0*/)) // _killPath = new Queue<Move>(path); //} //if (_killPath.Count != 0) // return _killPath.Dequeue().Control; if (_scorePath.Count != 0 && _scorePath.Count % _divider != 0) // 1-cycled, %2- no { return(_scorePath.Dequeue().Control); } //if (false && world0.streak_expiry >= 20 && butterfliesLeft != 0 && _scanForRelease) //{ // var wave = new Wave(world0.Clone(), Butterfly.Chars, "", null); // wave.Update(y0, x0, false, 0); // if (wave.Width != butterfliesLeft) // { // var wave2 = new Wave(world0.Clone(), Butterfly.Chars, ":", scr => // { // foreach (var step in wave.Scored) // scr = scr.SetAt(step.Y, step.X, ' '); // //remove reached butterflies // return scr; // }); // wave2.Update(y0, x0, false, 0); // foreach (var scoreStep in wave2.Scored) // { // var path = wave2.GetSteps(scoreStep).Skip(1).Reverse().ToArray(); // var world = world0.Clone(); // foreach (var step in path) // { // world.control(step.Move.Dir); // world.update(); // } // if (world.is_playable() && path.Length > 0) // return path[0].Move.Control; // } // } // else // _scanForRelease = false; //} var depth = 1; var width = 10; var run = 0; foreach (var huntItem in new[] { "*" }) //, "@", "@" }) { Func <string[], string[]> transform = null; //if (run == 0) transform = MarkStones2Fall; if (run == 1) { transform = MarkDirtUpperButterfly; // ??? } //if (run == 2) transform = MarkDirtRowButterfly; if (run == 2) { transform = MarkDirt2Eat; } if (run == 3) { transform = MarkButterfly; } // !!!!!!!!!! //var wavesAll = new List<Wave>(); for (var limit = 1; limit <= 4; limit++) { //var waves = Wave.Process(y0, x0, world0.Clone(), depth, width, huntItem, ":*", transform, run == 0, limit); var wave = new WaveOld(world0.Clone(), huntItem, ":*", null); wave.Update(y0, x0, run == 0, limit); //wavesAll.AddRange(waves); //wavesAll = Wave.Sort(wavesAll).ToList(); foreach (var score in wave.Scored) { var path = score.GetPath().Reverse().ToArray(); if (path.Length > 0) { var world = world0.Clone(); var ok = true; var len = 0; var breakN = 2; for (var n = 0; n < path.Length + 0 && ok /*&& n < path.Length*/; n++) { if (n < path.Length) { world.control(path[n].Move.Dir); len++; } world.update(); ok = world.is_playable() && world.player_can_move();// && CanMove(screen, h, w); if (n < path.Length && path[n].Scored && --breakN <= 0) { break; } } //world.update(); // ????? чуть хуже //ok = world.is_playable() && world.player.can_move(); //var npos = FindItem(world.render(), h, w, "AX").First(); ok = ok && len != 0 && //world.player.point != null && WaveOld.CheckCanMove(world, world.player_y, world.player_x, 6) != null; //ok = len != 0 && ok && _killer.CheckPlayable(screen, world0, 3); if (ok || (butterfliesLeft == 0 && diamondsLeft == 1)) { _scorePath = new Queue <Move>(path.Take(len).Select(x => x.Move)); // get full path to score !!! + n-alive epsilon //scores.Add(Tuple.Create(path, world.score)); //return path[0].Move.Control; _scanForKills = !wave.Killed; return(_scorePath.Dequeue().Control); } } } } //width = -width; run++; } _scanForKills = true; var somePath = WaveOld.CheckCanMove(world0, y0, x0, 5); if (somePath != null) { _scorePath = new Queue <Move>(somePath.Select(x => x.Move)); return(_scorePath.Dequeue().Control); //return somePath[0].Move.Control; } //var moves = (Move[])Move.All.Clone(); //for (var i = 0; i < moves.Length; i++) //{ // var j = _rnd.Next(moves.Length); // var tmp = moves[i]; // moves[i] = moves[j]; // moves[j] = tmp; // foreach (var move in moves) // { // var world = world0.Clone();// Generate.from_ascii(screen); // world.control(move.Dir); // world.update(); // //if (world.is_playable() && _killer.CheckPlayable(screen, world, 3)) // if (world.is_playable() && Wave.CheckCanMove(world, y0, x0, 5)) // return move.Control; // } //} return(' '); }