Ejemplo n.º 1
0
        public bool GetBestMove(IBoard board, IPiece current, IPiece next, out int bestRotationDelta, out int bestTranslationDelta, out bool rotationBeforeTranslation)
        {
            int    currentBestTranslationDelta = 0;
            int    currentBestRotationDelta    = 0;
            double currentBestRating           = -1.0e+20; // Really bad!
            int    currentBestPriority         = 0;

            //if (current.PosY == board.Height) // TODO: put current totally in board before trying to get best move
            //    current.Translate(0, -1);

            IBoard tempBoard = board.Clone();
            IPiece tempPiece = current.Clone();

            MoveManager moveManager = new MoveManager();

            //Log.Default.WriteLine(LogLevels.Debug, "Get Best Move for Piece {0} {1}", tempPiece.Value, tempPiece.Index);

            #region Rotation then translation

            // Consider all possible rotations
            for (int trialRotationDelta = 0; trialRotationDelta < current.MaxOrientations; trialRotationDelta++)
            {
                // Copy piece
                tempPiece.CopyFrom(current);
                // Rotate
                tempPiece.Rotate(trialRotationDelta);

                // Get translation range
                bool isMovePossible;
                int  minDeltaX;
                int  maxDeltaX;
                BoardHelper.GetAccessibleTranslationsForOrientation(board, tempPiece, out isMovePossible, out minDeltaX, out maxDeltaX);

                //Log.Default.WriteLine(LogLevels.Debug, "Accessible translation {0} {1} {2} {3} {4}  {5} {6}", minDeltaX, maxDeltaX, trialRotationDelta, current.PosX, current.PosY, tempPiece.Value, tempPiece.Index);

                //StringBuilder sb = new StringBuilder();
                //for (int i = 1; i <= tempPiece.TotalCells; i++)
                //{
                //    int x, y;
                //    tempPiece.GetCellAbsolutePosition(i, out x, out y);
                //    sb.Append(String.Format("[{0}->{1},{2}]", i, x - tempPiece.PosX, y - tempPiece.PosY));
                //}
                //Log.Log.Default.WriteLine("{0} {1} -> {2}  {3}", trialRotationDelta, minDeltaX, maxDeltaX, sb.ToString());
                if (isMovePossible)
                {
                    // Consider all allowed translations
                    for (int trialTranslationDelta = minDeltaX; trialTranslationDelta <= maxDeltaX; trialTranslationDelta++)
                    {
                        // Check if not already evaluated
                        bool found = moveManager.Exists(trialRotationDelta, trialTranslationDelta);

                        if (!found)
                        {
                            // Evaluate this move

                            // Copy piece
                            tempPiece.CopyFrom(current);
                            // Rotate
                            tempPiece.Rotate(trialRotationDelta);
                            // Translate
                            tempPiece.Translate(trialTranslationDelta, 0);

                            // Check if move is acceptable
                            if (board.CheckNoConflict(tempPiece))
                            {
                                // Copy board
                                tempBoard.CopyFrom(board);
                                // Drop piece
                                tempBoard.DropAndCommit(tempPiece);

                                // Evaluate
                                double trialRating;
                                int    trialPriority;
                                EvaluteMove(tempBoard, tempPiece, out trialRating, out trialPriority);

                                //Log.Log.Default.WriteLine("R:{0:0.0000} P:{1} R:{2} T:{3}", trialRating, trialPriority, trialRotationDelta, trialTranslationDelta);

                                // Check if better than previous best
                                if (trialRating > currentBestRating || (Math.Abs(trialRating - currentBestRating) < 0.0001 && trialPriority > currentBestPriority))
                                {
                                    currentBestRating           = trialRating;
                                    currentBestPriority         = trialPriority;
                                    currentBestTranslationDelta = trialTranslationDelta;
                                    currentBestRotationDelta    = trialRotationDelta;
                                }

                                moveManager.Add(trialRotationDelta, trialTranslationDelta, trialRating, trialPriority);
                            }
                        }
                    }
                }
            }
            //Log.Default.WriteLine(LogLevels.Debug, "ROTATION + TRANSLATION: {0} {1} {2:0.000} {3}", currentBestTranslationDelta, currentBestRotationDelta, currentBestRating, currentBestPriority);
            #endregion

            #region Translation then rotation
            bool isTrialMovePossible;
            int  minTrialDeltaX;
            int  maxTrialDeltaX;
            BoardHelper.GetAccessibleTranslationsForOrientation(board, tempPiece, out isTrialMovePossible, out minTrialDeltaX, out maxTrialDeltaX);
            if (isTrialMovePossible)
            {
                for (int trialTranslationDelta = minTrialDeltaX; trialTranslationDelta <= maxTrialDeltaX; trialTranslationDelta++)
                {
                    // Copy piece
                    tempPiece.CopyFrom(current);
                    // Translate
                    tempPiece.Translate(trialTranslationDelta, 0);

                    // Consider all rotations
                    for (int trialRotationDelta = 0; trialRotationDelta <= current.MaxOrientations; trialRotationDelta++)
                    {
                        // Rotate
                        tempPiece.Rotate(trialRotationDelta);

                        // Check if not already evaluated
                        bool found = moveManager.Exists(trialRotationDelta, trialTranslationDelta);

                        if (!found)
                        {
                            // Evaluate this move

                            // Copy piece
                            tempPiece.CopyFrom(current);
                            // Rotate
                            tempPiece.Rotate(trialRotationDelta);
                            // Translate
                            tempPiece.Translate(trialTranslationDelta, 0);

                            // Check if move is acceptable
                            if (board.CheckNoConflict(tempPiece))
                            {
                                // Copy board
                                tempBoard.CopyFrom(board);
                                // Drop piece
                                tempBoard.DropAndCommit(tempPiece);

                                // Evaluate
                                double trialRating;
                                int    trialPriority;
                                EvaluteMove(tempBoard, tempPiece, out trialRating, out trialPriority);

                                //Log.Log.Default.WriteLine("R:{0:0.0000} P:{1} R:{2} T:{3}", trialRating, trialPriority, trialRotationDelta, trialTranslationDelta);

                                // Check if better than previous best
                                if (trialRating > currentBestRating || (Math.Abs(trialRating - currentBestRating) < 0.0001 && trialPriority > currentBestPriority))
                                {
                                    currentBestRating           = trialRating;
                                    currentBestPriority         = trialPriority;
                                    currentBestTranslationDelta = trialTranslationDelta;
                                    currentBestRotationDelta    = trialRotationDelta;
                                    //Log.Default.WriteLine(LogLevels.Debug, "FOUND BETTER MOVE USING TRANSLATION + ROTATION");
                                }

                                moveManager.Add(trialRotationDelta, trialTranslationDelta, trialRating, trialPriority);
                            }
                        }
                    }
                }
            }
            //Log.Default.WriteLine(LogLevels.Debug, "TRANSLATION + ROTATION: {0} {1} {2:0.000} {3}", currentBestTranslationDelta, currentBestRotationDelta, currentBestRating, currentBestPriority);
            #endregion

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

            // Log.Default.WriteLine(LogLevels.Debug, "{0} {1} {2:0.000} {3}", bestRotationDelta, bestTranslationDelta, currentBestRating, currentBestPriority);

            return(true);
        }