public SnakeAction DoRun(GameBoard gameBoard)
        {
            var start = gameBoard.GetMyHead();

            if (start == null)
            {
                return(new SnakeAction(false, Direction.Stop));
            }

            var routes  = new ConcurrentBag <IReadOnlyList <BoardPoint> >();
            var targets = NiceTargets(gameBoard);

            Parallel.ForEach(targets, point =>
            {
                try
                {
                    var path = FindPath(start.Value, point, gameBoard);
                    if (path.Count > 0)
                    {
                        routes.Add(path);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });

            var bestRoutes = routes.OrderBy(r => r.Count).ToList();

            // todo: assign properties to each GOAL (route): enemy snake is near, amount of deadends, enemy with enrage is near, etc.
            CheckDeadend(bestRoutes, gameBoard);

            var best = bestRoutes.FirstOrDefault();

            if (best != null)
            {
                var next = best.Skip(1).First();
                Report(start.Value, next, best, gameBoard);

                if (next.X < start.Value.X)
                {
                    return(new SnakeAction(false, Direction.Left));
                }
                if (next.X > start.Value.X)
                {
                    return(new SnakeAction(false, Direction.Right));
                }
                if (next.Y < start.Value.Y)
                {
                    return(new SnakeAction(false, Direction.Up));
                }
                if (next.Y > start.Value.Y)
                {
                    return(new SnakeAction(false, Direction.Down));
                }
            }

            return(new SnakeAction(false, Direction.Stop));
        }
Ejemplo n.º 2
0
        private SnakeAction Think(GameBoard gameBoard, Stopwatch stopwatch)
        {
            var start = gameBoard.GetMyHead();

            if (start == null)
            {
                return(new SnakeAction(false, Direction.Stop));
            }
            var startElement = gameBoard.GetElementAt(start.Value);

            if (startElement == HeadSleep || startElement == HeadDead)
            {
                return(new SnakeAction(false, Direction.Stop));
            }


            var isFury = gameBoard.AmIEvil();

            var pathFinder = new PathFinder(gameBoard, isFury);

            // find all apples/coins
            var routes = pathFinder.FindRoutes(start.Value,
                                               (elem, point, requestRoute) => ConsiderGoal(elem, point, requestRoute, isFury));

            // find weighted routes
            var max = routes.OrderByDescending(r => r.Length).First();

            Console.WriteLine($"Max: {max.Length}");
            var weighted = FindWeightedRoutes(routes, pathFinder, gameBoard, max);

            // avoid deadend
            var possible = weighted.Where(w => !w.Properties.IsDeadEnd).ToList();

            if (possible.Count == 0)
            {
                Console.WriteLine("DEADEND!!!!");
                // choose the longest: in the future it will be changed
                return(RouteToAction(weighted.OrderByDescending(r => r.Route.Length).First(), start.Value));
            }


            // make a decision
            var best = Decide(possible, max, isFury, start.Value, pathFinder);

            return(RouteToAction(best, start.Value));
        }
Ejemplo n.º 3
0
        private SnakeAction RandomMove(GameBoard gameBoard)
        {
            var random          = new Random();
            var currentPosition = gameBoard.GetMyHead();

            do
            {
                var        direction    = (Direction)random.Next(Enum.GetValues(typeof(Direction)).Length - 1);
                BoardPoint nextPosition = currentPosition.Value;
                switch (direction)
                {
                case Direction.Down:
                    nextPosition = currentPosition.Value.ShiftTop();
                    break;

                case Direction.Left:
                    nextPosition = currentPosition.Value.ShiftRight();
                    break;

                case Direction.Right:
                    nextPosition = currentPosition.Value.ShiftLeft();
                    break;

                case Direction.Up:
                    nextPosition = currentPosition.Value.ShiftBottom();
                    break;

                case Direction.Stop:
                    continue;
                    break;
                }
                if (gameBoard.IsBadThingAt(nextPosition))
                {
                    continue;
                }
                return(new SnakeAction(false, direction));
            } while (false);
            var act = random.Next() % 2 == 0;

            return(new SnakeAction(false, Direction.Right));
        }
Ejemplo n.º 4
0
        private SnakeAction ClosestApple(GameBoard gameBoard)
        {
            Graph graph      = GraphCreator.Create(gameBoard);
            var   myPosition = gameBoard.GetMyHead().Value;

            var        weights     = graph.Dijkstra(graph[myPosition]);
            var        applePoints = gameBoard.GetApples();
            BoardPoint best        = applePoints.FirstOrDefault();
            double     bestWeight  = double.MaxValue;

            foreach (var point in applePoints)
            {
                if (weights[graph[point].NodeNumber] < bestWeight)
                {
                    bestWeight = weights[graph[point].NodeNumber];
                    best       = point;
                }
            }
            var bestNode = graph.Dijkstra(graph[myPosition], graph[best]);

            if (myPosition.ShiftBottom() == bestNode.BoardPoint)
            {
                return(new SnakeAction(false, Direction.Down));
            }
            if (myPosition.ShiftLeft() == bestNode.BoardPoint)
            {
                return(new SnakeAction(false, Direction.Left));
            }
            if (myPosition.ShiftRight() == bestNode.BoardPoint)
            {
                return(new SnakeAction(false, Direction.Right));
            }
            if (myPosition.ShiftTop() == bestNode.BoardPoint)
            {
                return(new SnakeAction(false, Direction.Up));
            }

            return(new SnakeAction(false, Direction.Up));
        }
        private static SnakeAction DoRun(GameBoard gameBoard)
        {
            if (!gameBoard.AmIEvil())
            {
                restEvelRound = 0;
            }
            else if (restEvelRound == 0)
            {
                restEvelRound = MaxEvelRounds;
            }

            if (restEvelRound > 0)
            {
                restEvelRound--;
            }


            var head = gameBoard.GetMyHead();

            if (head == null)
            {
                prevDirection = Direction.Right;
                return(new SnakeAction(IsEnemyInTheTail(gameBoard), prevDirection));
            }

            var huntingElements = gameBoard.FindAllElements(goodElements);
            var hunting         = huntingElements
                                  .OrderBy(element => Math.Abs(element.X - head.Value.X) + Math.Abs(element.Y - head.Value.Y))
                                  .FirstOrDefault(element => isNotDeadEnd2(gameBoard, element));

            if (hunting == null)
            {
                prevDirection = GetDefaultDirection(gameBoard, head.Value);
                return(new SnakeAction(IsEnemyInTheTail(gameBoard), prevDirection));
            }

            prevDirection = GetDirectionToTarget(gameBoard, head.Value, hunting);
            return(new SnakeAction(IsEnemyInTheTail(gameBoard), prevDirection));
        }