/// <summary> /// Get the co-ordinates with respectt to grid and return the Cell type enum /// </summary> /// <param name="grid"></param> /// <param name="coOrdinates"></param> /// <returns>returns CellTypeEnum</returns> public static CellTypeEnum GetCellType(Grid grid, CoOrdinates coOrdinates) { if ((coOrdinates.X < -1 || coOrdinates.X > grid.RowCount) || (coOrdinates.Y < -1 || coOrdinates.Y > grid.ColumnCount)) { throw new ArgumentOutOfRangeException("Invalid Index value: must be greater than or equal to minus one and less than or equal to Row count"); } CellTypeEnum enumCellType = CellTypeEnum.None; if (coOrdinates.X == 0 && coOrdinates.Y == 0) enumCellType = CellTypeEnum.TopLeftCorner; else if (coOrdinates.X == 0 && coOrdinates.Y == grid.ColumnCount - 1) enumCellType = CellTypeEnum.TopRightCorner; else if (coOrdinates.X == grid.RowCount - 1 && coOrdinates.Y == 0) enumCellType = CellTypeEnum.BottomLeftCorner; else if (coOrdinates.X == grid.RowCount - 1 && coOrdinates.Y == grid.ColumnCount - 1) enumCellType = CellTypeEnum.BottomRightCorner; else if (coOrdinates.X == 0 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) enumCellType = CellTypeEnum.TopSide; else if (coOrdinates.X == grid.RowCount - 1 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) enumCellType = CellTypeEnum.BottomSide; else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == 0) enumCellType = CellTypeEnum.LeftSide; else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == grid.ColumnCount - 1) enumCellType = CellTypeEnum.RightSide; else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) enumCellType = CellTypeEnum.Center; else if (coOrdinates.X == -1 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) enumCellType = CellTypeEnum.OuterTopSide; else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == grid.ColumnCount) enumCellType = CellTypeEnum.OuterRightSide; else if (coOrdinates.X == grid.RowCount && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) enumCellType = CellTypeEnum.OuterBottomSide; else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == -1) enumCellType = CellTypeEnum.OuterLeftSide; return enumCellType; }
/// <summary> /// Change Cell state of specified co-ordinate using Ruls /// </summary> /// <param name="inputGrid"></param> /// <param name="outputGrid"></param> /// <param name="coOrdinates"></param> public static void ChangeCellsState(Grid inputGrid, Grid outputGrid, CoOrdinates coOrdinates) { int liveNeighbourCount = CountAliveNeighbours(inputGrid, coOrdinates); lock (outputGrid) { if (IsAliveInNextState(inputGrid[coOrdinates.X, coOrdinates.Y], liveNeighbourCount)) { //set output grid's cell to live only if it is in alive status in next generation outputGrid[coOrdinates.X, coOrdinates.Y].IsAlive = true; } } }
/// <summary> /// Check if the adjacent cell is alive or not /// </summary> /// <param name="grid"></param> /// <param name="baseCoOrdinates"></param> /// <param name="offSetCoOrdinates"></param> /// <returns>returns 1 if live otherwise 0</returns> private static int IsAliveNeighbour(Grid grid, CoOrdinates baseCoOrdinates, CoOrdinates offSetCoOrdinates) { int live = 0; // set default as 0 int x = baseCoOrdinates.X + offSetCoOrdinates.X; // get x axis of neighbour int y = baseCoOrdinates.Y + offSetCoOrdinates.Y; // get y axis of neighbour // check the computed bound is within range of grid, if it is not within bounds live is 0 as default if ((x >= 0 && x < grid.RowCount) && y >= 0 && y < grid.ColumnCount) { // if reachable neighbour cell is alive then set live to 1 otherwise 0 live = grid[x, y].IsAlive ? 1 : 0; } return(live); }
/// <summary> /// Count live adjacent cells for specified cell co-ordinates /// </summary> /// <param name="grid"></param> /// <param name="coOrdinates"></param> /// <returns>returns number of live neighbours</returns> private static int CountAliveNeighbours(Grid grid, CoOrdinates coOrdinates) { int liveNeighbours = 0; // Get the Cell type of current cell CellTypeEnum enumInnerCell = ReachableCell.GetCellType(grid, coOrdinates); List <CoOrdinates> reachableCells = new List <CoOrdinates>(); // populate reachable cells from current cell for easier traversing ReachableCell.ReachableCells.TryGetValue(enumInnerCell, out reachableCells); if (reachableCells.Count == 0) { throw new ArgumentNullException("Cannot find reachable co-ordinates"); } foreach (CoOrdinates coOrds in reachableCells) { liveNeighbours += IsAliveNeighbour(grid, coOrdinates, coOrds); } return(liveNeighbours); }
/// <summary> /// Get the co-ordinates with respectt to grid and return the Cell type enum /// </summary> /// <param name="grid"></param> /// <param name="coOrdinates"></param> /// <returns>returns CellTypeEnum</returns> public static CellTypeEnum GetCellType(Grid grid, CoOrdinates coOrdinates) { if ((coOrdinates.X < -1 || coOrdinates.X > grid.RowCount) || (coOrdinates.Y < -1 || coOrdinates.Y > grid.ColumnCount)) { throw new ArgumentOutOfRangeException("Invalid Index value: must be greater than or equal to minus one and less than or equal to Row count"); } CellTypeEnum enumCellType = CellTypeEnum.None; if (coOrdinates.X == 0 && coOrdinates.Y == 0) { enumCellType = CellTypeEnum.TopLeftCorner; } else if (coOrdinates.X == 0 && coOrdinates.Y == grid.ColumnCount - 1) { enumCellType = CellTypeEnum.TopRightCorner; } else if (coOrdinates.X == grid.RowCount - 1 && coOrdinates.Y == 0) { enumCellType = CellTypeEnum.BottomLeftCorner; } else if (coOrdinates.X == grid.RowCount - 1 && coOrdinates.Y == grid.ColumnCount - 1) { enumCellType = CellTypeEnum.BottomRightCorner; } else if (coOrdinates.X == 0 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) { enumCellType = CellTypeEnum.TopSide; } else if (coOrdinates.X == grid.RowCount - 1 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) { enumCellType = CellTypeEnum.BottomSide; } else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == 0) { enumCellType = CellTypeEnum.LeftSide; } else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == grid.ColumnCount - 1) { enumCellType = CellTypeEnum.RightSide; } else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) { enumCellType = CellTypeEnum.Center; } else if (coOrdinates.X == -1 && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) { enumCellType = CellTypeEnum.OuterTopSide; } else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == grid.ColumnCount) { enumCellType = CellTypeEnum.OuterRightSide; } else if (coOrdinates.X == grid.RowCount && (coOrdinates.Y > 0 && coOrdinates.Y < grid.ColumnCount - 1)) { enumCellType = CellTypeEnum.OuterBottomSide; } else if ((coOrdinates.X > 0 && coOrdinates.X < grid.RowCount - 1) && coOrdinates.Y == -1) { enumCellType = CellTypeEnum.OuterLeftSide; } return(enumCellType); }
/// <summary> /// Check if the adjacent cell is alive or not /// </summary> /// <param name="grid"></param> /// <param name="baseCoOrdinates"></param> /// <param name="offSetCoOrdinates"></param> /// <returns>returns 1 if live otherwise 0</returns> private static int IsAliveNeighbour(Grid grid, CoOrdinates baseCoOrdinates, CoOrdinates offSetCoOrdinates) { int live = 0; // set default as 0 int x = baseCoOrdinates.X + offSetCoOrdinates.X; // get x axis of neighbour int y = baseCoOrdinates.Y + offSetCoOrdinates.Y; // get y axis of neighbour // check the computed bound is within range of grid, if it is not within bounds live is 0 as default if ((x >= 0 && x < grid.RowCount) && y >= 0 && y < grid.ColumnCount) { // if reachable neighbour cell is alive then set live to 1 otherwise 0 live = grid[x, y].IsAlive ? 1 : 0; } return live; }
/// <summary> /// Count live adjacent cells for specified cell co-ordinates /// </summary> /// <param name="grid"></param> /// <param name="coOrdinates"></param> /// <returns>returns number of live neighbours</returns> private static int CountAliveNeighbours(Grid grid, CoOrdinates coOrdinates) { int liveNeighbours = 0; // Get the Cell type of current cell CellTypeEnum enumInnerCell = ReachableCell.GetCellType(grid, coOrdinates); List<CoOrdinates> reachableCells = new List<CoOrdinates>(); // populate reachable cells from current cell for easier traversing ReachableCell.ReachableCells.TryGetValue(enumInnerCell, out reachableCells); if (reachableCells.Count == 0) throw new ArgumentNullException("Cannot find reachable co-ordinates"); foreach (CoOrdinates coOrds in reachableCells) { liveNeighbours += IsAliveNeighbour(grid, coOrdinates, coOrds); } return liveNeighbours; }