コード例 #1
0
        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);
        }
コード例 #2
0
        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;
        }
コード例 #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
ファイル: WaveAI.cs プロジェクト: pwjyifeng/challenge_jsdash
        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(' ');
        }