/// <summary> /// Checks for Plants to eat (which are in direct contact with the Animal, so /// diagonal Plants are not included). Eats a Plant if a valid one is found (only one Plant can be eaten). /// </summary> /// <remarks> /// Author: Rudy Ariaz /// </remarks> /// <param name="grid">The Grid to use for finding Plants.</param> /// <param name="gameEnv">The Environment with which the Unit interacts.</param> private void CheckPlantsToEat(Unit[,] grid, Environment gameEnv) { // Get the row and column of the Animal int row = Location.r, col = Location.c; // Iterate through each of the directions (up, down, left, right) foreach (var dir in GridHelper.directions) { // Compute the new row and column of the grid block being checked int newRow = row + dir.Item1; int newCol = col + dir.Item2; // If the block is not within the grid, try a different direction if (!grid.InGridBounds(newRow, newCol)) { continue; } // Otherwise, get the neighbor in the block Unit neighbor = grid[newRow, newCol]; // Check if the neighbor is a non-null Plant if (neighbor != null && neighbor is Plant) { // Eat the Plant EatPlant(grid, gameEnv, (Plant)neighbor); // Stop looking for Plants break; } } }
/// <summary> /// Simulates infection of a neighboring LivingUnit. Only LivingUnits to the left, right, /// top, and bottom of the Virus. Only infects a single neighbor. /// </summary> /// <param name="grid">The grid of Units.</param> private void Infect(Unit[,] grid) { // Iterate through each of the directions (left, right, top, bottom) foreach (var dir in GridHelper.directions) { // Calculate the row and column of the neighbor int newRow = Location.r + dir.Item1; int newCol = Location.c + dir.Item2; // Check if the neighbor is within the grid if (!grid.InGridBounds(newRow, newCol)) { // Try a different direction continue; } // Otherwise, get the neighbor Unit neighbor = grid[newRow, newCol]; // Check if there is a non-null LivingUnit in the block // Infects a unit even if it is already infected if (neighbor != null && neighbor is LivingUnit) { // Infect the neighbor (neighbor as LivingUnit).BeInfected(); // Do not infect any other neighbors break; } } }
/// <summary> /// Returns the number of non-null Unit neighbors, either all Virus or all LivingUnit, /// of the block at (row, col). /// </summary> /// <remarks> /// Reusable method for both Virus counting and LivingUnit counting. /// </remarks> /// <param name="grid">Grid to use for counting neighbors.</param> /// <param name="row">Row (within the grid) of the block whose neighbors are counted.</param> /// <param name="col">Column (within the grid) of the block whose neighbors are counted.</param> /// <param name="countViral">Whether to count Viruses as neighbors (in which case LivingUnit /// neighbors are not counted), or not count them as neighbors (in which case only LivingUnit /// neighbors are counted).</param> /// <returns>The number of non-null Virus neighbors if "countViral" is true, or the number /// of non-null LivingUnit neighbors if "countViral" is false. Neighbors are in the Moore neighborhood.</returns> private static int NumberOfNeighbors(Unit[,] grid, int row, int col, bool countViral) { // Will store the number of neighbors int neighbors = 0; // Iterate through the Moore neighborhood // Iterate row by row, starting from the row above the block and ending at the row // below the block. for (int i = row - 1; i <= row + 1; i++) { // Iterate column by column, starting from the column to the left of the block // and ending at the column to the right of the block. for (int j = col - 1; j <= col + 1; j++) { // Check if the current block is not the original block at (row, col), // that it is inside the grid bounds, and that the Unit stored in the block is not null if ((i != row || j != col) && grid.InGridBounds(i, j) && grid[i, j] != null) { // Count the current neighbor only if Viruses should be counted and the neighbor is // not a LivingUnit, or if Viruses should not be counted and the neighbour is a LivingUnit neighbors += (!countViral == grid[i, j] is LivingUnit ? 1 : 0); } } } // Return the number of neighbors corresponding to the criterion of Virus counting or not counting return(neighbors); }
/// <summary> /// Gets the number of neighbors of the same type as this Multicellular /// in a 5x5 square centered on the organism. /// </summary> /// <param name="grid"></param> /// <returns> an integer representing the number of neighbours of the same species that this unit has </returns> protected int NumberOfSameSpeciesNeighbors(Unit[,] grid) { // Create a counter to store the number of same species neighbours int numNeighbors = 0; // Compute the boundaries of the area to check for same species neighbours int rowLowerBound = Math.Max(0, Location.r - EXTENDED_NEIGHBORHOOD_SIZE / 2), colLowerBound = Math.Max(0, Location.c - EXTENDED_NEIGHBORHOOD_SIZE / 2); int rowUpperBound = Math.Min(grid.GetLength(GridHelper.ROW), Location.r + EXTENDED_NEIGHBORHOOD_SIZE / 2 + 1), colUpperBound = Math.Min(grid.GetLength(GridHelper.COLUMN), Location.c + EXTENDED_NEIGHBORHOOD_SIZE / 2 + 1); // Loop through all rows in the area to be checked to check each grid cell for (int i = rowLowerBound; i < rowUpperBound; i++) { // Loop through all columns in the area to be checked to check each grid cell for (int j = colLowerBound; j < colUpperBound; j++) { // Check if the current grid cell is in the grid and holds a unit if (grid.InGridBounds(i, j) && grid[i, j] != null) { // Increase the number of same species neighbour in the community // only if the type of the unit in the current grid cell matches the type of the current unit numNeighbors += grid[i, j].GetType() == this.GetType() ? 1 : 0; } } } // Return the number of same species neighbours in the area surrounding this unit return(numNeighbors); }
/// <summary> /// Gets a list of all the non-null Unit neighbors of a block in the grid. /// </summary> /// <param name="grid">Grid to use for finding neighbors.</param> /// <param name="row">Row (within the grid) of the block whose neighbors are found.</param> /// <param name="col">Column (within the grid) of the block whose neighbors are found.</param> /// <returns>A List of non-null Units which are neighbors of the block at (row, col).</returns> private static List <Unit> GetAllNeighbors(Unit[,] grid, int row, int col) { // List that will store all the neighbors List <Unit> neighbors = new List <Unit>(); // Iterate through the Moore neighborhood // Iterate row by row, starting from the row above the block and ending at the row // below the block. for (int i = row - 1; i <= row + 1; i++) { // Iterate column by column, starting from the column to the left of the block // and ending at the column to the right of the block. for (int j = col - 1; j <= col + 1; j++) { // Check if the current block is not the original block at (row, col), // that it is inside the grid bounds, and that the Unit stored in the block is not null if ((i != row || j != col) && grid.InGridBounds(i, j) && grid[i, j] != null) { // Store this neighbor neighbors.Add(grid[i, j]); } } } // Return all the neighbors return(neighbors); }