Ejemplo n.º 1
0
        private static void SolveMovements(GameBoard gameBoard, IGameBlockParent sourceBlock, BlockMovement head)
        {
            string key = gameBoard.GetBoardStringFullHashed() + "_" + sourceBlock.IndexRow + "_" + sourceBlock.IndexColumn;

            lock (AlreadyTestedBoards)
            {
                // Already tested this, so don't need to try it again
                if (AlreadyTestedBoards.Contains(key))
                {
                    return;
                }

                AlreadyTestedBoards.Add(key);
            }

            List <MovementDirection> movementDirections = GetDirections();

            bool allFailures = true;

            foreach (MovementDirection direction in movementDirections)
            {
                BlockMovement currentMove = new BlockMovement(sourceBlock, direction);
                BlockMovement headMove;
                if (head != null)
                {
                    headMove = head.CloneFromGameBoard(gameBoard, head);
                    headMove.Enqueue(currentMove);
                }
                else
                {
                    currentMove.Head = currentMove;
                    headMove         = currentMove;
                }

                if (sourceBlock.ApplyMove(null, direction, headMove))
                {
                    allFailures = false;

                    List <IGameBlockParent> leftoverBlocks =
                        gameBoard.GameBlocks.OfType <IGameBlockParent>().Where(g => g.AvailableMoves > 0).ToList();

                    if (leftoverBlocks.Count == 0)
                    {
                        if (gameBoard.HasOrphan())
                        {
                            // failed
                            lock (MyLock)
                            {
                                Failures++;
                            }
                        }
                        else
                        {
                            // succeeded
                            lock (MyLock)
                            {
                                Successes++;
                            }
                        }
                    }
                    else
                    {
                        // Continue to the next move
                        foreach (IGameBlockParent gameBlockParent in leftoverBlocks)
                        {
                            SolveMovements(gameBoard, gameBlockParent, head);
                        }
                    }

                    // Undo move
                    headMove.UndoMove();
                }
            }

            if (allFailures)
            {
                // Any direction, doesn't matter
                BlockMovement currentMove = new BlockMovement(sourceBlock, MovementDirection.Right);
                BlockMovement headMove;
                if (head != null)
                {
                    headMove = head.CloneFromGameBoard(gameBoard, head);
                    headMove.Enqueue(currentMove);
                }
                else
                {
                    currentMove.Head = currentMove;
                    headMove         = currentMove;
                }

                lock (MyLock)
                {
                    Failures++;
                }
            }
        }