/// <summary> /// Constructor for clonning /// </summary> /// <param name="cell"><see cref="Cell"/> for clonning</param> public Cell(Cell cell) { _x = cell.X; _y = cell.Y; _status = cell.Status; _cellOrganism = cell.Organism; }
/// <summary> /// Prepare to next step /// </summary> /// <param name="neighborCells">Nearest neighbor <see cref="Cell"/> of organism - 24</param> /// <returns><see cref="PrepareResult"/></returns> public PrepareResult Prepare(Collection<Cell> neighborCells) { var result = new PrepareResult(); if (!_migrant) { var array = new Cell[5, 5]; var migrationMaybe = new Collection<Cell>(); var dictionary = new Dictionary<Cell, int>(); CreateArray5X5(neighborCells, array); if (IsNeedMigration(array)) { CreateDictionaryOfCountNeighbor(array, dictionary); CreateAvaliableMigration(dictionary, migrationMaybe); if (migrationMaybe.Count > 0) { var rand = new Random(Environment.TickCount + migrationMaybe.Count()); var migration = migrationMaybe[rand.Next(0, migrationMaybe.Count)]; var from = new Coordinate {X = _x, Y = _y}; var to = new Coordinate {X = migration.X, Y = migration.Y}; _x = to.X; _y = to.Y; _migrant = true; result.SetMigration(from, to, this); } } } return result; }
/// <summary> /// Check is migration is need /// </summary> /// <param name="array">Array of neighboe cell</param> /// <returns><see cref="bool"/></returns> private bool IsNeedMigration(Cell[,] array) { var countNeighbor = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (!((i == j) && (i == 0)) && array[2 + i, 2 + j].Organism != null) { countNeighbor++; } } } for (int i = 1; i < 10; i++) { if (_genome.GetBit(i)) { if (countNeighbor == i - 1) { return false; } } } return true; }
/// <summary> /// Create collection of neighbor cell with count of they neighbor /// </summary> /// <param name="array">Array of all neighbor</param> /// <param name="dictionary">output data</param> private void CreateDictionaryOfCountNeighbor(Cell[,] array, Dictionary<Cell, int> dictionary) { for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { var temp = array[2 + i, 2 + j]; if (temp != null && temp.Organism == null) { var countOrganism = 0; for (int k = -1; k < 2; k++) { for (int l = -1; l < 2; l++) { var temp2 = array[2 + i + k, 2 + j + l]; if (temp2 != null && temp2.Organism != null) { countOrganism++; } } } if (temp.Organism != null) { countOrganism--; } dictionary.Add(temp, countOrganism); } } } }
/// <summary> /// Convert collection of neigbor to array 5 x 5 /// </summary> /// <param name="neighborCells">Collection of neighbors</param> /// <param name="array">Output data</param> private void CreateArray5X5(Collection<Cell> neighborCells, Cell[,] array) { var count = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (!(i == j && i == 2)) { array[i, j] = neighborCells[count]; count++; } } } }
/// <summary> /// Calculate next step of organism life /// </summary> /// <param name="neighborCells">Nearest neighbor <see cref="Cell"/> of organism - 8</param> /// <param name="countNeighbors">Count of nearest life organism</param> /// <param name="currentCell">Current cell</param> public void Update(IEnumerable<Cell> neighborCells, int countNeighbors, Cell currentCell) { _age++; _migrant = false; if (countNeighbors < 2 || countNeighbors > 3) { currentCell.SetCellStatus(OrganismStatus.Dead); } else { currentCell.SetCellStatus(OrganismStatus.Live); } }
/// <summary> /// Set begin status of game for testing /// </summary> private void InitGameLifeEngineTest() { for (int i = 0; i < _widthField; i++) { for (int j = 0; j < _heightField; j++) { _arrayCell[i, j] = new Cell(i, j); } } _arrayCell[2, 2].SetCellStatus(OrganismStatus.Create); _arrayCell[2, 3].SetCellStatus(OrganismStatus.Create); _arrayCell[2, 4].SetCellStatus(OrganismStatus.Create); _arrayCell[5, 5].SetCellStatus(OrganismStatus.Create); _arrayCell[5, 6].SetCellStatus(OrganismStatus.Create); _arrayCell[5, 7].SetCellStatus(OrganismStatus.Create); _arrayCell[4, 7].SetCellStatus(OrganismStatus.Create); _arrayCell[9, 7].SetCellStatus(OrganismStatus.Create); _arrayCell[9, 8].SetCellStatus(OrganismStatus.Create); _arrayCell[0, 7].SetCellStatus(OrganismStatus.Create); _arrayCell[0, 8].SetCellStatus(OrganismStatus.Create); }
/// <summary> /// Set begin status of game /// </summary> private void InitGameLifeEngine() { var rand = new Random(); for (int i = 0; i < _widthField; i++) { for (int j = 0; j < _heightField; j++) { _arrayCell[i, j] = new Cell(i, j); var t = rand.Next(2); if (t < 1) _arrayCell[i, j].SetCellStatus(OrganismStatus.Create); } } }
/// <summary> /// Create <see cref="IEnumerable{T}"/> of 8 or 24 neighbor cell for current cell /// </summary> /// <param name="cell">Current cell</param> /// <param name="neighborCount">Count of neighbor cell: 8, 24, 48</param> /// <returns><see cref="IEnumerable{T}"/> of <see cref="Cell"/></returns> private Collection<Cell> GetNeighborCell(Cell cell, int neighborCount) { int sizeOfNeighborArea; switch (neighborCount) { case 8: sizeOfNeighborArea = 3; break; case 24: sizeOfNeighborArea = 5; break; default: sizeOfNeighborArea = 3; break; } int different = (sizeOfNeighborArea - 1)/2; var list = new Collection<Cell>(); for (int i = 0; i < sizeOfNeighborArea; i++) { for (int j = 0; j < sizeOfNeighborArea; j++) { if (!(i == j && i == different)) { list.Add(GetCell(cell.X - different + i, cell.Y - different + j)); } } } return list; }
/// <summary> /// Claculate next step of game /// </summary> private void GameLifeEngineNextStep() { var tempArray = new Cell[_widthField,_heightField]; for (int i = 0; i < _widthField; i++) { for (int j = 0; j < _heightField; j++) { var neighbor8 = GetNeighborCell(_arrayCell[i, j], 8); var temp = _arrayCell[i, j].Clone(); _arrayCell[i, j].NextStep(neighbor8); tempArray[i, j] = _arrayCell[i, j]; _arrayCell[i, j] = temp; } } _arrayCell = tempArray; }