Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

You have already displayed the Tetris Bucket, started dropping the shapes, stopp

ID: 3841931 • Letter: Y

Question

You have already displayed the Tetris Bucket, started dropping the shapes, stopped them at the bottom of the Bucket, dropped another shape from the top, got the user input and moved/rotated the shape in response to the user input.

In this assignment, you need to:

Determine whether any of the rows are complete.

If a row is complete, remove that line and drop all the shapes above the line by one cell.

Compute and display the score.

Add plenty of narrative comments. Your program must be compilable and executable.

My current code:

#include "stdafx.h"
#include<iostream>
#include<windows.h>
#include<thread>
#include<chrono>
#include<conio.h>
#include<stdlib.h>
#include<time.h>

using namespace std;

class TetrisShape
{
public:
   char shapeArray[4][4];
   int shapeType;

   int shapeTopLeftX;
   int shapeTopLeftY;

   TetrisShape(int shapetype);
   TetrisShape();

   void setShape(int shapetype);
   bool moveShape(int input, int& newShapeTopLeftX, int& newShapeTopLeftY);
};

char bucket[25][13];
enum{ UP_ARROW = 72, DOWN_ARROW = 80, LEFT_ARROW = 75, RIGHT_ARROW = 77 };

void initializeBucket()
{
   int i, j;
   for (i = 0; i < 25; i++)
   {
       for (j = 0; j < 13; j++)
           bucket[i][j] = ' ';
       bucket[i][0] = '#';
       bucket[i][11] = '#';
   }

   for (i = 0; i < 12; i++)
       bucket[24][i] = '#';
}

void setCursorTo(int x, int y)//coordinate setup
{
   HANDLE handle;
   COORD position;
   handle = GetStdHandle(STD_OUTPUT_HANDLE);
   position.X = x;
   position.Y = y;
   SetConsoleCursorPosition(handle, position);
}
void displayBucket()//display bucket
{

   //for loop to display bucket
   for (int y = 0; y <25; y++)
   {
       setCursorTo(0, y);
       for (int j = 0; j < 12; j++)
           cout << bucket[y][j];
       cout << endl;
   }
}

void updateBucket(TetrisShape localTetrisShape)//update bucket
{
   int topX = localTetrisShape.shapeTopLeftX;
   int topY = localTetrisShape.shapeTopLeftY;

   for (int i = 0; i <4; i++)
   {
       for (int j = 0; j <4; j++)
       {
           if (localTetrisShape.shapeArray[i][j] != ' ')
               bucket[i + topY][j + topX] = localTetrisShape.shapeArray[i][j];
       }
   }
}

void clearOldShape(TetrisShape localTetrisShape)
{
   int topX = localTetrisShape.shapeTopLeftX;
   int topY = localTetrisShape.shapeTopLeftY;

   for (int i = 0; i <4; i++)
   {
       for (int j = 0; j <4; j++)
       {
           if (localTetrisShape.shapeArray[i][j] != ' ')
               bucket[i + topY][j + topX] = ' ';
       }
   }
}

bool stuckCheck(TetrisShape shape, int newTopX, int newTopY)//for collision detection
{
   for (int i = 0; i <4; i++)
   {
       for (int j = 0; j <4; j++)
       {
           if (shape.shapeArray[i][j] != ' ')
           {
               int y = newTopY + i;
               int x = newTopX + j;

               if (y < 0 || y >= 25)
                   return true;

               if (x < 0 || x >= 12)
                   return true;

               // inside bucket
               if (bucket[y][x] != ' ')
                   return true;
           }
       }
   }
   return false;
}

bool processDownArrow(TetrisShape& shape)
{
   if (stuckCheck(shape, shape.shapeTopLeftX, shape.shapeTopLeftY + 1))
       return true;
   shape.shapeTopLeftY += 1;
   return false;
}

void processLeftArrow(TetrisShape& shape)
{

   if (stuckCheck(shape, shape.shapeTopLeftX - 1, shape.shapeTopLeftY))
       return;
   shape.shapeTopLeftX -= 1;
}

void processRightArrow(TetrisShape& shape)
{
   if (stuckCheck(shape, shape.shapeTopLeftX + 1, shape.shapeTopLeftY))
       return;
   shape.shapeTopLeftX += 1;
}

int getUserInput()
{
   int key = 0;
   if (_kbhit())
   {
       key = _getch();
   }
   return key;
}

int checkFullRow()
{
   int i, j, k;
   int count = 0;
   for (i = 23; i >= 0; i--)
   {
       bool full = true;
       for (j = 1; j <= 10 && full; j++)
       {
           if (bucket[i][j] == ' ')
               full = false;
       }

       // if this row is full, remove this row
       if (full)
       {
           count++;
           for (k = i; k > 0; k--)
           {
               for (j = 1; j <= 10; j++)
                   bucket[k][j] = bucket[k - 1][j];
           }

           // fill blank at top
           for (j = 1; j <= 10; j++)
               bucket[0][j] = ' ';

           // check this row again
           i++;
       }
   }
   return count;
}

