Exemplo n.º 1
0
        private double PrivateStrategyNextPiece
        (
            STBoard board,
            STPiece piece,
            STPiece.STPieceShape nextPieceShape, // None == no piece available or known
            ref int bestRotationDelta,           // 0 or {0,1,2,3}
            ref int bestTranslationDelta         // 0 or {...,-2,-1,0,1,2,...}
        )
        {
            if (false == piece.IsValid( ))
            {
                return(0.0);
            }



            int    currentBestTranslationDelta = 0;
            int    currentBestRotationDelta    = 0;
            double currentBestMerit            = (-1.0e20);
            int    currentBestPriority         = 0;

            int    trialTranslationDelta = 0;
            int    trialRotationDelta    = 0;
            double trialMerit            = 0.0;
            int    trialPriority         = 0;

            int  maxOrientations = 0;
            bool moveAcceptable  = false;
            int  count           = 0;



            STBoard tempBoard = new STBoard();
            STPiece tempPiece = new STPiece();



            maxOrientations = STPiece.GetMaximumOrientationsOfShape(piece.GetShape());



            for
            (
                trialRotationDelta = 0;
                trialRotationDelta < maxOrientations;
                trialRotationDelta++
            )
            {
                // Make temporary copy of piece, and rotate the copy.

                tempPiece.CopyFrom(piece);

                for (count = 0; count < trialRotationDelta; count++)
                {
                    tempPiece.Rotate();
                }



                // Determine the translation limits for this rotated piece.

                bool moveIsPossible = false;
                int  minDeltaX      = 0;
                int  maxDeltaX      = 0;
                board.DetermineAccessibleTranslationsForPieceOrientation
                (
                    tempPiece,
                    ref moveIsPossible,                   // false==NONE POSSIBLE
                    ref minDeltaX,                        // Left limit
                    ref maxDeltaX                         // Right limit
                );



                // Consider all allowed translations for the current rotation.

                if (true == moveIsPossible)
                {
                    for
                    (
                        trialTranslationDelta = minDeltaX;
                        trialTranslationDelta <= maxDeltaX;
                        trialTranslationDelta++
                    )
                    {
                        // Evaluate this move

                        // Copy piece to temp and rotate and translate
                        tempPiece.CopyFrom(piece);

                        for (count = 0; count < trialRotationDelta; count++)
                        {
                            tempPiece.Rotate();
                        }

                        tempPiece.Translate(trialTranslationDelta, 0);

                        moveAcceptable =
                            board.DetermineIfPieceIsWithinBoardAndDoesNotOverlapOccupiedCells
                            (
                                tempPiece
                            );

                        if (true == moveAcceptable)
                        {
                            // Since the piece can be (not necessarily GET) at the goal
                            // horizontal translation and orientation, it's worth trying
                            // out a drop and evaluating the move.
                            tempBoard.CopyFrom(board);


                            tempBoard.FullDropAndCommitPieceToBoard(tempPiece);


                            trialPriority = 0;



                            // Okay, now do second move with "Next Piece"
                            int nextPieceBestRotation    = 0;                                // Dummy variable
                            int nextPieceBestTranslation = 0;                                // Dummy variable

                            STPiece nextPiece = new STPiece();
                            nextPiece.SetShape(nextPieceShape);
                            nextPiece.SetX(tempBoard.GetPieceSpawnX());
                            nextPiece.SetY(tempBoard.GetPieceSpawnY() - 1);
                            nextPiece.SetOrientation(1);

                            trialMerit =
                                PrivateStrategy
                                (
                                    true,                             // Not just a single ply; We are calling from a parent ply.
                                    tempBoard,
                                    nextPiece,
                                    ref nextPieceBestRotation,
                                    ref nextPieceBestTranslation
                                );



                            // If this move is better than any move considered before,
                            // or if this move is equally ranked but has a higher priority,
                            // then update this to be our best move.
                            if (
                                (trialMerit > currentBestMerit) ||
                                ((trialMerit == currentBestMerit) && (trialPriority > currentBestPriority))
                                )
                            {
                                currentBestPriority         = trialPriority;
                                currentBestMerit            = trialMerit;
                                currentBestTranslationDelta = trialTranslationDelta;
                                currentBestRotationDelta    = trialRotationDelta;
                            }
                        }
                    }
                }
            }


            // Commit to this move
            bestTranslationDelta = currentBestTranslationDelta;
            bestRotationDelta    = currentBestRotationDelta;


            return(currentBestMerit);
        }