/// <summary> /// Finds the spouse for single human cell. /// </summary> /// <param name="i">The i.</param> /// <param name="j">The j.</param> /// <param name="board">The board.</param> /// <returns></returns> private Cell FindSpouseForSingleHumanCell(int i, int j, Board board, Board nextGenerationBoard) { Human human = board[i, j].Humans[0]; List <Cell> neighbours = GetCellNeighbours(i, j, board); //Filter only optional spouses neighbours = neighbours.Where(n => n.State != CellState.Empty && n.GetOppositeSexHuman(human.Sex) != null).ToList(); //Choose the best spouse var spouses = from neighbour in neighbours let charDiff = Math.Abs(neighbour.GetOppositeSexHuman(human.Sex).Character - human.Character) where (!m_enableMemory || charDiff < human.BestCharacterDiffMemory) && (m_maxCharacterDiffForCoupling == null || (charDiff <= m_maxCharacterDiffForCoupling && charDiff < neighbour.CharacterDiff)) orderby charDiff ascending select neighbour; //Filter couple spouse where the couple cell was already calculated in the next generation board, to avoid override spouses = from spouse in spouses let spouseIndexes = board.FindCellIndexes(spouse) where spouse.State != CellState.Couple || nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].State == CellState.Empty select spouse; return(spouses.FirstOrDefault()); //The best spouse }
/// <summary> /// Calculates the state of the next board. /// </summary> /// <param name="board">The board.</param> /// <returns></returns> public Board CalculateNextBoardState(Board board) { var nextGenerationBoard = new Board(board.Size); for (int i = 0; i < board.Size; i++) { for (int j = 0; j < board.Size; j++) { Cell currGenerationCell = board[i, j]; Cell nextGenerationCell = nextGenerationBoard[i, j]; if (nextGenerationCell.State != CellState.Empty /*Already calculated*/ || currGenerationCell.State == CellState.Empty) continue; if (currGenerationCell.State != CellState.Couple) //A single cell, try to find spouses { Cell spouseCell = FindSpouseForSingleHumanCell(i, j, board, nextGenerationBoard); if (spouseCell != null) // Found a spouse, create a couple { Human spouse = spouseCell.GetOppositeSexHuman(currGenerationCell.Humans[0].Sex); Human human = currGenerationCell.Humans[0].Clone(); if (m_enableMemory) //If memory is enable, save spouses memory { human.BestCharacterDiffMemory = Math.Abs(spouse.Character - human.Character); } nextGenerationCell.Humans.Add(human); nextGenerationCell.Humans.Add(spouse.Clone()); Tuple<int, int> spouseIndexes = board.FindCellIndexes(spouseCell); if (spouseCell.State == CellState.Couple) //Create the single human cell in the next state board { spouseCell.Humans.Remove(spouse); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouseCell.Humans[0].Clone()); } board[spouseIndexes.Item1, spouseIndexes.Item2] = new Cell(); board[i, j] = new Cell(); } else //Didn't find a spouse, try to move the human { MoveCell(board, nextGenerationBoard, i, j); } } else //The cell has a couple { Cell spouse = FindBetterSpouseForCoupleCell(i, j, board); if (spouse != null) //Found a better spouse, generate the new couple and new single { Tuple<int, int> spouseIndexes = board.FindCellIndexes(spouse); if (spouse.State == CellState.Man) { //The new couple nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouse.Male.Clone()); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(board[i, j].Female.Clone()); //The new single nextGenerationBoard[i, j].Humans.Add(board[i, j].Male.Clone()); } else //Woman { //The new couple nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouse.Female.Clone()); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(board[i, j].Male.Clone()); //The new single nextGenerationBoard[i, j].Humans.Add(board[i, j].Female.Clone()); } //Clear the couple and the new spouse cells from the original board board[i, j] = new Cell(); board[spouseIndexes.Item1, spouseIndexes.Item2] = new Cell(); } else //Didn't find a better spouse, try to move the couple { MoveCell(board, nextGenerationBoard, i, j); } } } } return nextGenerationBoard; }
/// <summary> /// Finds the spouse for single human cell. /// </summary> /// <param name="i">The i.</param> /// <param name="j">The j.</param> /// <param name="board">The board.</param> /// <returns></returns> private Cell FindSpouseForSingleHumanCell(int i, int j, Board board, Board nextGenerationBoard) { Human human = board[i, j].Humans[0]; List<Cell> neighbours = GetCellNeighbours(i, j, board); //Filter only optional spouses neighbours = neighbours.Where(n => n.State != CellState.Empty && n.GetOppositeSexHuman(human.Sex) != null).ToList(); //Choose the best spouse var spouses = from neighbour in neighbours let charDiff = Math.Abs(neighbour.GetOppositeSexHuman(human.Sex).Character - human.Character) where (!m_enableMemory || charDiff < human.BestCharacterDiffMemory) && (m_maxCharacterDiffForCoupling == null || (charDiff <= m_maxCharacterDiffForCoupling && charDiff < neighbour.CharacterDiff)) orderby charDiff ascending select neighbour; //Filter couple spouse where the couple cell was already calculated in the next generation board, to avoid override spouses = from spouse in spouses let spouseIndexes = board.FindCellIndexes(spouse) where spouse.State != CellState.Couple || nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].State == CellState.Empty select spouse; return spouses.FirstOrDefault(); //The best spouse }
/// <summary> /// Calculates the state of the next board. /// </summary> /// <param name="board">The board.</param> /// <returns></returns> public Board CalculateNextBoardState(Board board) { var nextGenerationBoard = new Board(board.Size); for (int i = 0; i < board.Size; i++) { for (int j = 0; j < board.Size; j++) { Cell currGenerationCell = board[i, j]; Cell nextGenerationCell = nextGenerationBoard[i, j]; if (nextGenerationCell.State != CellState.Empty /*Already calculated*/ || currGenerationCell.State == CellState.Empty) { continue; } if (currGenerationCell.State != CellState.Couple) //A single cell, try to find spouses { Cell spouseCell = FindSpouseForSingleHumanCell(i, j, board, nextGenerationBoard); if (spouseCell != null) // Found a spouse, create a couple { Human spouse = spouseCell.GetOppositeSexHuman(currGenerationCell.Humans[0].Sex); Human human = currGenerationCell.Humans[0].Clone(); if (m_enableMemory) //If memory is enable, save spouses memory { human.BestCharacterDiffMemory = Math.Abs(spouse.Character - human.Character); } nextGenerationCell.Humans.Add(human); nextGenerationCell.Humans.Add(spouse.Clone()); Tuple <int, int> spouseIndexes = board.FindCellIndexes(spouseCell); if (spouseCell.State == CellState.Couple) //Create the single human cell in the next state board { spouseCell.Humans.Remove(spouse); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouseCell.Humans[0].Clone()); } board[spouseIndexes.Item1, spouseIndexes.Item2] = new Cell(); board[i, j] = new Cell(); } else //Didn't find a spouse, try to move the human { MoveCell(board, nextGenerationBoard, i, j); } } else //The cell has a couple { Cell spouse = FindBetterSpouseForCoupleCell(i, j, board); if (spouse != null) //Found a better spouse, generate the new couple and new single { Tuple <int, int> spouseIndexes = board.FindCellIndexes(spouse); if (spouse.State == CellState.Man) { //The new couple nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouse.Male.Clone()); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(board[i, j].Female.Clone()); //The new single nextGenerationBoard[i, j].Humans.Add(board[i, j].Male.Clone()); } else //Woman { //The new couple nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(spouse.Female.Clone()); nextGenerationBoard[spouseIndexes.Item1, spouseIndexes.Item2].Humans.Add(board[i, j].Male.Clone()); //The new single nextGenerationBoard[i, j].Humans.Add(board[i, j].Female.Clone()); } //Clear the couple and the new spouse cells from the original board board[i, j] = new Cell(); board[spouseIndexes.Item1, spouseIndexes.Item2] = new Cell(); } else //Didn't find a better spouse, try to move the couple { MoveCell(board, nextGenerationBoard, i, j); } } } } return(nextGenerationBoard); }