void inline timeControl(int timer)//call this timer at last in while loop of main function.
{
   Sleep(timer);
}

int main()
{
   srand(time(0)); // initialize the random seed

   int gameOver = 0;
   int shapeType = (rand() % 7) + 0;//Randomly generates a number and sends it to the constructor to choose shape with the 0 to 6 condition
   TetrisShape currentShape(shapeType);
   TetrisShape nextShape(rand() % 7);

   int newShapeTopLeftY;
   int newShapeTopLeftX;
   int input;
   bool reached = false;   // reach bottom
   int timeCount = 0;
   bool display = false;
   int score = 0;

   initializeBucket();

   updateBucket(currentShape);//updates and displays bucket
   displayBucket();

   while (gameOver == 0)//while to start game
   {
       clearOldShape(currentShape);

       input = getUserInput();
       display = false;
       reached = false;

       if (input == LEFT_ARROW || input == RIGHT_ARROW ||
           input == UP_ARROW || input == DOWN_ARROW)
       {
           reached = currentShape.moveShape(input, newShapeTopLeftX, newShapeTopLeftY);
           currentShape.shapeTopLeftY = newShapeTopLeftY;
           currentShape.shapeTopLeftX = newShapeTopLeftX;
           display = true;
       }

       timeCount++;
       if (timeCount == 100)
       {
           // every 2 seconds drop
           reached = currentShape.moveShape(0, newShapeTopLeftX, newShapeTopLeftY);
           currentShape.shapeTopLeftY = newShapeTopLeftY;
           currentShape.shapeTopLeftX = newShapeTopLeftX;
           display = true;
           timeCount = 0;
       }

       updateBucket(currentShape);

       if (reached)
       {
           int cnt = checkFullRow();
           if (cnt == 1)
               score += 10;
           else if (cnt == 2)
               score += 25;
           else if (cnt == 3)
               score += 40;
           else if (cnt == 4)
               score += 60;

           // create another
           currentShape.setShape(nextShape.shapeType);
           nextShape.setShape(rand() % 7);

           if (stuckCheck(currentShape, currentShape.shapeTopLeftX,
               currentShape.shapeTopLeftY))
           {
               gameOver = 1;
           }
           else
           {
               updateBucket(currentShape);//updates and displays bucket
               display = true;
           }
       }

       if (display)
       {
           displayBucket();
           setCursorTo(25, 0);
           cout << "Current Score: " << score << "     ";
       }

       //Sleeps for the game
       timeControl(20); // 20 mill seconds

   }

   system("PAUSE");
   return 0;
}


// Default constructor
TetrisShape::TetrisShape()
{
   shapeTopLeftX = 6;
   shapeTopLeftY = 0;
   shapeType = -1;
}
//Constructor for shape arrays
TetrisShape::TetrisShape(int shapetype)
{
   setShape(shapetype);
}

void TetrisShape::setShape(int shapetype)
{
   shapeType = shapetype;
   shapeTopLeftX = 6;
   shapeTopLeftY = 0;

   switch (shapetype)
   {
   case 0:
       //L Shape
       shapeArray[0][0] = ' '; shapeArray[1][0] = 'X'; shapeArray[2][0] = ' '; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = ' '; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = 'X'; shapeArray[2][2] = 'X'; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 1:
       //I Shape
       shapeArray[0][0] = ' '; shapeArray[1][0] = 'X'; shapeArray[2][0] = ' '; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = ' '; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = 'X'; shapeArray[2][2] = ' '; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = 'X'; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 2:
       //J Shape
       shapeArray[0][0] = ' '; shapeArray[1][0] = 'X'; shapeArray[2][0] = ' '; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = ' '; shapeArray[3][1] = ' ';
       shapeArray[0][2] = 'X'; shapeArray[1][2] = 'X'; shapeArray[2][2] = ' '; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 3:
       //O Shape
       shapeArray[0][0] = ' '; shapeArray[1][0] = ' '; shapeArray[2][0] = ' '; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = 'X'; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = 'X'; shapeArray[2][2] = 'X'; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 4:
       //T Shape
       shapeArray[0][0] = 'X'; shapeArray[1][0] = 'X'; shapeArray[2][0] = 'X'; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = ' '; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = ' '; shapeArray[2][2] = ' '; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 5:
       //S Shape
       shapeArray[0][0] = ' '; shapeArray[1][0] = 'X'; shapeArray[2][0] = 'X'; shapeArray[3][0] = ' ';
       shapeArray[0][1] = 'X'; shapeArray[1][1] = 'X'; shapeArray[2][1] = ' '; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = ' '; shapeArray[2][2] = ' '; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   case 6:
       //Z Shape
       shapeArray[0][0] = 'X'; shapeArray[1][0] = 'X'; shapeArray[2][0] = ' '; shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' '; shapeArray[1][1] = 'X'; shapeArray[2][1] = 'X'; shapeArray[3][1] = ' ';
       shapeArray[0][2] = ' '; shapeArray[1][2] = ' '; shapeArray[2][2] = ' '; shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' '; shapeArray[1][3] = ' '; shapeArray[2][3] = ' '; shapeArray[3][3] = ' ';
       break;
   }
}

