This is a remake of tetris game for mbed. Please see detail here http://developer.mbed.org/users/sucrelv/notebook/tetris-game-on-mbed

Dependencies:   4DGL-uLCD-SE PinDetect SDFileSystem mbed-rtos mbed wave_player

Committer:
sucrelv
Date:
Tue Oct 21 15:10:36 2014 +0000
Revision:
0:3b5e97ab5884
initial upload

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sucrelv 0:3b5e97ab5884 1 #include "Board.h"
sucrelv 0:3b5e97ab5884 2
sucrelv 0:3b5e97ab5884 3 /*
sucrelv 0:3b5e97ab5884 4 ==================
sucrelv 0:3b5e97ab5884 5 Init
sucrelv 0:3b5e97ab5884 6 ==================
sucrelv 0:3b5e97ab5884 7 */
sucrelv 0:3b5e97ab5884 8 Board::Board (Pieces *pPieces, int pScreenHeight)
sucrelv 0:3b5e97ab5884 9 {
sucrelv 0:3b5e97ab5884 10 // Get the screen height
sucrelv 0:3b5e97ab5884 11 mScreenHeight = pScreenHeight;
sucrelv 0:3b5e97ab5884 12
sucrelv 0:3b5e97ab5884 13 // Get the pointer to the pieces class
sucrelv 0:3b5e97ab5884 14 mPieces = pPieces;
sucrelv 0:3b5e97ab5884 15
sucrelv 0:3b5e97ab5884 16 //Init the board blocks with free positions
sucrelv 0:3b5e97ab5884 17 InitBoard();
sucrelv 0:3b5e97ab5884 18 }
sucrelv 0:3b5e97ab5884 19
sucrelv 0:3b5e97ab5884 20
sucrelv 0:3b5e97ab5884 21 /*
sucrelv 0:3b5e97ab5884 22 ======================================
sucrelv 0:3b5e97ab5884 23 Init the board blocks with free positions
sucrelv 0:3b5e97ab5884 24 ======================================
sucrelv 0:3b5e97ab5884 25 */
sucrelv 0:3b5e97ab5884 26 void Board::InitBoard()
sucrelv 0:3b5e97ab5884 27 {
sucrelv 0:3b5e97ab5884 28 for (int i = 0; i < BOARD_WIDTH; i++)
sucrelv 0:3b5e97ab5884 29 for (int j = 0; j < BOARD_HEIGHT; j++)
sucrelv 0:3b5e97ab5884 30 mBoard[i][j] = POS_FREE;
sucrelv 0:3b5e97ab5884 31 }
sucrelv 0:3b5e97ab5884 32
sucrelv 0:3b5e97ab5884 33 /*
sucrelv 0:3b5e97ab5884 34 ======================================
sucrelv 0:3b5e97ab5884 35 Store a piece in the board by filling the blocks
sucrelv 0:3b5e97ab5884 36
sucrelv 0:3b5e97ab5884 37 Parameters:
sucrelv 0:3b5e97ab5884 38
sucrelv 0:3b5e97ab5884 39 >> pX: Horizontal position in blocks
sucrelv 0:3b5e97ab5884 40 >> pY: Vertical position in blocks
sucrelv 0:3b5e97ab5884 41 >> pPiece: Piece to draw
sucrelv 0:3b5e97ab5884 42 >> pRotation: 1 of the 4 possible rotations
sucrelv 0:3b5e97ab5884 43 ======================================
sucrelv 0:3b5e97ab5884 44 */
sucrelv 0:3b5e97ab5884 45 void Board::StorePiece (int pX, int pY, int pPiece, int pRotation)
sucrelv 0:3b5e97ab5884 46 {
sucrelv 0:3b5e97ab5884 47 // Store each block of the piece into the board
sucrelv 0:3b5e97ab5884 48 for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
sucrelv 0:3b5e97ab5884 49 {
sucrelv 0:3b5e97ab5884 50 for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
sucrelv 0:3b5e97ab5884 51 {
sucrelv 0:3b5e97ab5884 52 // Store only the blocks of the piece that are not holes
sucrelv 0:3b5e97ab5884 53 if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)
sucrelv 0:3b5e97ab5884 54 mBoard[i1][j1] = POS_FILLED;
sucrelv 0:3b5e97ab5884 55 }
sucrelv 0:3b5e97ab5884 56 }
sucrelv 0:3b5e97ab5884 57 }
sucrelv 0:3b5e97ab5884 58
sucrelv 0:3b5e97ab5884 59
sucrelv 0:3b5e97ab5884 60 /*
sucrelv 0:3b5e97ab5884 61 ======================================
sucrelv 0:3b5e97ab5884 62 Check if the game is over becase a piece have achived the upper position
sucrelv 0:3b5e97ab5884 63
sucrelv 0:3b5e97ab5884 64 Returns true or false
sucrelv 0:3b5e97ab5884 65 ======================================
sucrelv 0:3b5e97ab5884 66 */
sucrelv 0:3b5e97ab5884 67 bool Board::IsGameOver()
sucrelv 0:3b5e97ab5884 68 {
sucrelv 0:3b5e97ab5884 69 //If the first line has blocks, then, game over
sucrelv 0:3b5e97ab5884 70 for (int i = 0; i < BOARD_WIDTH; i++)
sucrelv 0:3b5e97ab5884 71 {
sucrelv 0:3b5e97ab5884 72 if (mBoard[i][0] == POS_FILLED) return true;
sucrelv 0:3b5e97ab5884 73 }
sucrelv 0:3b5e97ab5884 74
sucrelv 0:3b5e97ab5884 75 return false;
sucrelv 0:3b5e97ab5884 76 }
sucrelv 0:3b5e97ab5884 77
sucrelv 0:3b5e97ab5884 78
sucrelv 0:3b5e97ab5884 79 /*
sucrelv 0:3b5e97ab5884 80 ======================================
sucrelv 0:3b5e97ab5884 81 Delete a line of the board by moving all above lines down
sucrelv 0:3b5e97ab5884 82
sucrelv 0:3b5e97ab5884 83 Parameters:
sucrelv 0:3b5e97ab5884 84
sucrelv 0:3b5e97ab5884 85 >> pY: Vertical position in blocks of the line to delete
sucrelv 0:3b5e97ab5884 86 ======================================
sucrelv 0:3b5e97ab5884 87 */
sucrelv 0:3b5e97ab5884 88 void Board::DeleteLine (int pY)
sucrelv 0:3b5e97ab5884 89 {
sucrelv 0:3b5e97ab5884 90 // Moves all the upper lines one row down
sucrelv 0:3b5e97ab5884 91 for (int j = pY; j > 0; j--)
sucrelv 0:3b5e97ab5884 92 {
sucrelv 0:3b5e97ab5884 93 for (int i = 0; i < BOARD_WIDTH; i++)
sucrelv 0:3b5e97ab5884 94 {
sucrelv 0:3b5e97ab5884 95 mBoard[i][j] = mBoard[i][j-1];
sucrelv 0:3b5e97ab5884 96 }
sucrelv 0:3b5e97ab5884 97 }
sucrelv 0:3b5e97ab5884 98 }
sucrelv 0:3b5e97ab5884 99
sucrelv 0:3b5e97ab5884 100
sucrelv 0:3b5e97ab5884 101 /*
sucrelv 0:3b5e97ab5884 102 ======================================
sucrelv 0:3b5e97ab5884 103 Delete all the lines that should be removed
sucrelv 0:3b5e97ab5884 104 ======================================
sucrelv 0:3b5e97ab5884 105 */
sucrelv 0:3b5e97ab5884 106 int Board::DeletePossibleLines ()
sucrelv 0:3b5e97ab5884 107 {
sucrelv 0:3b5e97ab5884 108 int count =0;
sucrelv 0:3b5e97ab5884 109 for (int j = 0; j < BOARD_HEIGHT; j++)
sucrelv 0:3b5e97ab5884 110 {
sucrelv 0:3b5e97ab5884 111 int i = 0;
sucrelv 0:3b5e97ab5884 112 while (i < BOARD_WIDTH)
sucrelv 0:3b5e97ab5884 113 {
sucrelv 0:3b5e97ab5884 114 if (mBoard[i][j] != POS_FILLED) break;
sucrelv 0:3b5e97ab5884 115 i++;
sucrelv 0:3b5e97ab5884 116 }
sucrelv 0:3b5e97ab5884 117
sucrelv 0:3b5e97ab5884 118 if (i == BOARD_WIDTH)
sucrelv 0:3b5e97ab5884 119 {
sucrelv 0:3b5e97ab5884 120 DeleteLine (j);
sucrelv 0:3b5e97ab5884 121 count++;
sucrelv 0:3b5e97ab5884 122 }
sucrelv 0:3b5e97ab5884 123 }
sucrelv 0:3b5e97ab5884 124 return count;
sucrelv 0:3b5e97ab5884 125 }
sucrelv 0:3b5e97ab5884 126
sucrelv 0:3b5e97ab5884 127
sucrelv 0:3b5e97ab5884 128 /*
sucrelv 0:3b5e97ab5884 129 ======================================
sucrelv 0:3b5e97ab5884 130 Returns 1 (true) if the this block of the board is empty, 0 if it is filled
sucrelv 0:3b5e97ab5884 131
sucrelv 0:3b5e97ab5884 132 Parameters:
sucrelv 0:3b5e97ab5884 133
sucrelv 0:3b5e97ab5884 134 >> pX: Horizontal position in blocks
sucrelv 0:3b5e97ab5884 135 >> pY: Vertical position in blocks
sucrelv 0:3b5e97ab5884 136 ======================================
sucrelv 0:3b5e97ab5884 137 */
sucrelv 0:3b5e97ab5884 138 bool Board::IsFreeBlock (int pX, int pY)
sucrelv 0:3b5e97ab5884 139 {
sucrelv 0:3b5e97ab5884 140 if (mBoard [pX][pY] == POS_FREE) return true; else return false;
sucrelv 0:3b5e97ab5884 141 }
sucrelv 0:3b5e97ab5884 142
sucrelv 0:3b5e97ab5884 143
sucrelv 0:3b5e97ab5884 144 /*
sucrelv 0:3b5e97ab5884 145 ======================================
sucrelv 0:3b5e97ab5884 146 Returns the horizontal position (isn pixels) of the block given like parameter
sucrelv 0:3b5e97ab5884 147
sucrelv 0:3b5e97ab5884 148 Parameters:
sucrelv 0:3b5e97ab5884 149
sucrelv 0:3b5e97ab5884 150 >> pPos: Horizontal position of the block in the board
sucrelv 0:3b5e97ab5884 151 ======================================
sucrelv 0:3b5e97ab5884 152 */
sucrelv 0:3b5e97ab5884 153 int Board::GetXPosInPixels (int pPos)
sucrelv 0:3b5e97ab5884 154 {
sucrelv 0:3b5e97ab5884 155 return ( ( BOARD_POSITION - (BLOCK_SIZE * (BOARD_WIDTH / 2)) ) + (pPos * BLOCK_SIZE) );
sucrelv 0:3b5e97ab5884 156 }
sucrelv 0:3b5e97ab5884 157
sucrelv 0:3b5e97ab5884 158
sucrelv 0:3b5e97ab5884 159 /*
sucrelv 0:3b5e97ab5884 160 ======================================
sucrelv 0:3b5e97ab5884 161 Returns the vertical position (in pixels) of the block given like parameter
sucrelv 0:3b5e97ab5884 162
sucrelv 0:3b5e97ab5884 163 Parameters:
sucrelv 0:3b5e97ab5884 164
sucrelv 0:3b5e97ab5884 165 >> pPos: Horizontal position of the block in the board
sucrelv 0:3b5e97ab5884 166 ======================================
sucrelv 0:3b5e97ab5884 167 */
sucrelv 0:3b5e97ab5884 168 int Board::GetYPosInPixels (int pPos)
sucrelv 0:3b5e97ab5884 169 {
sucrelv 0:3b5e97ab5884 170 return ( (mScreenHeight - (BLOCK_SIZE * BOARD_HEIGHT)) + (pPos * BLOCK_SIZE) );
sucrelv 0:3b5e97ab5884 171 }
sucrelv 0:3b5e97ab5884 172
sucrelv 0:3b5e97ab5884 173
sucrelv 0:3b5e97ab5884 174 /*
sucrelv 0:3b5e97ab5884 175 ======================================
sucrelv 0:3b5e97ab5884 176 Check if the piece can be stored at this position without any collision
sucrelv 0:3b5e97ab5884 177 Returns true if the movement is possible, false if it not possible
sucrelv 0:3b5e97ab5884 178
sucrelv 0:3b5e97ab5884 179 Parameters:
sucrelv 0:3b5e97ab5884 180
sucrelv 0:3b5e97ab5884 181 >> pX: Horizontal position in blocks
sucrelv 0:3b5e97ab5884 182 >> pY: Vertical position in blocks
sucrelv 0:3b5e97ab5884 183 >> pPiece: Piece to draw
sucrelv 0:3b5e97ab5884 184 >> pRotation: 1 of the 4 possible rotations
sucrelv 0:3b5e97ab5884 185 ======================================
sucrelv 0:3b5e97ab5884 186 */
sucrelv 0:3b5e97ab5884 187 bool Board::IsPossibleMovement (int pX, int pY, int pPiece, int pRotation)
sucrelv 0:3b5e97ab5884 188 {
sucrelv 0:3b5e97ab5884 189 // Checks collision with pieces already stored in the board or the board limits
sucrelv 0:3b5e97ab5884 190 // This is just to check the 5x5 blocks of a piece with the appropiate area in the board
sucrelv 0:3b5e97ab5884 191 for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
sucrelv 0:3b5e97ab5884 192 {
sucrelv 0:3b5e97ab5884 193 for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
sucrelv 0:3b5e97ab5884 194 {
sucrelv 0:3b5e97ab5884 195 // Check if the piece is outside the limits of the board
sucrelv 0:3b5e97ab5884 196 if ( i1 < 0 ||
sucrelv 0:3b5e97ab5884 197 i1 > BOARD_WIDTH - 1 ||
sucrelv 0:3b5e97ab5884 198 j1 > BOARD_HEIGHT - 1)
sucrelv 0:3b5e97ab5884 199 {
sucrelv 0:3b5e97ab5884 200 if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)
sucrelv 0:3b5e97ab5884 201 return 0;
sucrelv 0:3b5e97ab5884 202 }
sucrelv 0:3b5e97ab5884 203
sucrelv 0:3b5e97ab5884 204 // Check if the piece have collisioned with a block already stored in the map
sucrelv 0:3b5e97ab5884 205 if (j1 >= 0)
sucrelv 0:3b5e97ab5884 206 {
sucrelv 0:3b5e97ab5884 207 if ((mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0) &&
sucrelv 0:3b5e97ab5884 208 (!IsFreeBlock (i1, j1)) )
sucrelv 0:3b5e97ab5884 209 return false;
sucrelv 0:3b5e97ab5884 210 }
sucrelv 0:3b5e97ab5884 211 }
sucrelv 0:3b5e97ab5884 212 }
sucrelv 0:3b5e97ab5884 213
sucrelv 0:3b5e97ab5884 214 // No collision
sucrelv 0:3b5e97ab5884 215 return true;
sucrelv 0:3b5e97ab5884 216 }