public Node(Node parent, Position position) { Parent = parent; Position = position; DistanceFromStart = 0; DistanceToGoal = 0; }
public Position GetClosestWalkablePositionWithUnknownNeighbour(Position fromPos, Func<Position, bool> predicate) { return AllPositions.Where(IsWalkable) .Where(x => x.GetNeighbours().Any(n => GetPositionValue(n) == uint.MaxValue)) .OrderBy(fromPos.Distance) .FirstOrDefault(predicate); }
public bool IsWalkable(Position pos) { var value = (TileFlags)GetPositionValue(pos); if (value == TileFlags.UNKNOWN) return true; if (value == TileFlags.NOTHING) return false; if ((value & (TileFlags.PERIMETER | TileFlags.BLOCKED)) > 0) return false; return true; }
public static IEnumerable<Position> CalculatePath(Position start, Position end, Func<Position, bool> isWalkable) { var startNode = new Node(null, start); var aStar = new HashSet<Position>(); var open = new List<Node> { startNode }; var result = new LinkedList<Position>(); while (open.Any()) { var closestNode = open.OrderBy(node => node.DistanceFromStart).First(); open.Remove(closestNode); if (closestNode.Position.Equals(end)) { while (true) { result.AddFirst(closestNode.Position); if (closestNode.Parent == null) { return result; } closestNode = closestNode.Parent; } } var walkableNeighbours = closestNode.Position.GetNeighbours().Where(isWalkable); foreach (var neighbour in walkableNeighbours) { if (aStar.Contains(neighbour)) continue; var distanceToGoal = closestNode.DistanceToGoal + neighbour.Distance(closestNode.Position); var distanceFromStart = distanceToGoal + neighbour.Distance(end); open.Add(new Node(closestNode, neighbour) { DistanceToGoal = distanceToGoal, DistanceFromStart = distanceFromStart }); aStar.Add(neighbour); } } return result; }
private Direction GetDirection(Position from, Position to) { if (from == null || to == null) return Direction.None; if (to.X > from.X) { if(to.Y > from.Y) return Direction.DownRight; if(to.Y < from.Y) return Direction.UpRight; return Direction.Right; } if (to.X < from.X) { if(to.Y > from.Y) return Direction.DownLeft; if(to.Y < from.Y) return Direction.UpLeft; return Direction.Left; } if (to.Y > from.Y) return Direction.Down; if (to.Y < from.Y) return Direction.Up; return Direction.None; }
private bool PlayerCanWalkHere(Character player, Map map, Position pos) { var friends = GetFriends(player); var enemyCharacters = GetEnemyCharacters(player); var monsters = GetMonsters(player); var boulders = player.VisibleItems.Where(item => GetInfoFor(item.Id).SubType == "boulder"); var blockingItems = friends.Concat(boulders); if (!PlayerHasPvPMode(player.Id)) { blockingItems = blockingItems.Concat(enemyCharacters); } if (!PlayerHasAttackMode(player.Id)) { blockingItems = blockingItems.Concat(monsters); } var blockedPositions = blockingItems.Select(item => item.Position); return !blockedPositions.Any(x => x.Equals(pos)) && (PlayerIsGaseous(player.Id) || map.IsWalkable(pos)); }
private bool GaseousPlayerCanWalkHere(Character player, Position pos) { var entities = player.VisibleEntities.Where(item => item.Id != player.Id); var boulders = player.VisibleItems.Where(item => GetInfoFor(item.Id).SubType == "boulder"); var blocked = entities.Concat(boulders).Select(item => new Position(item.XPos, item.YPos)); return !blocked.Any(x => x.Equals(pos)); }
private void SetTempGoalForPlayer(string playerId, Position goal) { _tmpGoals[playerId] = goal; }
public void SetGoalForPlayer(string playerId, Position goal) { if (goal == null || playerId == null) return; var player = GetPlayer(playerId); _goals[player.Id] = goal; AddMessage(String.Format("New goal for player {0} [{1}] set to ({2},{3})", player.Name, player.Id, goal.X, goal.Y)); }
private Position GetNextPosition(Position pos, Direction dir) { return pos.GetNeighbours().FirstOrDefault(next => GetDirection(pos, next) == dir); }
public int Distance(Position to) { return Math.Max(Math.Abs(X - to.X), Math.Abs(Y - to.Y)); }
private Position SelectPosition(Map map, Position start, string title) { var mapArea = CreateMapArea(map); var messageArea = CreateMessageArea(); mapArea.SetTitle(title); messageArea.SetTitle(title); var position = start; while (true) { var previousPosition = position; mapArea.Write("S", start.X, start.Y, ConsoleColor.Blue, ConsoleColor.DarkBlue); mapArea.Write("X", position.X, position.Y, ConsoleColor.Red, ConsoleColor.DarkRed); mapArea.CenterOffset(position.X, position.Y); messageArea.Clear(); messageArea.Write(string.Format("Select position and press [ENTER] ([Escape] to abort)"), 1, 1); messageArea.Write(string.Format("Current position: {0}, {1}", position.X, position.Y), 1, 2); _console2.DrawArea(mapArea, 0, 0); _console2.DrawArea(messageArea, 0, mapArea.Height); switch (Console.ReadKey(true).Key) { case ConsoleKey.UpArrow: position = new Position(position.X, position.Y - 1); break; case ConsoleKey.DownArrow: position = new Position(position.X, position.Y + 1); break; case ConsoleKey.LeftArrow: position = new Position(position.X - 1, position.Y); break; case ConsoleKey.RightArrow: position = new Position(position.X + 1, position.Y); break; case ConsoleKey.Enter: return position; case ConsoleKey.Escape: return null; } FillArea(map, mapArea, new[] { previousPosition }); } }
private void SetGoal(IEnumerable<string> args) { Position posArg1 = null; if (args != null && args.Any()) { posArg1 = TryParsePosition(args.FirstOrDefault()); } var player = _context.GetPlayer(_currentPlayerId); var map = _context.GetMap(player.CurrentMap); var mapArea = CreateMapArea(map); _console2.DrawArea(CreatePlayerArea(player), mapArea.Width, 0); var startPos = new Position(player.XPos, player.YPos); var endPos = posArg1 ?? SelectPosition(map, startPos, "Select goal for player"); if (endPos == null) return; _context.SetGoalForPlayer(player.Id, endPos); }
public uint GetPositionValue(Position position) { return _positions.ContainsKey(position) ? _positions[position] : uint.MaxValue; }
public void SetPositionValue(Position position, uint value) { UpdatePosition(position, value); }
private void UpdatePosition(Position pos, uint val) { if (pos == null || (_positions.ContainsKey(pos) && GetPositionValue(pos) == val)) return; _hasChanges = true; _positions[pos] = val; }