// Return if reach bottom
bool TetrisShape::moveShape(int input, int& newShapeTopLeftX, int& newShapeTopLeftY)
{
   int i;
   int oldX = shapeTopLeftX;
   int oldY = shapeTopLeftY;
   bool reached = false;
   char tempCellVal;

   switch (input)
   {
   case UP_ARROW:
       // after rotation, sometimes we will have stuck
       // stop such rotate
       do
       {
           tempCellVal = shapeArray[0][0];
           shapeArray[0][0] = shapeArray[0][3];
           shapeArray[0][3] = shapeArray[3][3];
           shapeArray[3][3] = shapeArray[3][0];
           shapeArray[3][0] = tempCellVal;
           tempCellVal = shapeArray[0][1];
           shapeArray[0][1] = shapeArray[1][3];
           shapeArray[1][3] = shapeArray[3][2];
           shapeArray[3][2] = shapeArray[2][0];
           shapeArray[2][0] = tempCellVal;
           tempCellVal = shapeArray[0][2];
           shapeArray[0][2] = shapeArray[2][3];
           shapeArray[2][3] = shapeArray[3][1];
           shapeArray[3][1] = shapeArray[1][0];
           shapeArray[1][0] = tempCellVal;
           tempCellVal = shapeArray[1][1];
           shapeArray[1][1] = shapeArray[1][2];
           shapeArray[1][2] = shapeArray[2][2];
           shapeArray[2][2] = shapeArray[2][1];
           shapeArray[2][1] = tempCellVal;
       } while (stuckCheck(*this, shapeTopLeftX, shapeTopLeftY));

       break;
   case DOWN_ARROW:
       for (i = 0; i < 3 && !reached; i++)
           reached = processDownArrow(*this);
       break;
   case LEFT_ARROW:
       processLeftArrow(*this);
       break;
   case RIGHT_ARROW:
       processRightArrow(*this);
       break;
   default:
       reached = processDownArrow(*this);
       break;
   }

   // get the new position
   newShapeTopLeftX = shapeTopLeftX;
   newShapeTopLeftY = shapeTopLeftY;

   // recover current position to old
   shapeTopLeftX = oldX;
   shapeTopLeftY = oldY;

   return reached;
}

Explanation / Answer

Detecting The Complete Line in the Game

Step 1:

line = 4;                //check fourth line
isComplete = true;
for (var horizontal = 0; horizontal < landed[line].length; horizontal++) {
if (landed[line][horizontal] == 0) {
isComplete = false;
}
} // if isComplete is still true than line 4 is filled
              
              
Step 2:

for (var line = 0; horizontal < landed.length; line++) {
isComplete = true;
for (var horizontal = 0; horizontal < landed[line].length; horizontal++) {
if (landed[line][horizontal] == 0) {
isComplete = false;
}
}
//if isComplete is still true then current line is filled
}

Step 3:

We have two methods now

1. Naive Method

for (var row = 0; row < landed.length; row++) {
isComplete = true;
for (var horizontal = 0; horizontal < landed[row].length; horizontal++) {
if (landed[row][horizontal] == 0) {
isComplete = false;
}
}
//remove the filled line sub-array from the array
landed.splice(row, 1);   
//add a new empty line sub-array to the start of the array
landed.unshift([0,0,0,0,0,0,0,0,0,0]);
}

2.Big Clump Method

for (var line = 0; line < tetris.shape.length; line++) {
for (var horizontal = 0; horizontal < tetris.shape[line].length; horizontal++) {
if (tetris.shape[line][horizontal] != 0) {
if (line + tetris.potentialTopLeft.line >= landed.length)
           {
//This block would be situated below the playing ground
}
else if (landed[line + tetris.potentialTopLeft.line] != 0 &&
landed[horizontal + tetris.potentialTopLeft.horizontal] != 0) {
  
               //the space will be taken
}
}
}
}

This will be all to remove the completely filled row in the tetris game. Rate the answer if it helped.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote