Example #1
0
 public static Step[] CheckCanMove(World world0, int y, int x, int depth, string[][] screens = null)
 {
     for (var limit = screens != null ? 1 : 1; limit <= 3; limit++)
     {
         var push = false;
         foreach (var eatItem in new[] { ":", ":*", ":*O" })
         {
             var wave = new WaveOld(world0.Clone(), "", eatItem, null);
             wave.Update(y, x, push, 0, int.MaxValue, depth, screens);
             foreach (var step in wave.Scored)
             {
                 var path  = step.GetPath().Reverse().ToArray();
                 var world = world0.Clone();
                 foreach (var st in path)
                 {
                     world.control(st.Move.Dir);
                     world.update();
                 }
                 var dest = path.Last();
                 if (world.is_playable() && world.player_x == dest.X && world.player_y == dest.Y)
                 {
                     return(path);
                 }
             }
             push = true;
         }
     }
     return(null);
 }
Example #2
0
        private WaveOld CloneAtScore(int index)
        {
            var path   = GetSteps(_scored[index]).Reverse().ToArray();
            var world  = _world.Clone();
            var killed = 0;

            foreach (var step in path)
            {
                var butterflies_killed = world.butterflies_killed;
                world.control(step.Move.Dir);
                world.update();
                if (killed == 0 && butterflies_killed != world.butterflies_killed)
                {
                    killed = step.StepsCount;
                }
            }
            if (killed != 0)
            {
                //var
            }

            if (!world.is_playable())
            {
                return(null);
            }
            //var scr = world.render(false, false).ToArray();

            // ??????????????????
            //var wave = new Wave(world.Clone(), _huntItem, _eatItem, _transform);
            var wave = new WaveOld(_world.Clone(), _huntItem, _eatItem, _transform);

            //wave._depth = _depth;
            wave._initial = _initial;
            wave._parent  = _parent;
            wave._scored.AddRange(_scored);
            wave._collected = new HashSet <Tuple <int, int> >(_collected);
            wave._killed    = _parent != null && _parent._killed != 0 ? _parent._killed :
                              killed != 0 ? wave._depth : 0;
            wave._streak = (_parent != null ? _parent._streak : 0) + (path.Length <= 18 ? 1 : 0);
            return(wave);
        }
Example #3
0
 public WaveOld(WaveOld parent, Step initial)
 {
     _parent    = parent;
     _depth     = _parent._depth + 1;
     _initial   = initial;
     _screen    = parent._screen.ToArray();
     _world     = parent._world;
     _killed    = parent._killed;
     _streak    = parent._streak;
     _transform = parent._transform;
     //_height = parent._height;
     //_width = parent._width;
     _huntItem = _parent._huntItem;
     _eatItem  = _parent._eatItem;
     //_steps = new Step[_world.height, _world.width];
     foreach (var item in _parent._collected)
     {
         _collected.Add(item);
     }
     _collected.Add(Tuple.Create(_initial.Y, _initial.X));
 }
Example #4
0
        public static Path[] Process(string[] screen, World world)
        {
            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 = new int[dict.Count, dict.Count];

            for (var i = 0; i < dict.Count; i++)
            {
                for (var j = 0; j < dict.Count; j++)
                {
                    matrix[i, j] = -1;
                }
            }
            foreach (var item in dict)
            {
                var src  = item.Value;
                var wave = new WaveOld(world.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);
                    var dst   = dict[coord];
                    matrix[src, dst] = scored.StepsCount;
                }
            }
            return(Process(matrix).ToArray());
        }
Example #5
0
        public static WaveOld[] Process(int y0, int x0, World world, int depth, int width,
                                        string huntItem, string eatItem, Func <string[], string[]> transform, bool push, int limit)
        {
            var start = new WaveOld(world, huntItem, eatItem, transform);

            start.Update(y0, x0, push, limit, width);
            var list = new List <WaveOld>();

            list.Add(start);

            var index = 0;

            for (var iteration = 0; iteration < depth; iteration++)
            {
                var sz = list.Count;
                if (sz > 1000)
                {
                    break;
                }
                for (var i = index; i < sz; i++)
                {
                    var wave  = list[i];
                    var range = width > 0 ?
                                Enumerable.Range(0, wave._scored.Count).Take(width) :
                                Enumerable.Range(0, wave._scored.Count).Skip(-width).Take(-width);
                    foreach (var pos in range)
                    {
                        var cloned = wave.CloneAtScore(pos);
                        if (cloned != null)
                        {
                            //var child = new Wave(cloned, wave._scored[pos]);
                            var child = cloned;
                            child._depth++;
                            child._scored.Clear();
                            child._initial = wave._scored[pos]; // StepCount != 0 !!!
                            //child._initial = new Step(wave._scored[pos].Y, wave._scored[pos].X);
                            child._collected.Add(Tuple.Create(child._initial.Y, child._initial.X));

                            child.Update(wave._scored[pos].Y, wave._scored[pos].X, push, limit);
                            list.Add(child);
                        }
                    }
                }
                index = sz;
            }

            foreach (var wave in list)
            {
                wave.UpdateStepsCount();
            }

            //if (transform == null && list.Count != 0) System.Diagnostics.Trace.WriteLine("max(depth): " + list.Max(x => x._depth));

            //return list.OrderBy(x => -x._world.butterflies_killed).ThenBy(x => -x._world.score).ToArray();

            //return list.OrderBy(x => x.StepsCount).ToArray();

            //return list.OrderByDescending(x => x._depth).ThenByDescending(x => x._killed).ThenByDescending(x => (float)x.StepsCount / x._depth).ToArray();

            // best ???
            //return list.OrderByDescending(x => x._killed).ThenByDescending(x => x._depth).ThenByDescending(x => (float)x.StepsCount / x._depth).ToArray();

            return(list.OrderBy(x => - x._streak).ThenBy(x => x._killed != 0 && x._killed <= -x._streak ? x._killed : int.MaxValue).ThenBy(x => (float)-x._depth / x.StepsCount).ThenBy(x => - x._depth).ToArray());

            //return list.OrderBy(x => x._killed > 0 && x._killed < 7 ? x._killed : int.MaxValue).ThenBy(x => (float)-x._depth / x.StepsCount).ThenBy(x => -x._depth).ToArray();

            //return list.OrderBy(x => (float)-x._depth / x.StepsCount).ThenBy(x => -x._depth).ToArray();
        }
Example #6
0
        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(' ');
        }
Example #7
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]
                }
            }
            ;
        }