/// <summary> /// Counts the units on a board that satisfy a constraint /// </summary> /// <param name="board">The board to count units on</param> /// <param name="constraint">The constraint units need to satisfy</param> /// <returns>Dictionary with the amount of each unit type of units that satisfied the constraint on the board.</returns> public static Dictionary <UnitType, int> Count(Tile[,] board, LookupConstraint constraint) { Dictionary <UnitType, int> res = new Dictionary <UnitType, int>(); foreach (Tile t in board) { foreach (Unit u in t.UnitsOn) { if (constraint.Check(u)) { if (!res.ContainsKey(u.type)) { res[u.type] = 0; } res[u.type]++; } } } return(res); }
/// <summary> /// Get a path to the nearest location that has a unit on it that satisfies the given LookupConstraint. /// </summary> /// <param name="traveler">The unit that will travel the path</param> /// <param name="board">The board to search for a path in</param> /// <param name="xStart">The beggining x position of the path in tiles</param> /// <param name="yStart">The beggining y position of the path in tiles</param> /// <param name="lookup">The constraint to satisfy</param> /// <returns>A List of ALocations starting at (xStart,yStart) and ending at the nearest tile with a unit satisfying the constraint</returns> public static List <ALocation> PathToNearestUnit(UnitType traveler, Tile[,] board, int xStart, int yStart, LookupConstraint lookup) { ALocation start = new ALocation(xStart, yStart); //Current positions to check Stack <ALocation> current = new Stack <ALocation>(); //Next positions to check Stack <ALocation> next = new Stack <ALocation>(); //Start by checking the start current.Push(start); //Iteration i checks all the tiles in distance 1 from the beggining. Repeat until the maximum path length is reached. for (int i = 0; i < MAX_PATH_LENGTH; i++) { //Check every tile in the current list foreach (ALocation test in current) { //Check if there is a unit satisfying the constraint on this tile foreach (Unit u in test.Tile(board).UnitsOn) { if (lookup.Check(u)) { List <ALocation> res = new List <ALocation>(); ALocation curr = test; while (curr != null) { res.Add(curr); curr = curr.parent; } //Clear the flags foreach (Tile t in board) { t.flag = false; } //Return the path res.Reverse(); res.RemoveAt(0); return(res); } } //If the traveler cannot walk on that tile, stop checking it, it cannot be path of a path. if (!traveler.CanPlaceOn(board, test.x, test.y) && test != start) { continue; } //This tile is not final but may be in the shortest path. Check all tiles adjecent to it. foreach (ALocation l in GetAdjacentSquares(traveler, board, test.x, test.y)) { //Only check tiles that weren't checked yet. if (!board[l.x, l.y].flag) { l.parent = test; next.Push(l); //Mark this tile as checked. board[l.x, l.y].flag = true; } } } //Finished checking current tiles, switch on to the next batch. current = next; next = new Stack <ALocation>(); } //If the maximum tile length is reached and no path was found, stop looking, unflag all tiles and return null. foreach (Tile t in board) { t.flag = false; } return(null); }