Files
OHLGames/tetris.cpp
2020-11-20 06:53:03 +01:00

88 lines
4.4 KiB
C++

#include <SDL2/SDL.h>
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;
}