private void CheckDeadend(List <IReadOnlyList <BoardPoint> > bestRoutes, GameBoard gameBoard)
        {
            var toExclude = new ConcurrentBag <IReadOnlyList <BoardPoint> >();

            Parallel.ForEach(bestRoutes, route =>
            {
                try
                {
                    var goal         = route.Last();
                    var otherTargets = NiceTargets(gameBoard).Except(new[] { goal });
                    foreach (var target in otherTargets)
                    {
                        var path = FindPath(goal, target, gameBoard);
                        if (path.Count > 0)
                        {
                            return;
                        }
                    }

                    toExclude.Add(route);
                    Console.WriteLine($"DEADEND {goal} {gameBoard.GetElementAt(goal)}");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });

            foreach (var deadend in toExclude)
            {
                bestRoutes.Remove(deadend);
            }
        }
        private void Report(BoardPoint start, BoardPoint next, IReadOnlyList <BoardPoint> best, GameBoard gameBoard,
                            string name = "GOTO")
        {
            var last = best.Last();

            Console.WriteLine($"{name} {gameBoard.GetElementAt(last)} at {last}\t{start} -> {next}");
        }
        private static bool IsAcceptablePath(GameBoard board, BoardPoint leftPoint)
        {
            var left = board.GetElementAt(leftPoint);

            return(left == BoardElement.None || left == BoardElement.FuryPill ||
                   left == BoardElement.Apple || left == BoardElement.Gold);
        }
        public IReadOnlyList <Route> FindRoutes(BoardPoint start, IsGoal isGoal, bool stopOnFirstGoal = false,
                                                int?maxLength = null)
        {
            var result = new List <Route>();

            var frontier = new Queue <BoardPoint>();

            frontier.Enqueue(start);

            var cameFrom = new Dictionary <BoardPoint, BoardPoint> {
                [start] = new BoardPoint()
            };

            while (frontier.Count > 0)
            {
                var current        = frontier.Dequeue();
                var currentElement = _board.GetElementAt(current);

                var lazyRouteLength = new Lazy <int>(() => GetRouteLength(cameFrom, start, current));

                if (isGoal(currentElement, current, () => lazyRouteLength.Value))
                {
                    result.Add(CreateRoute(cameFrom, start, current, currentElement));
                    if (stopOnFirstGoal)
                    {
                        break;
                    }
                }

                if (maxLength.HasValue && lazyRouteLength.Value > maxLength)
                {
                    break;
                }

                foreach (var next in GetNeighbors(current))
                {
                    if (!cameFrom.ContainsKey(next))
                    {
                        frontier.Enqueue(next);
                        cameFrom[next] = current;
                    }
                }
            }

            return(result);
        }
Exemplo n.º 5
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));
        }