예제 #1
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;
 }
예제 #2
0
파일: Board.cs 프로젝트: SinaC/TetriNET
        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
        public void DrawPiece(IPiece piece, int boardHeight)
        {
            // Clear
            foreach (Rectangle rect in _grid)
            {
                rect.Fill = TransparentColor;
            }

            if (piece == null)
            {
                return;
            }
            // Draw
            IPiece temp = piece.Clone();
            int    minX, minY, maxX, maxY;

            temp.GetAbsoluteBoundingRectangle(out minX, out minY, out maxX, out maxY);
            // Move to top, left
            temp.Translate(-minX, 0);
            temp.Translate(0, boardHeight - maxY);
            Pieces cellPiece = temp.Value;

            for (int i = 1; i <= temp.TotalCells; i++)
            {
                int x, y;
                temp.GetCellAbsolutePosition(i, out x, out y); // 1->Width x 1->Height
                int cellY = boardHeight - y;
                int cellX = x;

                Rectangle uiPart = GetControl(cellX, cellY);
                uiPart.Fill = TextureManager.TextureManager.Instance.GetBigPiece(cellPiece);
            }
        }
예제 #4
0
        private void DrawPiece(IPiece piece, int size, int topX, int topY)
        {
            IPiece temp      = piece.Clone();
            Pieces cellPiece = temp.Value;

            for (int i = 1; i <= temp.TotalCells; i++)
            {
                int x, y;
                temp.GetCellAbsolutePosition(i, out x, out y); // 1->Width x 1->Height

                Rectangle rectangle = new Rectangle
                {
                    Width  = size,
                    Height = size,
                    Fill   = TextureManager.TextureManager.Instance.GetBigPiece(cellPiece)
                };
                Canvas.Children.Add(rectangle);
                Canvas.SetLeft(rectangle, topX + x * size);
                Canvas.SetTop(rectangle, topY + y * size);
            }

            Rectangle anchor = new Rectangle
            {
                Width  = size,
                Height = size,
                Fill   = PieceAnchorColor
            };

            Canvas.Children.Add(anchor);
            Canvas.SetLeft(anchor, topX);
            Canvas.SetTop(anchor, topY);
        }
예제 #5
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;
                }
            }
        }
예제 #6
0
        // The following counts the number of cells (0..4) of a piece that would
        // be eliminated by dropping the piece.
        public static int CountPieceCellsEliminated(IBoard board, IPiece piece, bool alreadyDropped)
        {
            // Copy piece and board so that this measurement is not destructive.
            IBoard copyOfBoard = alreadyDropped ? board : board.Clone();
            IPiece copyOfPiece = alreadyDropped ? piece : piece.Clone();

            if (!alreadyDropped)
            {
                // Drop copy of piece on to the copy of the board
                copyOfBoard.DropAndCommit(copyOfPiece);
            }

            // Scan rows.  For each full row, check all board Y values for the
            // piece.  If any board Y of the piece matches the full row Y,
            // increment the total eliminated cells.
            int countPieceCellsEliminated = 0;

            for (int y = 1; y <= copyOfBoard.Height; y++)
            {
                bool fullRow = true; // hypothesis
                for (int x = 1; x <= copyOfBoard.Width; x++)
                {
                    byte cellValue = copyOfBoard[x, y];
                    if (cellValue == 0)
                    {
                        fullRow = false;
                        break;
                    }
                }

                if (fullRow)
                {
                    // Find any matching board-relative Y values in dropped copy of piece.
                    for (int cellIndex = 1; cellIndex <= piece.TotalCells; cellIndex++)
                    {
                        int boardX;
                        int boardY;
                        copyOfPiece.GetCellAbsolutePosition(cellIndex, out boardX, out boardY);
                        if (boardY == y)
                        {
                            countPieceCellsEliminated++;  // Moohahahaaa!
                        }
                    }
                }
            }

            return(countPieceCellsEliminated);
        }
예제 #7
0
파일: Board.cs 프로젝트: SinaC/TetriNET
        public virtual 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))
            {
                return(false);
            }
            // Simply update the piece rotation
            piece.RotateCounterClockwise();
            return(true);
        }
예제 #8
0
파일: Board.cs 프로젝트: SinaC/TetriNET
        public bool MoveDown(IPiece piece)
        {
            // Special case: cannot place piece at starting location.
            if (!CheckNoConflict(piece))
            {
                return(false);
            }
            // Try to move down
            IPiece tempPiece = piece.Clone();

            tempPiece.Translate(0, -1);
            if (!CheckNoConflict(tempPiece))
            {
                return(false);
            }
            // Simply update the piece Y value
            piece.Translate(0, -1);
            return(true);
        }
예제 #9
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);
        }
예제 #10
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);
        }
예제 #11
0
파일: Board.cs 프로젝트: SinaC/TetriNET2
 public virtual 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))
         return false;
     // Simply update the piece rotation
     piece.RotateCounterClockwise();
     return true;
 }
예제 #12
0
파일: Board.cs 프로젝트: SinaC/TetriNET2
 public bool MoveDown(IPiece piece)
 {
     // Special case: cannot place piece at starting location.
     if (!CheckNoConflict(piece))
         return false;
     // Try to move down
     IPiece tempPiece = piece.Clone();
     tempPiece.Translate(0, -1);
     if (!CheckNoConflict(tempPiece))
         return false;
     // Simply update the piece Y value
     piece.Translate(0, -1);
     return true;
 }
예제 #13
0
파일: Board.cs 프로젝트: SinaC/TetriNET2
        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);
        }
예제 #14
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);
        }