using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace GameOfLife3D.GameModel { internal class Map { private Cell[,,] _Cells; private int _SizeX, _SizeY, _SizeZ; public Cell[,,] Cells => _Cells; public int AliveCell => GetAliveCells(); public Map SwapMap; public Map(int XSize, int YSize, int ZSize) { _Cells = new Cell[XSize, YSize, ZSize]; StoreDimensions(XSize, YSize, ZSize); InitializeCells(); } private void StoreDimensions(int xSize, int ySize, int zSize) { _SizeX = xSize; _SizeY = ySize; _SizeZ = zSize; } public Map(int Size) { _Cells = new Cell[Size, Size, Size]; StoreDimensions(Size, Size, Size); InitializeCells(); } public void Update() { if (SwapMap == null) { SwapMap = new(_SizeX, _SizeY, _SizeZ); } foreach (var cell in _Cells) { SwapMap.GetCell(cell.X, cell.Y, cell.Z).isAlive = GetNewState(GetAliveCount(cell), cell.isAlive); } this.CloneFrom(SwapMap); } private static bool GetNewState(int value, bool CurrentCellState) { if (value < Balancing.MIN_ALIVE) return false; if (value >= Balancing.MIN_ALIVE && value < Balancing.CREATE_MIN) return CurrentCellState; if (value >= Balancing.CREATE_MIN && value < Balancing.CREATE_MAX) return true; if (value > Balancing.CREATE_MAX && value < Balancing.MAX_ALIVE) return CurrentCellState; return false; } private int GetAliveCount(Cell cell) { int AliveCount = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { AliveCount += GetCell(cell.X + i, cell.Y + j, cell.Z + k).isAlive ? 1 : 0; if (AliveCount > Balancing.MAX_ALIVE) { return AliveCount; } } } } return AliveCount; } private void CloneFrom(Map source) { this._Cells = source.Cells; } private void InitializeCells() { for (int i = 0; i < _Cells.GetLength(0); i++) { for (int j = 0; j < _Cells.GetLength(1); j++) { for (int k = 0; k < _Cells.GetLength(2); k++) { _Cells[i, j, k].X = i; _Cells[i, j, k].Y = j; _Cells[i, j, k].Z = k; } } } } public ref Cell GetCell(int x, int y, int z) { //Clamp Values to Bound x = Math.Clamp(x, 0, _SizeX-1); y = Math.Clamp(y, 0, _SizeY-1); z = Math.Clamp(z, 0, _SizeZ-1); return ref _Cells[x, y, z]; } private int GetAliveCells() { int aliveCount = 0; foreach (Cell cell in _Cells) { aliveCount += cell.isAlive ? 1 : 0; } return aliveCount; } public void SetRandom(int mod = 2) { for (int i = 0; i < _Cells.GetLength(0); i++) { for (int j = 0; j < _Cells.GetLength(1); j++) { for (int k = 0; k < _Cells.GetLength(2); k++) { _Cells[i, j, k].isAlive = Random.Shared.Next() % mod == 0; //_Cells[i, j, k].isAlive = true; } } } } } }