Exemplo n.º 1
0
        public override bool ApplyReverseMoveForLoop(
            IGameBlockDestination destinationBlock,
            MovementDirection directionInReverse,
            int numberOfBlocksToMove,
            out BlockMovement move,
            IGameBlock previousBlock,
            IGameBlockDestination previousDestination,
            Queue<IGameBlock> blockHistory)
        {
            move = null;

            // Starting with a non-filled block isn't valid
            if (destinationBlock != null && this.numberOfMovesApplied == 0)
            {
                return false;
            }

            // If this is the destination
            bool thisIsFinalMove = destinationBlock == null;
            int availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary<IGameBlock, IGameBlock>());

            // See if there are enough blocks to do this move
            if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove)
            {
                return false;
            }

            // Use this block as the destination block if destinationBlock is null
            IGameBlockDestination destination = destinationBlock ?? this;

            blockHistory.Enqueue(this);

            bool moveApplied;
            switch (directionInReverse)
            {
                default:
                case MovementDirection.Up:
                    if (this.Top == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Top.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Down:
                    if (this.Bottom == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Bottom.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Left:
                    if (this.Left == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Left.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Right:
                    if (this.Right == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Right.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;
            }

            if (moveApplied && !this.IsFullyAvailable && move != null)
            {
                this.SetAvailability(true);
                move.InsertDestinationBlock(this);
                move.SourceBlock.AvailableMoves++;
            }

            return moveApplied;
        }
Exemplo n.º 2
0
        public override bool ApplyReverseMoveForLoop(
            IGameBlockDestination destinationBlock,
            MovementDirection directionInReverse,
            int numberOfBlocksToMove,
            out BlockMovement move,
            IGameBlock previousBlock,
            IGameBlockDestination previousDestination,
            Queue <IGameBlock> blockHistory)
        {
            move = null;

            // There should already be a destination block
            if (destinationBlock == null)
            {
                return(false);
            }

            blockHistory.Enqueue(this);

            bool moveApplied;

            switch (directionInReverse)
            {
            default:
            case MovementDirection.Down:
                if (this.Bottom == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Bottom.ApplyReverseMoveForLoop(
                        destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Up:
                if (this.Top == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Top.ApplyReverseMoveForLoop(
                        destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Right:
                if (this.Right == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Right.ApplyReverseMoveForLoop(
                        destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Left:
                if (this.Left == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Left.ApplyReverseMoveForLoop(
                        destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;
            }

            if (moveApplied && !this.isAvailable && move != null)
            {
                this.IsAvailable = true;
                move.InsertDestinationBlock(this);
                move.SourceBlock.AvailableMoves++;
            }

            return(moveApplied);
        }
Exemplo n.º 3
0
        public override bool ApplyReverseMoveForLoop(
            IGameBlockDestination destinationBlock,
            MovementDirection directionInReverse,
            int numberOfBlocksToMove,
            out BlockMovement move,
            IGameBlock previousBlock,
            IGameBlockDestination previousDestination,
            Queue<IGameBlock> blockHistory)
        {
            move = null;

            // There should already be a destination block
            if (destinationBlock == null)
            {
                return false;
            }

            blockHistory.Enqueue(this);

            bool moveApplied;
            switch (directionInReverse)
            {
                default:
                case MovementDirection.Down:
                    if (this.Bottom == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Bottom.ApplyReverseMoveForLoop(
                            destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Up:
                    if (this.Top == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Top.ApplyReverseMoveForLoop(
                            destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Right:
                    if (this.Right == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Right.ApplyReverseMoveForLoop(
                            destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;

                case MovementDirection.Left:
                    if (this.Left == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Left.ApplyReverseMoveForLoop(
                            destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                    break;
            }

            if (moveApplied && !this.isAvailable && move != null)
            {
                this.IsAvailable = true;
                move.InsertDestinationBlock(this);
                move.SourceBlock.AvailableMoves++;
            }

            return moveApplied;
        }
Exemplo n.º 4
0
        public override bool ApplyReverseMove(
            IGameBlockDestination destinationBlock,
            MovementDirection directionInReverse,
            int numberOfBlocksToMove,
            out BlockMovement move,
            IGameBlock previousBlock,
            IGameBlockDestination previousDestinationBlock,
            Queue <IGameBlock> blockHistory)
        {
            move = null;

            // Starting with a non-filled block isn't valid
            if (destinationBlock != null && this.isAvailable)
            {
                return(false);
            }

            // If this is the destination
            bool thisIsFinalMove      = destinationBlock == null;
            int  availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary <IGameBlock, IGameBlock>());

            // See if there are enough blocks to do this move
            if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove)
            {
                return(false);
            }
            else if (destinationBlock == this)
            {
                // If it came back around to this block again, then it's in a loop.  It needs to break out.
                return(false);
            }
            else if (blockHistory.Contains(this))
            {
                // If it came back around to this block again, then it's in a loop.  It needs to break out.
                return(false);
            }

            blockHistory.Enqueue(this);

            // Use this block as the destination block if destinationBlock is null
            IGameBlockDestination destination = destinationBlock ?? this;

            bool moveApplied;

            switch (directionInReverse)
            {
            default:
            case MovementDirection.Up:
                if (this.Bottom == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Bottom.ApplyReverseMove(
                        destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Down:
                if (this.Top == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Top.ApplyReverseMove(
                        destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Left:
                if (this.Right == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Right.ApplyReverseMove(
                        destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;

            case MovementDirection.Right:
                if (this.Left == null)
                {
                    moveApplied = false;
                }
                else
                {
                    moveApplied = this.Left.ApplyReverseMove(
                        destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                }
                break;
            }

            if (moveApplied && !this.isAvailable && move != null)
            {
                this.IsAvailable = true;
                move.InsertDestinationBlock(this);
                move.SourceBlock.AvailableMoves++;
            }

            return(moveApplied);
        }
Exemplo n.º 5
0
        public override bool ApplyReverseMove(
            IGameBlockDestination destinationBlock,
            MovementDirection directionInReverse,
            int numberOfBlocksToMove,
            out BlockMovement move,
            IGameBlock previousBlock,
            IGameBlockDestination previousDestinationBlock,
            Queue <IGameBlock> blockHistory)
        {
            move = null;

            // Starting with a non-filled block isn't valid
            if (destinationBlock != null && this.numberOfMovesApplied == 0)
            {
                return(false);
            }

            // If this is the destination
            bool thisIsFinalMove      = destinationBlock == null;
            int  availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary <IGameBlock, IGameBlock>());

            // See if there are enough blocks to do this move
            if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove - 1)
            {
                return(false);
            }

            bool isThisBlockUsedInLoop = ReferenceEquals(destinationBlock, this) || blockHistory.Contains(this);

            blockHistory.Enqueue(this);

            // Use this block as the destination block if destinationBlock is null
            IGameBlockDestination destination = destinationBlock ?? this;

            bool moveApplied;

            switch (directionInReverse)
            {
            default:
            case MovementDirection.Up:
                if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop)
                {
                    if (this.Top == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Top.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }

                    // Loop failed, so try non-looped
                    if (!moveApplied && this.Bottom != null)
                    {
                        moveApplied = this.Bottom.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }
                else
                {
                    if (this.Bottom == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Bottom.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }

                break;

            case MovementDirection.Down:
                if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop)
                {
                    if (this.Bottom == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Bottom.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }

                    // Loop failed, so try non-looped
                    if (!moveApplied && this.Top != null)
                    {
                        moveApplied = this.Top.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }
                else
                {
                    if (this.Top == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Top.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }

                break;

            case MovementDirection.Left:
                if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop)
                {
                    if (this.Left == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Left.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }

                    // Loop failed, so try non-looped
                    if (!moveApplied && this.Right != null)
                    {
                        moveApplied = this.Right.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }
                else
                {
                    if (this.Right == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Right.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }

                break;

            case MovementDirection.Right:
                if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop)
                {
                    if (this.Right == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Right.ApplyReverseMoveForLoop(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }

                    // Loop failed, so try non-looped
                    if (!moveApplied && this.Left != null)
                    {
                        moveApplied = this.Left.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }
                else
                {
                    if (this.Left == null)
                    {
                        moveApplied = false;
                    }
                    else
                    {
                        moveApplied = this.Left.ApplyReverseMove(
                            destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory);
                    }
                }

                break;
            }

            if (moveApplied && !this.IsFullyAvailable && move != null)
            {
                this.SetAvailability(true);
                move.InsertDestinationBlock(this);
                move.SourceBlock.AvailableMoves++;
            }

            return(moveApplied);
        }