private void PopulateDoubleAndTripleFaceCubies(CubeFace face, ref HashSet <Cubie> cubies)
        {
            PositionMover faceMover = new PositionMover(face.GetSquares(0).First());
            Func <RelativePosition, Position, Cubie> cubieCreator = _cubieCreators[face.FaceDirection];

            do
            {
                faceMover.Move(1);
                cubies.Add(cubieCreator(faceMover.CurrentRelativePosition, faceMover.CurrentPosition));
            }while (faceMover.CurrentRelativePosition != RelativePosition.OnPointOne);
        }
        public IEnumerable <Cubie> CreateCubies(int cubeSize)
        {
            CubeFace frontFace = new CubeFace(RubiksDirection.Front, cubeSize);
            CubeFace backFace  = new CubeFace(RubiksDirection.Back, cubeSize);
            CubeFace rightFace = new CubeFace(RubiksDirection.Right, cubeSize);
            CubeFace leftFace  = new CubeFace(RubiksDirection.Left, cubeSize);
            CubeFace upFace    = new CubeFace(RubiksDirection.Up, cubeSize);
            CubeFace downFace  = new CubeFace(RubiksDirection.Down, cubeSize);

            HashSet <Cubie> cubies = new HashSet <Cubie>();

            PopulateSingleFaceCubies(frontFace, ref cubies);
            PopulateDoubleAndTripleFaceCubies(frontFace, ref cubies);

            PopulateSingleFaceCubies(backFace, ref cubies);
            PopulateDoubleAndTripleFaceCubies(backFace, ref cubies);

            PopulateSingleFaceCubies(rightFace, ref cubies);
            PopulateDoubleAndTripleFaceCubies(rightFace, ref cubies);

            PopulateSingleFaceCubies(leftFace, ref cubies);
            PopulateDoubleAndTripleFaceCubies(leftFace, ref cubies);

            PopulateSingleFaceCubies(upFace, ref cubies);
            //PopulateDoubleAndTripleFaceCubies(upFace, ref cubies); //Unnecessary computation

            PopulateSingleFaceCubies(downFace, ref cubies);
            //PopulateDoubleAndTripleFaceCubies(downFace, ref cubies); //Unnecessary computation

            HashSet <Position>     allPositions      = new HashSet <Position>(frontFace.GetPositionsOfLayersBeneathFace(cubeSize - 1));
            IEnumerable <Position> existingPositions = cubies.Select(cube => cube.Position);

            allPositions.ExceptWith(existingPositions);

            foreach (Position position in allPositions)
            {
                cubies.Add
                (
                    new Cubie
                    (
                        frontSide: null,
                        backSide: null,
                        rightSide: null,
                        leftSide: null,
                        upSide: null,
                        downSide: null,
                        postion: position
                    )
                );
            }

            return(cubies);
        }
        private void PopulateSingleFaceCubies(CubeFace face, ref HashSet <Cubie> cubies)
        {
            Square square = face.GetSquares(0).First();

            HashSet <Position> allFacePositions = new HashSet <Position>(face.CubiePositions);

            allFacePositions.ExceptWith(square.PositionsInSquare);

            foreach (Position position in allFacePositions)
            {
                Cubie singleFacedCubie = null;
                switch (face.FaceDirection)
                {
                case RubiksDirection.Front:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: _frontColor,
                        backSide: null,
                        rightSide: null,
                        leftSide: null,
                        upSide: null,
                        downSide: null,
                        postion: position
                                       );
                    break;

                case RubiksDirection.Back:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: null,
                        backSide: _backColor,
                        rightSide: null,
                        leftSide: null,
                        upSide: null,
                        downSide: null,
                        postion: position
                                       );
                    break;

                case RubiksDirection.Up:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: null,
                        backSide: null,
                        rightSide: null,
                        leftSide: null,
                        upSide: _upColor,
                        downSide: null,
                        postion: position
                                       );
                    break;

                case RubiksDirection.Down:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: null,
                        backSide: null,
                        rightSide: null,
                        leftSide: null,
                        upSide: null,
                        downSide: _downColor,
                        postion: position
                                       );
                    break;

                case RubiksDirection.Left:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: null,
                        backSide: null,
                        rightSide: null,
                        leftSide: _leftColor,
                        upSide: null,
                        downSide: null,
                        postion: position
                                       );
                    break;

                case RubiksDirection.Right:
                    singleFacedCubie = new Cubie
                                       (
                        frontSide: null,
                        backSide: null,
                        rightSide: _rightColor,
                        leftSide: null,
                        upSide: null,
                        downSide: null,
                        postion: position
                                       );
                    break;

                default:
                    break;
                }

                cubies.Add(singleFacedCubie);
            }
        }