continuation of assignment

class SimpleTetris; class TetrisBucket; // ========================================================================== // A tetris piece type (one of the 7 pieces) // ========================================================================== class TetrisPieceType { public:

// The shape index int Index; // Definition of shape (4x4 for each of 4 rotations) bool Shape[4][4][4]; // Colour of the shape Paintbrush ShapeColour; }; // ========================================================================== // A single tetris piece (usually the current or next piece) // ========================================================================== class TetrisShape { // Pointer to renderer Simple2D *renderer; // Reference to bucket (game board) TetrisBucket *bucket; public:

// The piece layout TetrisPieceType Piece; // Current rotation of this shape (0-3) int CurrentRotation; // Hypothetical position of the top-left corner of the 4x4 shape in the bucket int PosX, PosY; // Defaults TetrisShape() : PosX(0), PosY(0), CurrentRotation(-1) {} // Set the shape and its default settings void SetShape(TetrisPieceType &); // One-time setup inline void Init(Simple2D *r, TetrisBucket *b) { renderer = r; bucket = b; } // Returns true if the shape has been set, false otherwise inline bool HasShape() { return (CurrentRotation != -1); } // Move the piece if no collision occurs void MoveLeft(); void MoveRight(); bool MoveDown(); void MoveToBottom(); void Rotate(); // Activate the piece (bring it into play) void Activate(); // Draw the piece void Draw(bool = false); void Draw(int, int); // Move the piece if enough time has expired, based on the current level number // Return true if the piece can go no further bool Update(int); // Get the width and height in blocks of a piece inline int GetWidth() { return lastUsedColumn() - firstUsedColumn() + 1; } inline int GetHeight() { return lastUsedRow() - firstUsedRow() + 1; } private:

// Returns true if a particular row has part of the object in it 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]); } // Returns true if a particular column has part of the object in it 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]); } // Returns the index of the first row in the bounding box that the piece occupies int firstUsedRow() { int row = 0; while (!isObjectInRow(row)) row++; return row; } // Returns the index of the last row in the bounding box that the piece occupies int lastUsedRow() { int row = 3; while (!isObjectInRow(row)) row--; return row; } // Returns the index of the first column in the bounding box that the piece occupies int firstUsedColumn() { int col = 0; while (!isObjectInColumn(col)) col++; return col; } // Returns the index of the last column in the bounding box that the piece occupies int lastUsedColumn() { int col = 3; while (!isObjectInColumn(col)) col--; return col; } // Collision detection bool isAtTop(); bool isAtBottom(); bool isAtLeft(); bool isAtRight(); // Timer for moving the piece downwards // This stores the TickCount of when the piece was last moved int LastMoveTime; }; // ========================================================================== // The game board // ========================================================================== class TetrisBucket { // Pointer to renderer SimpleTetris *renderer; // Colour to draw bucket Paintbrush bucketBrush; public:

// First time setup (not per game) void Init(SimpleTetris *r); // Makes the bucket empty void Reset(); // Drawing resources void SetupResources(); // Draw the bucket void Draw(); // Add a shape to the bucket, remove compete lines, update score and level void Add(TetrisShape &, int &score, int &linesCleared, int &level); // Check if a piece would collide with the contents of the bucket bool IsCollision(TetrisShape *); // Bucket size static int const BucketSizeX = 10; static int const BucketSizeY = 20; // Bucket co-ordinates (top left corner) static int TopSide; static int LeftSide; // Bucket line thickness static int const BucketWidth = 10; private:

// The bucket contents (game board) // (Shape type from 0-6, or -1 if blank) int board[BucketSizeY][BucketSizeX]; }; // ========================================================================== // The game controller (application class) // ========================================================================== class SimpleTetris : public Simple2D { public:

// Block size in pixels static int BlockSize; // Number of shapes in Tetris static int const numShapeTypes = 7; // Each piece type TetrisPieceType Pieces[numShapeTypes]; // Lines cleared per level static int const LinesPerLevel = 20; // Constructor SimpleTetris(); private:

// Callbacks bool SetupResources(); void ReleaseResources(); void UpdateObjects(); void OnKeyPress(WPARAM); void DrawScene(); // Colour to draw next shape box Paintbrush nextBoxBrush; // Text formats and their colours for different things TextFormat textFormat; Paintbrush textBrush; TextFormat scoreFormat; Paintbrush scoreBrush; TextFormat gameOverFormat; Paintbrush gameOverBrush; // The current shape being dropped TetrisShape currentShape; // The next shape to drop TetrisShape nextShape; // Bucket contents (game board) TetrisBucket bucket; // 0 for menu, 1 for playing, 2 for game over int gameState; // Current level in the game (controls speed at which pieces drop) int level; // Current score int score; // Current lines cleared int linesCleared; // Set up new game void newGame(); // Move to next piece void newPiece(); }; int TetrisBucket::TopSide = 0; int TetrisBucket::LeftSide = 0; int SimpleTetris::BlockSize = 0;