I have a class which takes a string representing a grid from Conway's game of life (along with its size, only accepting square grids) and returns the next grid in string format. Can it be improved?
Please note that this purely does the computation, and none of the displaying or editing. Also, it is internal so it will not have detection or prevention for errors.
The code:
public class GameOfLifeComputer
{
#region Fields
private int _up;
private int _down;
private int _left;
private int _right;
private int _currentIndex;
private int _cellCount;
private string _outputGrid;
#endregion
#region Methods
/// <summary>
/// Returns a string for the next grid state.
/// </summary>
/// <param name="inputGrid">The current grid state.</param>
/// <param name="gridSize">Side length of the grid in cells.</param>
/// <returns>The next grid state.</returns>
public string CalculateNextGrid(string inputGrid, int gridSize)
{
_outputGrid = "";
_currentIndex = 0;
foreach (char currentCell in inputGrid)
{
_cellCount = CountCells(_currentIndex, inputGrid, gridSize);
if (currentCell == '1')
{
if (_cellCount < 2 || _cellCount > 3)
{
_outputGrid += "0";
}
else
{
_outputGrid += "1";
}
}
else
{
if (_cellCount == 3)
{
_outputGrid += "1";
}
else
{
_outputGrid += "0";
}
}
}
return _outputGrid;
}
/// <summary>
/// Returns how many adjacent cells are alive.
/// </summary>
/// <param name="currentIndex">Position of the cell.</param>
/// <param name="inputGrid">State of the grid as a string.</param>
/// <param name="gridSize">Side length of the grid in cells.</param>
/// <returns></returns>
private int CountCells(int currentIndex, string inputGrid, int gridSize)
{
var count = 0;
// Define where the adjacent cells are in terms of relative index position.
_up = -gridSize;
_down = gridSize;
// Up and down must cycle to the top or bottom of the grid if the cell is on the edge.
if (currentIndex < gridSize)
{
_up = inputGrid.Length - gridSize;
}
else if (currentIndex > inputGrid.Length - gridSize)
{
_down = gridSize - inputGrid.Length;
}
// Left and right must cycle to the opposite side on the same row if the cell is on the edge.
if (currentIndex % gridSize == 0)
{
_left = gridSize - 1;
_right = 1;
}
else
{
_left = -1;
_right = 1 - gridSize;
}
// Count how many adjacent cells are alive.
if (inputGrid[currentIndex + _up + _right] == '1') { count += 1; }
if (inputGrid[currentIndex + _up ] == '1') { count += 1; }
if (inputGrid[currentIndex + _up + _left ] == '1') { count += 1; }
if (inputGrid[currentIndex + _left ] == '1') { count += 1; }
if (inputGrid[currentIndex + _down + _left ] == '1') { count += 1; }
if (inputGrid[currentIndex + _down ] == '1') { count += 1; }
if (inputGrid[currentIndex + _down + _right] == '1') { count += 1; }
if (inputGrid[currentIndex + _right ] == '1') { count += 1; }
return count;
}
#endregion
}