#include SDL_Event sdlEvent; bool should_exit = false; struct Tetromino { Uint16 figure; Uint8 orig, prev, next; }; Tetromino tetromino[19] { {0x0660, 0, 0, 0}, {0x4444, 1, 2, 2}, {0x0F00, 1, 1, 1}, {0x0C60, 2, 4, 4}, {0x2640, 2, 3, 3}, {0x06C0, 3, 6, 6}, {0x4620, 3, 5, 5}, {0x4460, 4, 8, 10}, {0x2E00, 4, 9, 7}, {0xC440, 4, 10, 8}, {0x0E80, 4, 7, 9}, {0x44C0, 5, 12, 14}, {0x0E20, 5, 13, 11}, {0x6440, 5, 14, 12}, {0x8E00, 5, 11, 13}, {0x4640, 6, 16, 18}, {0x4E00, 6, 17, 15}, {0x4C40, 6, 18, 16}, {0x0E40, 6, 15, 17} }; Uint8 starting[7] { 0, 1, 3, 5, 7, 11, 15 }; Uint8 colors[7][3] { {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {0, 255, 255}, {255, 0, 255}, {255, 128, 0} }; Uint8 board[18][10]; SDL_Point piece_pos {3, 0}; Uint8 current_piece = 0; Uint8 next_piece = 0; Uint8 level = 0; Uint8 speed = (20-level)*3; bool is_valid_move() { int x = piece_pos.x+3; int y = piece_pos.y+3; Uint16 piece = tetromino[current_piece].figure; for (int i=0; i<16; i++) { if ((piece & 1) && ( (x >= 10) || (x < 0) || (y >= 18) || (board[y][x] != 0) ) ) { return false; } piece = piece >> 1; x--; if (x < piece_pos.x) { x = piece_pos.x+3; y--; } } return true; } void fix_piece() { int x = piece_pos.x+3; int y = piece_pos.y+3; Uint16 piece = tetromino[current_piece].figure; for (int i=0; i<16; i++) { if (piece & 1) { board[y][x] = tetromino[current_piece].orig+1; } piece = piece >> 1; x--; if (x < piece_pos.x) { x = piece_pos.x+3; y--; } } piece_pos = {3, 0}; current_piece = next_piece; next_piece = starting[rand()%7]; } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_EVERYTHING); SDL_Window* sdlWindow = SDL_CreateWindow("TETRIS", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 576, SDL_WINDOW_SHOWN); SDL_Renderer* sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_PRESENTVSYNC); while(!should_exit) { while(SDL_PollEvent(&sdlEvent)) { if (sdlEvent.type == SDL_QUIT) { should_exit = true; break; } if (sdlEvent.type == SDL_KEYDOWN) { if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_RIGHT) { piece_pos.x++; if (!is_valid_move()) piece_pos.x--; } if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_LEFT) { piece_pos.x--; if (!is_valid_move()) piece_pos.x++; } if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_DOWN) { piece_pos.y++; if (!is_valid_move()) { piece_pos.y--; fix_piece(); } } if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_UP) { current_piece = tetromino[current_piece].next; if (!is_valid_move()) current_piece = tetromino[current_piece].prev; } } } SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); SDL_RenderClear(sdlRenderer); for (int y=0; y<18; y++) { for (int x=0; x<10; x++) { if (board[y][x] == 0) continue; SDL_Rect rect { 32*x, 32*y, 32, 32}; SDL_SetRenderDrawColor(sdlRenderer, colors[board[y][x]-1][0], colors[board[y][x]-1][1], colors[board[y][x]-1][2], 255); SDL_RenderFillRect(sdlRenderer, &rect); SDL_SetRenderDrawColor(sdlRenderer, colors[board[y][x]-1][0]/2, colors[board[y][x]-1][1]/2, colors[board[y][x]-1][2]/2, 255); SDL_RenderDrawRect(sdlRenderer, &rect); } } int x = piece_pos.x+3; int y = piece_pos.y+3; Uint16 piece = tetromino[current_piece].figure; for (int i=0; i<16; i++) { if (piece & 1) { SDL_Rect rect { 32*x, 32*y, 32, 32}; SDL_SetRenderDrawColor(sdlRenderer, colors[tetromino[current_piece].orig][0], colors[tetromino[current_piece].orig][1], colors[tetromino[current_piece].orig][2], 255); SDL_RenderFillRect(sdlRenderer, &rect); SDL_SetRenderDrawColor(sdlRenderer, colors[tetromino[current_piece].orig][0]/2, colors[tetromino[current_piece].orig][1]/2, colors[tetromino[current_piece].orig][2]/2, 255); SDL_RenderDrawRect(sdlRenderer, &rect); } piece = piece >> 1; x--; if (x < piece_pos.x) { x = piece_pos.x+3; y--; } } speed--; if (speed == 0) { speed = (20-level) * 3; piece_pos.y++; if (!is_valid_move()) { piece_pos.y--; fix_piece(); } } SDL_RenderPresent(sdlRenderer); } SDL_Quit(); return 0; }