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

Hi, I am working on tetris project and I am having problem with my code program

ID: 3769653 • Letter: H

Question

Hi,

I am working on tetris project and I am having problem with my code program and I was wondering if someone could help me compile it with no error.

I can someone help me create a good functioning tetris game that can show the score and that can make the user rotate the blocks and build up the blocks properly all the way top of the gride line??

#include "stdafx.h"
#include <iostream>
#include "windows.h"
#include <ctime>


using namespace std;

using namespace std;

//console width height
const int WIDTH = 400;
const int HEIGHT = 400;

//bucket row and column size
const int buckHeight = 25;
const int buckWidth = 12;

//bucket array
char bucket[buckHeight][buckWidth];


void initializeBucket();
void displayBucket();
void setCursorTo(int x, int y);
void userInput();
void moveShape();
void shapeDrop();
void clearRow();
void score();
void beginGame();
void endGame();

int main()
{
   int score = 0;
   char playAgain;
   //this is my working game loop, keeps replaying until n is entered
   cout << " Welcome to Tetris!!! Would you like to play? (y/n): ";
   cin >> playAgain;
   while ((playAgain != 'y') && (playAgain != 'n'))
   {
       cout << " Please enter y or n: ";
       cin >> playAgain;
   }
   if (playAgain == 'y')
   {
       //rand for shape
       srand(static_cast<unsigned int>(time(0)));
       int shapeType = rand() % 7;

       while (playAgain == 'y')
       {

           displayBucket();
           setCursorTo(0, 0);
           beginGame();
           cout << " Would you like to play again? (y/n): ";
           cin >> playAgain;
           while ((playAgain != 'y') && (playAgain != 'n'))
           {
               cout << " Please enter y or n: ";
               cin >> playAgain;
           }
       }
   }
   else


       system("pause");
   return 0;
}
void setCursorTo(int x, int y)
{
   HANDLE handle;
   COORD position;
   handle = GetStdHandle(STD_OUTPUT_HANDLE);
   position.X = x;
   position.Y = y;
   SetConsoleCursorPosition(handle, position);
}
void beginGame()
{
   //this function calls the gameplay functions
   //each function here is what keeps the shapes moving and user playing

   userInput();
   moveShape();
   shapeDrop();
   clearRow();
   endGame();
}
void displayBucket()
{
   setCursorTo(0, 1);

   initializeBucket();

   for (int i = 0; i < buckHeight; i++) {
       for (int j = 0; j < buckWidth; j++) {
           cout << bucket[i][j];

           if (j == 11) cout << endl;
       }
   }
}
void initializeBucket()
{
   for (int i = 0; i < buckHeight; i++) {
       for (int j = 0; j < buckWidth; j++) {


           if (j == 0 || j == 11 || i == 24) {
               bucket[i][j] = '#';
           }
           else if (bucket[i][j] == 'X') {
               continue;
           }
           else {
               bucket[i][j] = ' ';
           }

       }
   }

}
class TetrisShape {
public:
   int shapeTopLeftX;
   int shapeTopLeftY;
   TetrisShape() {
       shapeTopLeftX = 6;
       shapeTopLeftY = 0;
   }
   char shapeArray[4][4];
   void populateShapeArray(int shapeType) {
       switch (shapeType) {
       case 1:
           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 2:
           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 3:
           shapeArray[0][0] = ' '; shapeArray[1][0] = 'X'; shapeArray[2][0] = 'X'; 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;
       case 4:
           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 5:
           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;
       case 6:
           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;
       }
   }
};

