public Grid(Dimensions2D dimensions, ICellGenerator <T> cellGenerator) { Dimensions = dimensions; CellGenerator = cellGenerator; _elementMatrix = new Cell <T> [dimensions.Width][]; for (var x = 0; x < dimensions.Width; ++x) { _elementMatrix[x] = new Cell <T> [dimensions.Height]; } Regenerate(); }
/// <summary> /// Helper for generation method /// </summary> /// <param name="dimensions"></param> /// <param name="faceDimension"></param> /// <param name="negativeFace"></param> /// <param name="positiveFace"></param> private void GeneratePlaneHelper(Dimensions2D dimensions, int faceDimension, FaceType negativeFace, FaceType positiveFace) { VisibleVoxels = new List2D <FaceType>(new Dimensions2D(dimensions.X, dimensions.Y)); // Loop over plane and find which voxels should be visible. // A voxel is visible if it is at the edge of a volume or if a face is not touching another voxel for (int u = 0; u < dimensions.X; u++) { for (int v = 0; v < dimensions.Y; v++) { FaceType renderFaces = FaceType.None; if (!GetVoxel(0, u, v).Empty) { if (FaceIndex == 0) { renderFaces |= negativeFace; } else if (GetVoxel(-1, u, v).Empty) { renderFaces |= negativeFace; } if (FaceIndex == faceDimension - 1) { renderFaces |= positiveFace; } else if (GetVoxel(1, u, v).Empty) { renderFaces |= positiveFace; } } VisibleVoxels[u, v] = renderFaces; } } }
/// <summary> /// Helper method for mesh generation /// </summary> /// <param name="dimensions"></param> private void GenerateMeshPartHelper(Dimensions2D dimensions) { // Create a 2D list that represents if a coordinate has been processed or not // Also create a queue that contains all possible voxels to process var processed = new List2D <bool>(dimensions); var processQueue = new Queue <Dimensions2D>(); for (int u = 0; u < dimensions.X; u++) { for (int v = 0; v < dimensions.Y; v++) { processed[u, v] = false; processQueue.Enqueue(new Dimensions2D(u, v)); } } // Process the entire queue while (processQueue.Count > 0) { // Find the first voxel that has not been processed and has a visible face var currentCoord = processQueue.Dequeue(); int startU = currentCoord.X; int startV = currentCoord.Y; if (processed[startU, startV] || (_voxelPlaneFaces[startU, startV] & _faceType) != _faceType) { processed[startU, startV] = true; continue; } // Find width // Stop when one of the following is found // - an empty voxel // - voxel that doesn't have a visible face // - voxel that doesn't match the starting voxel // - voxel that has already been processed int width = 0; for (int u = startU; u < dimensions.X; u++) { if (GetVoxel(u, startV).Empty || (_voxelPlaneFaces[u, startV] & _faceType) != _faceType || !GetVoxel(startU, startV).Equals(GetVoxel(u, startV)) || processed[u, startV]) { break; } processed[u, startV] = true; width++; } // Find height // Stop when one of the following is found // - an empty voxel // - voxel that doesn't have a visible face // - voxel that doesn't match the starting voxel // - voxel that has already been processed int height = 1; for (int v = startV + 1; v < dimensions.Y + 1; v++) { bool fullHeight = true; // The entire width will be looped over even if the height is not full.. // This is done so the previous full height can be marked as processed for (int u = startU; u < startU + width; u++) { if (v != dimensions.Y && (GetVoxel(u, v).Empty || (_voxelPlaneFaces[u, v] & _faceType) != _faceType || !GetVoxel(startU, startV).Equals(GetVoxel(u, v)) || processed[u, v])) { fullHeight = false; } processed[u, v - 1] = true; } if (!fullHeight) { break; } if (v != dimensions.Y) { height++; } } AddFace(startU, startV, width, height); } }
public void RenderGrid(Grid <GameOfLifeCellMetadata> grid) { _dimensions = grid.Dimensions; Console.SetCursorPosition(0, 0); Console.ResetColor(); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("╔═"); for (var i = 0; i < grid.Dimensions.Width; ++i) { Console.Write("═"); } Console.WriteLine("═╗"); Console.Write("║ "); for (var i = 0; i < grid.Dimensions.Width; ++i) { Console.Write(" "); } Console.WriteLine(" ║"); for (var y = 0; y < grid.Dimensions.Height; ++y) { var row = grid.GetRow(y); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("║ "); var x = 0; foreach (var cell in row) { RenderCell(cell); //, cell.Payload.IsAlive ? GameOfLifeRule.KeepAlive : GameOfLifeRule.NoMatch); //Console.ForegroundColor = cell.Payload.IsAlive ? ConsoleColor.Green : ConsoleColor.DarkGray; //Console.Write(cell.Payload.IsAlive ? "■" : " "); ++x; } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(" ║"); } Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("║ "); for (var i = 0; i < grid.Dimensions.Width; ++i) { Console.Write(" "); } Console.WriteLine(" ║"); Console.Write("╚═"); for (var i = 0; i < grid.Dimensions.Width; ++i) { Console.Write("═"); } Console.WriteLine("═╝"); // TODO: output counters/timers? that really should be done in game class though }
public ConsoleGridRenderer() { _dimensions = null; }