Beispiel #1
0
        /* Adds a tetromino to the given tetris grid. */
        public Grid PlaceTetromino(Grid grid, Tetromino piece, int col)
        {
            /* The offset determines how far from the top the piece must be placed. */
            int offset = BotHelperFunctions.DistanceToField(grid, piece, col);

            /* Insert the piece grid into the playing grid. */
            grid.InsertGrid(piece, offset, col);

            return(grid);
        }
Beispiel #2
0
        /* Calculates the best move for the current grid and performs that move. */
        private void CalculateBestMoveAsync()
        {
            /* Copy of the processor grid, used for score calculations. */
            Grid currentGrid = Processor.Grid.Clone();
            /* The current workable tetromino. */
            Tetromino currentPiece = Processor.CurrentPiece.Clone();
            /* The look ahead tetromino, used for next level calculations. */
            Tetromino lookAheadPiece = Processor.LookAheadPiece.Clone();

            /* Remove the current piece from the top of the grid. */
            currentGrid.DeleteGrid(currentPiece, Processor.CurrentPieceRow, Processor.CurrentPieceColumn);

            PerformTetrisMove(CalculateBestMove(currentGrid, currentPiece, lookAheadPiece));
        }
Beispiel #3
0
        /* Calculates the smallest distance from the tetromino to the playing field. */
        public static int DistanceToField(Grid grid, Tetromino piece, int col)
        {
            /* Get the first distance from piece to field. */
            int minDistance = grid.DistanceToFirstBlock(piece.LowestBlockRow(0), col);

            /* Compare remaining distances. */
            for (int i = 1; i < piece.Width; i++)
            {
                /* Get distance. */
                int distance = grid.DistanceToFirstBlock(piece.LowestBlockRow(i), col + i);

                /* Select smallest distance.*/
                if (minDistance > distance)
                {
                    minDistance = distance;
                }
            }

            return(minDistance);
        }
Beispiel #4
0
        /* Fills the queue with 7 new pieces. */
        private void GeneratePieces()
        {
            Random r = new Random();
            /* Get a list of all pieces. */
            List <Tetromino> Pieces = new List <Tetromino>(Tetromino.All());

            /* The first item in the queue has to be an I, J, L or T piece.
             * These are the first four in the array, thus we can generate a random
             * number up to four to get one of those pieces. */

            int i = r.Next(4);

            PieceQueue.Enqueue(Pieces[i]);
            Pieces.RemoveAt(i);

            /* Generate the remaining pieces. */
            while (Pieces.Count > 0)
            {
                i = r.Next(Pieces.Count);
                PieceQueue.Enqueue(Pieces[i]);
                Pieces.RemoveAt(i);
            }
        }
Beispiel #5
0
 /* Determines whether a tetromino is an I piece. */
 private bool IsIPiece(Tetromino piece)
 {
     /* Only tetrominoes with width 4 can be I pieces. */
     return(piece.Width == 4);
 }
Beispiel #6
0
        /* Calculates the move with the highest grid score,
         * taking the current and look ahead pieces into consideration. */
        private TetrisMove CalculateBestMove(Grid grid, Tetromino piece, Tetromino lookAheadPiece)
        {
            /* Create a variable to hold the best move. */
            TetrisMove bestMove = new TetrisMove();
            /* Grids used for calculations. */
            Grid tempGrid      = null;
            Grid lookAheadGrid = null;

            /* Reset the bot move in the tetris processor. */
            Processor.BotPiece          = null;
            Processor.BotLookAheadPiece = null;
            Processor.BotMove           = true;

            bool prioritizeTetrisses = false;
            int  rightBoundaryOffset = 1;
            /* Highest point in the current field. */
            int fieldHeight = 0;

            if (PrioritizeTetrisses)
            {
                int tetrisReady = BotHelperFunctions.TetrisReady(grid);
                if (tetrisReady == 0 && IsIPiece(piece))
                {
                    /* Rotate the I piece upright. */
                    piece.Rotate90Deg();
                    /* Move it over to the right of the grid to make a tetris. */
                    return(new TetrisMove(grid.Width - piece.LeftMostBlockColumn() - 1, 1));
                }

                fieldHeight = BotHelperFunctions.FieldHeight(grid);

                if (fieldHeight < ForceNormalPlayFieldHeight && tetrisReady != 2)
                {
                    /* If it is still safe to do so, play without the last column. */
                    rightBoundaryOffset = 2;
                    prioritizeTetrisses = true;
                }
            }

            /* Calculate best permutation*/
            for (int rotation = 0; rotation < piece.UniqueRotations; rotation++)
            {
                /* Calculate boundaries. */
                int leftMostColumn  = piece.LeftMostBlockColumn();
                int rightMostColumn = grid.Width - piece.RightMostBlockColumn() - rightBoundaryOffset;

                for (int column = -leftMostColumn; column <= rightMostColumn; column++)
                {
                    /* Calculate best permutation for look ahead piece. */
                    for (int lookAheadRotation = 0; lookAheadRotation < lookAheadPiece.UniqueRotations; lookAheadRotation++)
                    {
                        /* Calculate look ahead boundaries. */
                        int lookAheadLeftMostColumn  = lookAheadPiece.LeftMostBlockColumn();
                        int lookAheadRightMostColumn = grid.Width - lookAheadPiece.RightMostBlockColumn() - rightBoundaryOffset;

                        for (int lookAheadColumn = -lookAheadLeftMostColumn; lookAheadColumn <= lookAheadRightMostColumn; lookAheadColumn++)
                        {
                            /* Create a grid with current pieces. */
                            tempGrid      = PlaceTetromino(grid.Clone(), piece, column);
                            lookAheadGrid = PlaceTetromino(tempGrid.Clone(), lookAheadPiece, lookAheadColumn);

                            double score = CalculateGridScore(lookAheadGrid, prioritizeTetrisses);

                            if (score > bestMove.Score)
                            {
                                /* Update best move. */
                                bestMove.Column   = column;
                                bestMove.Rotation = rotation;
                                bestMove.Score    = score;

                                /* Update bot move in tetris processor. */
                                Processor.BotPiece      = piece;
                                Processor.BotMoveRow    = BotHelperFunctions.DistanceToField(grid, piece, column);
                                Processor.BotMoveColumn = column;

                                Processor.BotLookAheadPiece      = lookAheadPiece;
                                Processor.BotLookAheadMoveRow    = BotHelperFunctions.DistanceToField(tempGrid, lookAheadPiece, lookAheadColumn);
                                Processor.BotLookAheadMoveColumn = lookAheadColumn;

                                /* Update view. */
                                Processor.RaiseUpdateEvent();

                                Thread.Sleep(BestMoveDelay);
                            }
                        }

                        /* Rotate look ahead piece for the next permutation. */
                        lookAheadPiece.Rotate90Deg();
                    }
                }

                /* Rotate piece for the next permutation. */
                piece.Rotate90Deg();
            }

            /* Remove the preview of the bots move. */
            Processor.BotMove = false;

            return(bestMove);
        }