145 lines
4.0 KiB
C#
145 lines
4.0 KiB
C#
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;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|