Exemple #1
0
        private double PrivateStrategy
        (
            bool flagCalledFromParentPly,  // True if called from a parent level
            STBoard board,
            STPiece piece,
            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;


                            if (true == flagCalledFromParentPly)
                            {
                                // UNUSED: int rowsEliminated = 0;
                                // UNUSED: rowsEliminated =

                                tempBoard.CollapseAnyCompletedRows();


                                double weightTotalShadowedHoles      = (-0.65);
                                double weightPileHeightWeightedCells = (-0.10);
                                double weightSumOfWellHeights        = (-0.20);

                                trialMerit  = (weightTotalShadowedHoles) * (double)(tempBoard.GetTotalShadowedHoles( ));
                                trialMerit += (weightPileHeightWeightedCells) * (double)(tempBoard.GetPileHeightWeightedCells( ));
                                trialMerit += (weightSumOfWellHeights) * (double)(tempBoard.GetSumOfWellHeights( ));
                            }
                            else
                            {
                                double weightRowElimination          = (0.30);
                                double weightTotalOccupiedCells      = (-0.00);
                                double weightTotalShadowedHoles      = (-0.65);
                                double weightPileHeightWeightedCells = (-0.10);
                                double weightSumOfWellHeights        = (-0.20);

                                int rowsEliminated = 0;
                                rowsEliminated = tempBoard.CollapseAnyCompletedRows();
                                // Single Ply (No next piece)
                                // Averages around 1310 rows in 10 games, with a min of 445 and a max of 3710.
                                trialMerit  = (weightRowElimination) * (double)(rowsEliminated);
                                trialMerit += (weightTotalOccupiedCells) * (double)(tempBoard.GetTotalOccupiedCells( ));
                                trialMerit += (weightTotalShadowedHoles) * (double)(tempBoard.GetTotalShadowedHoles( ));
                                trialMerit += (weightPileHeightWeightedCells) * (double)(tempBoard.GetPileHeightWeightedCells( ));
                                trialMerit += (weightSumOfWellHeights) * (double)(tempBoard.GetSumOfWellHeights( ));
                            }



                            // 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);
        }