void userInput(char shapeType)
{
   char shapeArray[4][4];
   char mvDir; // Move Direction
               //user presses keys to flip/move shape
   cout << " User moves shape" << endl;
   cout << "Please enter move direction: L = left, R = right, U = Up, D = Down ";
   cin >> mvDir;
   switch (mvDir) {
   case 'L':
       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 'R':
       shapeArray[0][0] = ' ';shapeArray[1][0] = ' ';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] = 'X';shapeArray[2][2] = 'X';shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' ';shapeArray[1][3] = ' ';shapeArray[2][3] = ' ';shapeArray[3][3] = ' ';
       break;

   case 'U':
       shapeArray[0][0] = ' ';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] = 'X';shapeArray[2][2] = ' ';shapeArray[3][2] = ' ';
       shapeArray[0][3] = ' ';shapeArray[1][3] = ' ';shapeArray[2][3] = ' ';shapeArray[3][3] = ' ';
       break;

   case 'D':
       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] = ' ';shapeArray[2][3] = 'X';shapeArray[3][3] = ' ';
       break;
   } // end of switch

}
void moveShape(int shapeType)
{
   char shapeArray[4][4];
   //shape reacts to user input
   cout << " Computer moves shape according to user request" << endl;
   int mvDir; // Move Direction
               //user presses keys to flip/move shape
   cout << "Please enter move direction: 1 = Up & left, 2 = Up & right, 3 = Down & Left, 4 = Down & Right";
   cin >> mvDir;
   switch (mvDir) {
   case '1':
       shapeArray[0][0] = ' ';shapeArray[1][0] = ' ';shapeArray[2][0] = ' ';shapeArray[3][0] = 'X';
       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 '2':
       shapeArray[0][0] = ' ';shapeArray[1][0] = ' ';shapeArray[2][0] = 'X ';shapeArray[3][0] = ' ';
       shapeArray[0][1] = ' ';shapeArray[1][1] = 'X';shapeArray[2][1] = ' ';shapeArray[3][1] = 'X';
       shapeArray[0][2] = ' ';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':
       shapeArray[0][0] = ' ';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] = 'X';shapeArray[1][3] = ' ';shapeArray[2][3] = ' ';shapeArray[3][3] = ' ';
       break;

   case '4':
       shapeArray[0][0] = ' ';shapeArray[1][0] = 'X';shapeArray[2][0] = ' ';shapeArray[3][0] = 'X';
       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] = ' ';shapeArray[2][3] = ' ';shapeArray[3][3] = ' ';
       break;
   } // end of switch


}
void shapeDrop()
{
   char shapeArray[4][4];
   //when shape drops on bottom and stops
   cout << " Shape drops to bottom" << endl;
   shapeArray[0][0] = ' ';shapeArray[1][0] = ' ';shapeArray[2][0] = ' ';shapeArray[3][0] = ' ';
   shapeArray[0][1] = ' ';shapeArray[1][1] = ' ';shapeArray[2][1] = ' ';shapeArray[3][1] = ' ';
   shapeArray[0][2] = ' ';shapeArray[1][2] = ' ';shapeArray[2][2] = ' ';shapeArray[3][2] = ' ';
   shapeArray[0][3] = 'X';shapeArray[1][3] = 'X';shapeArray[2][3] = 'X';shapeArray[3][3] = 'X';

}
void clearRow()
{
   char shapeArray[4][4];
   //when a row is filled, will clear and score
   cout << " A row is filled, it clears" << endl;
   shapeArray[0][0] = ' ';shapeArray[1][0] = ' ';shapeArray[2][0] = ' ';shapeArray[3][0] = ' ';
   shapeArray[0][1] = ' ';shapeArray[1][1] = ' ';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] = ' ';

   score();
}
void score()
{
   //calculates score
   int score;
   cout << " Add to score" << endl;
   score++;
}

void endGame()
{
   //when shape hits top, clear screen and display/save score
   cout << " Clear screen and save score" << endl;
   clearRow();
   cout << " Score = " << score;
}

Explanation / Answer

Answer :

SimpleGameSample.h

class SimpleTetris;
class TetrisBucket;

class TetrisPieceType
{
public:
  
   int Index;

  
   bool Shape[4][4][4];

  
   Paintbrush ShapeColour;
};

class TetrisShape
{
  
   SimpleGameSample *renderer;

  
   TetrisBucket *bucket;

public:
  
   TetrisPieceType Piece;

  
   int CurrentRotation;

  
   int PosX, PosY;


   TetrisShape() : PosX(0), PosY(0), CurrentRotation(-1) {}

  
   void SetShape(TetrisPieceType &);

  
   inline void Init(SimpleGame Sample *r, TetrisBucket *b)
   {
       renderer = r;
       bucket = b;
   }

  
   inline bool HasShape()
   {
       return (CurrentRotation != -1);
   }
  
  
   void MoveLeft();
   void MoveRight();
   bool MoveDown();
   void MoveToBottom();
   void Rotate();
   void Activate();


   void Draw(bool = false);
   void Draw(int, int);

  
   bool Update(int);

  
   inline int GetWidth()
   {
       return lastUsedColumn() - firstUsedColumn() + 1;
   }

   inline int GetHeight()
   {
       return lastUsedRow() - firstUsedRow() + 1;
   }

private:
  
