Example #1
0
        /// <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
        }
Example #4
0
        /// <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);
        }