Пример #1
0
        public static void GetAccessibleTranslationsForOrientation(IBoard board, IPiece piece, out bool isMovePossible, out int minDeltaX, out int maxDeltaX)
        {
            isMovePossible = false;
            minDeltaX      = 0;
            maxDeltaX      = 0;

            IPiece tempPiece = piece.Clone();

            // Check if we can move
            bool moveAcceptable = board.CheckNoConflict(tempPiece);

            if (!moveAcceptable)
            {
                return;
            }
            isMovePossible = true;

            // Scan from center to left to find left limit.
            for (int trial = 0; trial >= -board.Width; trial--)
            {
                // Copy piece
                tempPiece.CopyFrom(piece);
                // Translate
                tempPiece.Translate(trial, 0);
                // Check if move is valid
                moveAcceptable = board.CheckNoConflict(tempPiece);
                if (moveAcceptable)
                {
                    minDeltaX = trial;
                }
                else
                {
                    break;
                }
            }

            // Scan from center to right to find right limit.
            for (int trial = 0; trial <= board.Width; trial++)
            {
                // Copy piece
                tempPiece.CopyFrom(piece);
                // Translate
                tempPiece.Translate(trial, 0);
                // Check if move is valid
                moveAcceptable = board.CheckNoConflict(tempPiece);
                if (moveAcceptable)
                {
                    maxDeltaX = trial;
                }
                else
                {
                    break;
                }
            }
        }
Пример #2
0
        public void Drop(IPiece piece)
        {
            // Special case: cannot place piece at starting location.
            bool goalAcceptable = CheckNoConflict(piece);

            if (!goalAcceptable) // cannot drop piece at all
            {
                return;
            }

            // Try successively larger drop distances, up to the point of failure.
            // The last successful drop distance becomes our drop distance.
            int    lastSuccessfulDropDistance = 0;
            IPiece tempPiece = piece.Clone();

            for (int trial = 0; trial <= Height; trial++)
            {
                tempPiece.CopyFrom(piece);
                // Set temporary piece to new trial Y
                tempPiece.Translate(0, -trial);

                goalAcceptable = CheckNoConflict(tempPiece);
                if (!goalAcceptable)
                {
                    // We failed to drop this far.  Stop drop search.
                    break;
                }
                else
                {
                    lastSuccessfulDropDistance = trial;
                }
            }
            // Simply update the piece Y value.
            piece.Translate(0, -lastSuccessfulDropDistance);
        }
Пример #3
0
        //http://tetris.wikia.com/wiki/Wall_kick
        public override bool RotateCounterClockwise(IPiece piece)
        {
            // Special case: cannot place piece at starting location.
            if (!CheckNoConflict(piece))
            {
                return(false);
            }
            // Try to rotate
            IPiece tempPiece = piece.Clone();

            tempPiece.RotateCounterClockwise();
            if (!CheckNoConflict(tempPiece))
            {
                // Try to move right then rotate
                tempPiece.CopyFrom(piece);
                tempPiece.Translate(1, 0);
                tempPiece.RotateCounterClockwise();
                if (!CheckNoConflict(tempPiece))
                {
                    // Try to move left then rotate
                    tempPiece.CopyFrom(piece);
                    tempPiece.Translate(-1, 0);
                    tempPiece.RotateCounterClockwise();
                    if (!CheckNoConflict(tempPiece))
                    {
                        return(false);
                    }
                    else
                    {
                        piece.Translate(-1, 0);
                    }
                }
                else
                {
                    piece.Translate(1, 0);
                }
            }
            // Perform rotation (wall kick translation has been done before if needed)
            piece.RotateCounterClockwise();
            return(true);
        }
Пример #4
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!

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

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

            // 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++)
                    {
                        // 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 = EvaluteMove(tempBoard, tempPiece);

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

                            // Check if better than previous best
                            if (trialRating > currentBestRating)
                            {
                                currentBestRating           = trialRating;
                                currentBestTranslationDelta = trialTranslationDelta;
                                currentBestRotationDelta    = trialRotationDelta;
                            }
                        }
                    }
                }
            }

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

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

            return(true);
        }
Пример #5
0
        private double EvaluteMove(IBoard board, IPiece piece, out int bestRotationDelta, out int bestTranslationDelta)
        {
            int    currentBestTranslationDelta = 0;
            int    currentBestRotationDelta    = 0;
            double currentBestRating           = -1.0e+20; // Really bad!
            int    currentBestPriority         = 0;

            //current.Translate(0, -1);

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

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

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

                //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++)
                    {
                        // Evaluate this move

                        // Copy piece
                        tempPiece.CopyFrom(piece);
                        // 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);

                            tempBoard.CollapseCompletedRows();

                            double trialRating = 0;
                            trialRating += -0.65 * BoardHelper.GetTotalShadowedHoles(board);
                            trialRating += -0.10 * BoardHelper.GetPileHeightWeightedCells(board);
                            trialRating += -0.20 * BoardHelper.GetSumOfWellHeights(board);

                            // Check if better than previous best
                            if (trialRating > currentBestRating)
                            {
                                currentBestRating           = trialRating;
                                currentBestTranslationDelta = trialTranslationDelta;
                                currentBestRotationDelta    = trialRotationDelta;
                            }
                        }
                    }
                }
            }
            // Commit to this move
            bestTranslationDelta = currentBestTranslationDelta;
            bestRotationDelta    = currentBestRotationDelta;

            return(currentBestRating);
        }
        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;

            //current.Translate(0, -1);

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

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

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

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

            //Console.SetCursorPosition(0, _client.Board.Height+1);
            // Console.WriteLine("{0} {1} {2:0.000} {3}", bestRotationDelta, bestTranslationDelta, currentBestRating, currentBestPriority);

            return(true);
        }