   inline bool isObjectInRow(int row)
   {
       return (Piece.Shape[CurrentRotation][row][0] || Piece.Shape[CurrentRotation][row][1] || Piece.Shape[CurrentRotation][row][2] || Piece.Shape[CurrentRotation][row][3]);
   }

  
   inline bool isObjectInColumn(int col)
   {
       return (Piece.Shape[CurrentRotation][0][col] || Piece.Shape[CurrentRotation][1][col] || Piece.Shape[CurrentRotation][2][col] || Piece.Shape[CurrentRotation][3][col]);
   }

  
   int firstUsedRow()
   {
       int row = 0;
       while (!isObjectInRow(row))
           row++;

       return row;
   }

  
   int lastUsedRow()
   {
       int row = 3;
       while (!isObjectInRow(row))
           row--;

       return row;
   }

  
   int firstUsedColumn()
   {
       int col = 0;
       while (!isObjectInColumn(col))
           col++;

       return col;
   }


   int lastUsedColumn()
   {
       int col = 3;
       while (!isObjectInColumn(col))
           col--;

       return col;
   }

  
   bool isAtTop();
   bool isAtBottom();
   bool isAtLeft();
   bool isAtRight();

   int LastMoveTime;
};

class TetrisBucket
{
  
   SimpleTetris *renderer;

  
   Paintbrush bucketBrush;

public:
  
   void Init(SimpleTetris *r);

  
   void Reset();

  
   void keepResources();


   void Draw();

  
   void Add(TetrisShape &, int &score, int &linesCleared, int &level);

  
   bool IsCollision(TetrisShape *);

  
   static int const BucketSizeX = 10;
   static int const BucketSizeY = 20;

  
   static int TopSide;
   static int LeftSide;

  
   static int const BucketWidth = 10;

private:
  
   int board[BucketSizeY][BucketSizeX];
};


class SimpleTetris : public SimpleGameSample
{
public:
  
   static int BlockSize;

  
   static int const numShapeTypes = 7;


   TetrisPieceType Pieces[numShapeTypes];

  
   static int const LinesPerLevel = 20;

  
   SimpleTetris();

private:
  
   bool keepResources();
   void quitResources();
   void UpdateObjects();
   void OnKeyPress(WPARAM);
   void DisplayScene();

  
   Paintbrush nextBoxBrush;

  
   TextFormat textFormat;
   Paintbrush textBrush;

   TextFormat scoreFormat;
   Paintbrush scoreBrush;

   TextFormat gameOverFormat;
   Paintbrush gameOverBrush;

  
   TetrisShape currentShape;
   TetrisShape nextShape;
  

   TetrisBucket bucket;

  
   int gameState;

  
   int level;

   int score;

  
   int linesCleared;

  
   void modernGame();

  
   void modernPiece();
};

int TetrisBucket::TopSide = 0;
int TetrisBucket::LeftSide = 0;
int SimpleTetris::BlockSize = 0;

SampleTetris.cpp

#include <SimpleGameSample.h>
#include "SampleTetris.h"
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iomanip>


void TetrisShape::SetShape(TetrisPieceType &piece)
{
  
   Piece = piece;

  
   CurrentRotation = 0;

  
   PosX = (TetrisBucket::BucketSizeX - 4) / 2;

  
   PosY = -firstUsedRow();
}

void TetrisShape::Activate()
{
   LastMoveTime = GetTickCount();
}


bool TetrisShape::Update(int level)
{
   bool finished = false;

  

   unsigned int lifetime = 1000 - ((level - 1) * 50);

   if (GetTickCount() >= LastMoveTime + lifetime)
   {
       LastMoveTime = GetTickCount();
       finished = MoveDown();
   }

   return finished;
}


void TetrisShape::Draw(bool ignoreBucketHeight)
{

   if (!HasShape())
       return;

   for (int y = PosY; y < PosY + 4; y++)
   {
      
       if ((y < 0 || y >= TetrisBucket::BucketSizeY) && !ignoreBucketHeight) continue;

       for (int x = PosX; x < PosX + 4; x++)
       {
          
           if (x < 0 || x >= TetrisBucket::BucketSizeX) continue;

          
           if (Piece.Shape[CurrentRotation][y - PosY][x - PosX])
               renderer->FillRectangle(TetrisBucket::LeftSide + x * SampleTetris::BlockSize,
                                       TetrisBucket::TopSide + y * SampleTetris::BlockSize,
                                       TetrisBucket::LeftSide + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                       TetrisBucket::TopSide + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                       Piece.ShapeColour);
       }
   }
}


