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)); }
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)); }
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)); }
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)); }