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
Board.cpp@0:3b5e97ab5884, 2014-10-21 (annotated)
- Committer:
- sucrelv
- Date:
- Tue Oct 21 15:10:36 2014 +0000
- Revision:
- 0:3b5e97ab5884
initial upload
Who changed what in which revision?
User | Revision | Line number | New 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 | } |