void TetrisShape::Draw(int sx, int sy)
{
   int fx = firstUsedColumn();
   int lx = lastUsedColumn();
   int fy = firstUsedRow();
   int ly = lastUsedRow();

   int rows = lx - fx + 1;
   int cols = ly - fy + 1;

   for (int py = fy, y = 0; py <= ly; py++, y++)
       for (int px = fx, x = 0; px <= lx; px++, x++)
           if (Piece.Shape[CurrentRotation][py][px])
               renderer->FillRectangle(sx + x * SampleTetris::BlockSize,
                                       sy + y * SampleTetris::BlockSize,
                                       sx + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                       sy + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                       Piece.ShapeColour);
}


inline bool TetrisShape::isAtTop()
{
   return (PosY + firstUsedRow() == 0);
}

inline bool TetrisShape::isAtBottom()
{
   return (PosY + lastUsedRow() == TetrisBucket::BucketSizeY - 1);
}

inline bool TetrisShape::isAtLeft()
{
   return (PosX + firstUsedColumn() == 0);
}

inline bool TetrisShape::isAtRight()
{
   return (PosX + lastUsedColumn() == TetrisBucket::BucketSizeX - 1);
}
void TetrisShape::MoveLeft()
{
  
   if (!isAtLeft())
   {
       PosX--;

      
       if (bucket->IsCollision(this))
           PosX++;
   }
}

void TetrisShape::MoveRight()
{
  
   if (!isAtRight())
   {
       PosX++;

      
       if (bucket->IsCollision(this))
           PosX--;
   }
}


bool TetrisShape::MoveDown()
{
   bool collision = isAtBottom();

   if (!collision)
   {
       PosY++;

       collision = bucket->IsCollision(this);

       if (collision)
           PosY--;
   }

   return collision;
}

void TetrisShape::MoveToBottom()
{
  
   while (!MoveDown());
}

void TetrisShape::Rotate()
{

   bool atTop = isAtTop();
   bool atBottom = isAtBottom();
   bool atLeft = isAtLeft();
   bool atRight = isAtRight();

   int firstRow = firstUsedRow();
   int lastRow = lastUsedRow();
   int firstCol = firstUsedColumn();
   int lastCol = lastUsedColumn();


   int previousRotation = CurrentRotation;
   int previousX = PosX;
   int previousY = PosY;


   CurrentRotation = (CurrentRotation + 1) % 4;

  

   if (atTop)
       PosY -= firstUsedRow() - firstRow;

   if (atBottom)
       PosY -= lastUsedRow() - lastRow;

  
   if (atLeft)
       PosX -= firstUsedColumn() - firstCol;

   if (atRight)
       PosX -= lastUsedColumn() - lastCol;

  
   if (bucket->IsCollision(this))
   {
       PosX = previousX;
       PosY = previousY;
       CurrentRotation = previousRotation;
   }
}


void TetrisBucket::Init(SampleTetris *r)
{
   renderer = r;

  
   LeftSide = (renderer->ResolutionX - SampleTetris::BlockSize * BucketSizeX) / 2;
   TopSide = (renderer->ResolutionY - SampleTetris::BlockSize * BucketSizeY) / 2;
}


void TetrisBucket::Reset()
{
   for (int y = 0; y < BucketSizeY; y++)
       for (int x = 0; x < BucketSizeX; x++)
           board[y][x] = -1;
}


void TetrisBucket::Add(TetrisShape &s, int &score, int &linesCleared, int &level)
{
  
  
   for (int y = 0; y < 4; y++)
       for (int x = 0; x < 4; x++)
           board[s.PosY + y][s.PosX + x] = (s.Piece.Shape[s.CurrentRotation][y][x]? s.Piece.Index : board[s.PosY + y][s.PosX + x]);

  
   int newFills = 0;

   for (int y = 0, fills = 0; y < BucketSizeY; y++, fills = 0)
   {
       for (int x = 0; x < BucketSizeX; x++)
           if (board[y][x] != -1)
               fills++;

       if (fills == BucketSizeX)
       {
           newFills++;

          
           for (int nx = 0; nx < BucketSizeX; nx++)
               board[y][nx] = -1;

           for (int ny = y; ny >= 1; ny--)
               for (int nx = 0; nx < BucketSizeX; nx++)
                   board[ny][nx] = board[ny - 1][nx];

          
           for (int nx = 0; nx < BucketSizeX; nx++)
               board[0][nx] = -1;
       }
   }

  
   if (linesCleared / SampleTetris::LinesPerLevel < (linesCleared + newFills) / SampleTetris::LinesPerLevel)
       level++;

  
   linesCleared += newFills;

   if (newFills == 1) score += 10;
   if (newFills == 2) score += 50;
   if (newFills == 3) score += 200;
   if (newFills == 4) score += 1000;
}


bool TetrisBucket::IsCollision(TetrisShape *s)
{
   bool collision = false;

  
   for (int y = (s->PosY >= 0? 0 : -s->PosY); y < 4 && !collision; y++)
       for (int x = 0; x < 4 && !collision; x++)
           if (board[s->PosY + y][s->PosX + x] != -1
               && s->Piece.Shape[s->CurrentRotation][y][x])
               collision = true;

   return collision;
}


void TetrisBucket::keepResources()
{
  
  
   bucketBrush = renderer->MakeBrush(Colour::CornflowerBlue);
}


void TetrisBucket::Draw()
{
   renderer->SetBrush(bucketBrush);

  
   renderer->FillRectangle(LeftSide - BucketWidth, TopSide, LeftSide, TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);

  
   renderer->FillRectangle(LeftSide + BucketSizeX * SampleTetris::BlockSize,
                           TopSide,
                           LeftSide + BucketSizeX * SampleTetris::BlockSize + BucketWidth,
                           TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);

  
   renderer->FillRectangle(LeftSide,
                           TopSide + BucketSizeY * SampleTetris::BlockSize,
                           LeftSide + BucketSizeX * SampleTetris::BlockSize,
                           TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);

  
   for (int y = 0; y < BucketSizeY; y++)
       for (int x = 0; x < BucketSizeX; x++)
           if (board[y][x] != -1)
           {
               renderer->FillRectangle(   LeftSide + x * SampleTetris::BlockSize,
                                           TopSide + y * SampleTetris::BlockSize,
                                           LeftSide + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                           TopSide + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
                                           renderer->Pieces[board[y][x]].ShapeColour);
           }
}


SampleTetris::SampleTetris()
{
  
   srand(static_cast<unsigned int>(time(NULL)));

  
  
   bool shapetypes[7][4][4][4] = {
       {
          
           {
               { 0, 0, 0, 0 },
               { 1, 1, 1, 1 },
               { 0, 0, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 1, 1, 1, 1 },
               { 0, 0, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 }
           }
       },

       {
      
           {
               { 0, 0, 0, 0 },
               { 1, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 1, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 0, 0 },
               { 0, 0, 0, 0 }
           }
       },

       {
          
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 1, 1, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 1, 1, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 1, 0 },
               { 0, 0, 0, 0 }
           }
       },

       {
          
           {
               { 0, 0, 0, 0 },
               { 0, 1, 0, 0 },
               { 1, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 1, 1, 1, 0 },
               { 0, 1, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 1, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 0, 0, 0 }
           }
       },

       {
          
           {
               { 0, 0, 0, 0 },
               { 0, 0, 1, 0 },
               { 1, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 1, 1, 1, 0 },
               { 1, 0, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 1, 0 },
               { 0, 0, 1, 0 },
               { 0, 0, 1, 0 },
               { 0, 0, 0, 0 }
           }
       },

       {
          
           {
               { 0, 0, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 1, 1 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 1, 1, 0 },
               { 0, 1, 0, 0 },
               { 0, 1, 0, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 1 },
               { 0, 0, 0, 1 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 1, 0 },
               { 0, 0, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           }
       },

       {
          
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           },
           {
               { 0, 0, 0, 0 },
               { 0, 1, 1, 0 },
               { 0, 1, 1, 0 },
               { 0, 0, 0, 0 }
           }
       }
   };

  
   for (int i = 0; i < numShapeTypes; i++)
   {
       Pieces[i].Index = i;

       for (int u = 0; u < 4; u++)
           for (int v = 0; v < 4; v++)
               for (int w = 0; w < 4; w++)
                   Pieces[i].Shape[u][v][w] = shapetypes[i][u][v][w];
   }
   BlockSize = 18;


   bucket.Init(this);

  
   currentShape.Init(this, &bucket);
   nextShape.Init(this, &bucket);

  
   scoreFormat = NULL;

  
   gameState = 0;
}

