Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <thread>
- #include <chrono>
- #include <math.h>
- struct Vector{int x, y;};
- struct Console{
- Vector size;
- private:
- char* screen;
- HANDLE hConsole;
- DWORD bytesWritten;
- public:
- Console(int x, int y);
- ~Console();
- void sleep(int time);
- void clear();
- void draw(int x, int y, char c);
- void draw(int x, int y, const char* str, int size);
- void display();
- };
- Console console(120, 40);
- Vector fieldSize{30, 25};
- char field[25 * 30];
- Vector fieldPos{10,3};
- std::string shapes[7] =
- {
- "..#."
- "..#."
- "..#."
- "..#.",
- "...."
- ".##."
- ".##."
- "....",
- "...."
- "..#."
- "..#."
- ".##.",
- "...."
- ".#.."
- ".#.."
- ".##.",
- "...."
- "..##"
- ".##."
- "....",
- "...."
- "##.."
- ".##."
- "....",
- "...."
- ".#.."
- "###."
- "...."
- };
- std::string curShape, nextShape;
- Vector curPos{fieldSize.x/2 - 2, 1}, nextPos{50, 10};
- int score = 0;
- std::string rotate(const std::string& shape);
- void drawField();
- void drawShape();
- bool isShapeColliding();
- void updateField();
- void resetShape();
- void displayScore();
- void displayCredits(int x);
- char wallCharacter = '\xDB';
- void start()
- {
- console.clear();
- srand(time(NULL));
- nextShape = shapes[rand()%7];
- score = 0;
- for(int i = 0; i < fieldSize.x; i++){
- field[(fieldSize.y - 1)*fieldSize.x + i] = '\xDB';
- }
- for(int i = 0; i < fieldSize.y; i++){
- field[i*fieldSize.x] = '\xDB'; field[(i+1)*fieldSize.x - 1] = '\xDB';
- }
- for(int i = 1; i < fieldSize.y - 1; i++)
- for(int j = 1; j < fieldSize.x - 1; j++)
- field[i*fieldSize.x + j] = 0;
- resetShape();
- int fallSpeed = 10, moveSpeed = 2, quickFallSpeed = 5;
- int fallCounter = 0, moveCounter = 0, quickFallCounter = 0;
- int level = 1, levelCounter = 0;
- bool isRunning = true;
- while(isRunning){
- console.sleep(50);
- if(GetAsyncKeyState(VK_ESCAPE))isRunning = false;
- fallCounter++;
- if(fallCounter == fallSpeed){
- fallCounter = 0;
- curPos.y++;
- if(isShapeColliding()){
- moveCounter = 0;
- curPos.y--;
- updateField();
- resetShape();
- isRunning = !isShapeColliding();
- }
- }
- moveCounter++;
- if(moveCounter == moveSpeed){
- moveCounter = 0;
- if(GetAsyncKeyState(VK_DOWN)){
- curPos.y++;
- if(isShapeColliding())curPos.y--;
- }
- else if(GetAsyncKeyState(VK_LEFT)){
- curPos.x--;
- if(isShapeColliding())curPos.x++;
- }
- else if(GetAsyncKeyState(VK_RIGHT)){
- curPos.x++;
- if(isShapeColliding())curPos.x--;
- }
- else if(GetAsyncKeyState(VK_SHIFT)){
- std::string s = rotate(curShape), t = curShape;
- curShape = s;
- if(isShapeColliding())curShape = t;
- }
- }
- quickFallCounter++;
- if(quickFallCounter == quickFallSpeed){
- quickFallCounter = 0;
- if(GetAsyncKeyState(VK_SPACE)){
- while(!isShapeColliding())curPos.y++;
- curPos.y--;
- fallCounter = 0;
- moveCounter = 0;
- updateField();
- resetShape();
- isRunning = !isShapeColliding();
- }
- }
- console.clear();
- displayCredits(80);
- drawShape();
- drawField();
- displayScore();
- console.display();
- }
- }
- int main()
- {
- bool isRunning = true;
- Vector tet[5] = {{0,0}, {0,-5}, {0,-10}, {0,-15}, {0,-20}};
- int index = 0;
- int counter = 0;
- tet[0].x = rand()%24;
- while(isRunning){
- console.sleep(100);
- counter++;
- if(counter == 5){
- counter = 0;
- index++;
- if(index == 5)index = 0;
- tet[index].x = rand()%24;
- tet[index].y = 0;
- }
- console.clear();
- for(int i = 0; i < 5; i++){
- if(tet[i].y >=0 )console.draw(tet[i].x, tet[i].y, "TETRIS", 6);
- tet[i].y++;
- }
- displayCredits(50);
- if(GetAsyncKeyState(VK_RETURN))isRunning = false;
- console.display();
- }
- bool gameOver = false;
- if(!isRunning){
- start();
- gameOver = true;
- }
- while(gameOver){
- console.sleep(50);
- if(GetAsyncKeyState(VK_ESCAPE))gameOver = false;
- else if(GetAsyncKeyState(VK_RETURN))start();
- console.draw(50, 25, "GAME OVER!", 10);
- console.draw(45, 27, "Press Enter To Restart.", 23);
- displayScore();
- console.display();
- }
- }
- std::string rotate(const std::string& shape)
- {
- std::string s = "................";
- for(int i = 0; i < 16; i++){
- int x = i%4;
- int y = i/4;
- s[i] = shape[12 + y - 4*x];
- }
- return s;
- }
- void displayCredits(int x)
- {
- console.draw(x, 10, "MADE BY : MUKUL SINGH", 21);
- console.draw(x, 11, "May 7/8 2021", 12);
- console.draw(x, 13, "In Game Controls :", 18);
- console.draw(x, 14, "Left : LEFT ARROW", 17);
- console.draw(x, 15, "Right : RIGHT ARROW", 19);
- console.draw(x, 16, "Down : DOWN ARROW", 17);
- console.draw(x, 17, "Fall : SPACE", 12);
- console.draw(x, 18, "Rotate : SHIFT", 14);
- console.draw(x, 19, "Exit : ESCAPE", 13);
- }
- void resetShape()
- {
- curShape = nextShape;
- nextShape = shapes[rand()%7];
- curPos = {fieldSize.x/2 - 2, 1};
- }
- void updateField()
- {
- for(int i = 0; i < 16; i++){
- int fi = (curPos.y + i/4) * fieldSize.x + curPos.x + i%4;
- if(curShape[i] == '#')field[fi] = '\xDB';
- }
- int score_count = 0;
- for(int i = 1; i < fieldSize.y-1; i++){
- bool line = true;
- for(int j = 1; j < fieldSize.x-1 && line; j++){
- line = field[i*fieldSize.x + j] == '\xDB';
- }
- if(line){
- score_count++;
- for(int _i = i; _i > 0; _i--){
- for(int j = 1; j < fieldSize.x-1; j++){
- field[_i*fieldSize.x + j] = field[(_i-1)*fieldSize.x + j];
- }
- }
- }
- }
- if(score_count)score += (log2(score_count) + 1) * (500);
- }
- void displayScore()
- {
- console.draw(50, 20, "SCORE :", 7);
- std::string str = std::to_string(score);
- console.draw(58, 20, str.c_str(), str.size());
- }
- bool isShapeColliding()
- {
- for(int i = 0; i < 16; i++){
- int fi = (curPos.y + i/4) * fieldSize.x + curPos.x + i%4;
- if(curShape[i] == '#' && field[fi] == '\xDB')return true;
- }
- return false;
- }
- void drawShape()
- {
- for(int i = 0; i < 16; i++){
- if(curShape[i] == '#')
- console.draw(fieldPos.x + curPos.x + i%4, fieldPos.y + curPos.y + i/4, curShape[i]);
- if(nextShape[i] == '#')
- console.draw(i%4 + nextPos.x,i/4 + nextPos.y, nextShape[i]);
- }
- console.draw(nextPos.x, nextPos.y-1, "NEXT SHAPE :", 12);
- }
- void drawField()
- {
- for(int i = 0; i < fieldSize.y * fieldSize.x; i++){
- if(field[i])console.draw(i%fieldSize.x + fieldPos.x, i/fieldSize.x + fieldPos.y, field[i]);
- }
- }
- Console::Console(int x, int y)
- {
- size = {x, y};
- screen = new char[size.x * size.y];
- hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
- SetConsoleActiveScreenBuffer(hConsole);
- bytesWritten = 0;
- }
- Console::~Console()
- {
- delete screen;
- }
- void Console::sleep(int time)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(time));
- }
- void Console::clear()
- {
- for(int i = 0; i < size.x; i++){
- for(int j = 0; j < size.y; j++){
- screen[i*size.y + j] = ' ';
- }
- }
- }
- void Console::draw(int x, int y, char c){
- screen[y*size.x + x] = c;
- }
- void Console::draw(int x, int y, const char* str, int size)
- {
- for(int i = 0; i < size; i++){
- console.draw(x + i, y, str[i]);
- }
- }
- void Console::display()
- {
- screen[size.x*size.y - 1] = '\0';
- WriteConsoleOutputCharacter(hConsole, screen, size.x * size.y, {0, 0}, &bytesWritten);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement