biquadris / block.h
block.h
Raw
/*
    Block class module
    
    stores information of the Shapes of blocks, the rotation
	orientation (version), the position (pivots bottom left), and other state of
	the Block (dropped, activeCells, level)
*/

#ifndef _BLOCK_H_
#define _BLOCK_H_

#include "subject.h"
#include "subscriptions.h"
#include <vector>
#include <memory>

class Board;
class Cell;
class Shapes;

class InvalidPlacement {};

class Block : public Subject {
	int activeCells, level, version;
	int pivotRow, pivotCol, boardWidth, boardHeight;
	bool dropped;
	char type;
	std::unique_ptr<Shapes> theShape;
	Board *theBoard;

	static int NUM_SHAPES;
	// withinBoard, filled, and isItself are helper functions for validation of
	//	movement or generation of Block
	bool withinBoard(int row, int col);
	bool filled(int row, int col);
	bool isItself(int row, int col);
	bool validate(int version, int pivotRow, int pivotCol);

	void draw(int row, int col); // fills the cell at row, col with this block
	void erase(int row, int col); // erases the cell at row, col with this block

	// weightDown(currPivotRow, currPivotCol, currVersion, weight)
	// 	calculates the number of downward movement caused by weight
	int weightDown(int currPivotRow, int currPivotCol, int currVersion, int weight);

	// applyToShape(func()) applies the block with the function that 
	// 	may change the state of the Block
	void applyToShape(void (Block::*func)(int, int));

	// changeOnBoard(newPivotRow, newPivotCol, newVersion) changes the state of 
	// 	the Block on the Board
	void changeOnBoard(int newPivotRow, int newPivotCol, int newVersion);
	void initBlock();
	public:
		Block(int level, Board *b, Cell *c, char type, int version = 0);
		~Block();
		bool isDropped() const noexcept;
		
		int getPivotRow() const noexcept;
		int getPivotCol() const noexcept;
		int getVersion() const noexcept;
		char getType() const noexcept;
		int getLevel() const noexcept;
		int getBoardId() const noexcept;
		int getHeight() const noexcept;
		int getActiveCells() const noexcept;

		void move(char direction, int step, int weight = 0);
		void rotate(bool isClockwise, int amount, int weight = 0);
		void drop(int currPivotRow, int currPivotCol, int currVersion);
		void eraseOnBoard(); // erases the Block on the Board

		void decreaseActiveCell();
};

#endif