bool SampleTetris::keepResources()
{
   if (scoreFormat == NULL)
   {
      
       textFormat = MakeTextFormat(L"Courier New", 18.0f, DWRITE_FONT_WEIGHT_BOLD);
       scoreFormat = MakeTextFormat(L"Verdana", 24.0f);
       gameOverFormat = MakeTextFormat(L"Courier New", 64.0f, DWRITE_FONT_WEIGHT_BOLD);
   }

  
   textBrush = MakeBrush(Colour::Snow);
   scoreBrush = MakeBrush(Colour::CornflowerBlue);
   gameOverBrush = MakeBrush(Colour::DarkRed);

  
   Pieces[0].ShapeColour = MakeBrush(Colour::Blue);
   Pieces[1].ShapeColour = MakeBrush(Colour::LightBlue);
   Pieces[2].ShapeColour = MakeBrush(Colour::LightSeaGreen);
   Pieces[3].ShapeColour = MakeBrush(Colour::Yellow);
   Pieces[4].ShapeColour = MakeBrush(Colour::Red);
   Pieces[5].ShapeColour = MakeBrush(Colour::Azure);
   Pieces[6].ShapeColour = MakeBrush(Colour::Violet);

  
   nextBoxBrush = MakeBrush(Colour::White);

   bucket.keepResources();

   return true;
}

void SampleTetris::quitResources()
{
   for (int i = 0; i < numShapeTypes; i++)
       SafeRelease(&Pieces[i].ShapeColour);
}

void SampleTetris::UpdateObjects()
{
  
   if (gameState == 2)
       return;

  
   if (gameState == 0)
   {
       gameState = 1;
       newGame();
   }

   if (currentShape.Update(level))
   {
       newPiece();
   }
}

void SampleTetris::OnKeyPress(WPARAM key)
{
   if (gameState != 1)
       return;

   if (currentShape.HasShape())
   {
       if (key == VK_LEFT)
           currentShape.MoveLeft();

       if (key == VK_RIGHT)
           currentShape.MoveRight();

       if (key == VK_DOWN)
           currentShape.MoveDown();

       if (key == VK_UP)
       {
           currentShape.MoveToBottom();
           newPiece();
       }

       if (key == VK_CONTROL)
           currentShape.Rotate();
   }
}

void SampleTetris::DisplayScene()
{
  
   if (gameState != 0)
   {
      
       bucket.Draw();

      
       currentShape.Draw((gameState == 2));

      
       DrawRectangle(   ResolutionX - 50 - BlockSize * 6,   50,
                       ResolutionX - 50,                   50 + BlockSize * 4,
                       nextBoxBrush);

      
       int nw = nextShape.GetWidth();
       int nh = nextShape.GetHeight();
       nextShape.Draw(ResolutionX - 50 - BlockSize * 6 + (BlockSize * 6 - nw * BlockSize) / 2,
                   50 + (BlockSize * 4 - nh * BlockSize) / 2);

  
       Text(50, 60, "Score", textFormat, textBrush);
       Text(50, 140, "Lines Cleared", textFormat, textBrush);
       Text(50, 220, "Level", textFormat, textBrush);

       std::stringstream s, l, lv;
       s << std::setw(6) << std::setfill('0') << score;
       l << linesCleared;
       lv << level;

       Text(50, 75, s.str(), scoreFormat, scoreBrush);
       Text(50, 155, l.str(), scoreFormat, scoreBrush);
       Text(50, 235, lv.str(), scoreFormat, scoreBrush);
   }

  
   if (gameState == 2)
   {
       gameOverFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
       Text(0, 200, "EPIC FAIL", gameOverFormat, gameOverBrush);
   }
}


void SampleTetris::modernGame()
{
   int shapeNum;

  
   shapeNum = rand() % numShapeTypes;
   currentShape.SetShape(Pieces[shapeNum]);
   currentShape.Activate();

   shapeNum = rand() % numShapeTypes;
   nextShape.SetShape(Pieces[shapeNum]);

  
   level = 1;

  
   score = 0;
  
  
   linesCleared = 0;

  
   bucket.Reset();
}

void SampleTetris::modernPiece()
{
  
   bucket.Add(currentShape, score, linesCleared, level);

  
   currentShape = nextShape;
   currentShape.Activate();

  
   int shapeNum = rand() % numShapeTypes;
   nextShape.SetShape(Pieces[shapeNum]);

  
   if (bucket.IsCollision(&currentShape))
   {
  
       gameState = 2;

      
       while (bucket.IsCollision(&currentShape))
           currentShape.PosY--;
   }
}

void Simple2DStart()
{
   SampleTetris tetris;
   tetris.SetWindowName(L"SampleTetris by Katy Coe (c) 2012");
   tetris.SetResolution(640, 480);
   tetris.SetBackgroundColour(Colour::Black);
   tetris.SetResizableWindow(false);

   tetris.Run();
}

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