168 lines
5.3 KiB
C++
168 lines
5.3 KiB
C++
#pragma once
|
|
|
|
#include "../Pieces/Piece.h"
|
|
#include "Board.h"
|
|
#include "Bag.h"
|
|
#include "LineClear.h"
|
|
|
|
#include <vector>
|
|
#include <memory>
|
|
|
|
|
|
/**
|
|
* Links a board with the pieces moving in it
|
|
*/
|
|
class GameBoard {
|
|
private:
|
|
Board board; // the board in which pieces moves, (0, 0) is downleft
|
|
Bag generator; // the piece generator
|
|
std::shared_ptr<Piece> activePiece; // the piece currently in the board
|
|
Position activePiecePosition; // the position of the piece currently in the board
|
|
std::shared_ptr<Piece> heldPiece; // a piece being holded
|
|
int nextQueueLength; // the number of next pieces seeable at a time
|
|
std::vector<Piece> nextQueue; // the list of the next pieces to spawn in the board
|
|
bool isLastMoveKick; // wheter the last action the piece did was kicking
|
|
bool movedLeftLast; // wheter the last sideway movement was a left one
|
|
|
|
public:
|
|
/**
|
|
* Creates a new board, generator, and next queue
|
|
*/
|
|
GameBoard(int boardWidth, int boardHeight, const std::shared_ptr<PiecesList>& piecesList, int nextQueueLength);
|
|
|
|
/**
|
|
* Resets the board as if it was newly created
|
|
*/
|
|
void reset();
|
|
|
|
private:
|
|
/**
|
|
* Initializes the board
|
|
*/
|
|
void initialize();
|
|
|
|
public:
|
|
/**
|
|
* Tries moving the piece one position to the left
|
|
* @return If it suceeded
|
|
*/
|
|
bool moveLeft();
|
|
|
|
/**
|
|
* Tries moving the piece one position to the right
|
|
* @return If it suceeded
|
|
*/
|
|
bool moveRight();
|
|
|
|
/**
|
|
* Tries moving the piece one position down
|
|
* @return If it suceeded
|
|
*/
|
|
bool moveDown();
|
|
|
|
/**
|
|
* Tries rotating the piece and kicking it if necessary, if it's a 0° rotation, it will forcefully try kicking
|
|
* @return If it suceeded
|
|
*/
|
|
bool rotate(Rotation rotation);
|
|
|
|
private:
|
|
/**
|
|
* Tries kicking the piece, testing position either above or below the piece's initial position
|
|
* @return If it suceeded
|
|
*/
|
|
bool tryKicking(bool testingBottom, const std::set<Position>& safePositions);
|
|
|
|
/**
|
|
* Tries fitting the kicked active piece at the specified position
|
|
* @return If it suceeded
|
|
*/
|
|
bool tryFittingKickedPiece(const std::set<Position>& safePositions, const Position& shift, bool& overlaps);
|
|
|
|
/**
|
|
* Check if one of the active piece's positions shifted by a specified position would overlap with a set of positions
|
|
* @return If the shifted active piece overlaps with one of the position
|
|
*/
|
|
bool activePieceOverlaps(const std::set<Position>& safePositions, const Position& shift = Position{0, 0}) const;
|
|
|
|
public:
|
|
/**
|
|
* Tries holding the active piece or swapping it if one was already stocked, while trying to apply an initial rotation to the newly spawned piece
|
|
* @return If it suceeded
|
|
*/
|
|
bool hold(Rotation initialRotation = NONE);
|
|
|
|
/**
|
|
* Spawns the next piece from the queue
|
|
* @return If it spawned in a wall
|
|
*/
|
|
bool spawnNextPiece();
|
|
|
|
/**
|
|
* Checks if one of the active piece's positions touches a wall in the board
|
|
* @return If the active piece is in a wall
|
|
*/
|
|
bool activePieceInWall(const Position& shift = Position{0, 0}) const;
|
|
|
|
/**
|
|
* Checks is the active piece as a wall directly below one of its position
|
|
* @return If it touches a ground
|
|
*/
|
|
bool touchesGround() const;
|
|
|
|
/**
|
|
* Computes what the piece position would be if it were to be dropped down as much as possible
|
|
* @return The lowest position before hitting a wall
|
|
*/
|
|
Position lowestPosition() const;
|
|
|
|
/**
|
|
* Locks the active piece into the board and clears lines if needed
|
|
* @return The resulting line clear
|
|
*/
|
|
LineClear lockPiece();
|
|
|
|
/**
|
|
* Adds a specified number of garbage rows to the bottom of the board, the hole position being random but the same for all of them
|
|
*/
|
|
void addGarbageRows(int number);
|
|
|
|
/**
|
|
* @return The board
|
|
*/
|
|
const Board& getBoard() const;
|
|
|
|
/**
|
|
* @return A pointer to the active piece, can be null
|
|
*/
|
|
const std::shared_ptr<Piece>& getActivePiece() const;
|
|
|
|
/**
|
|
* @return The position of the active piece
|
|
*/
|
|
const Position& getActivePiecePosition() const;
|
|
|
|
/**
|
|
* @return A pointer to the held piece, can be null
|
|
*/
|
|
const std::shared_ptr<Piece>& getHeldPiece() const;
|
|
|
|
/**
|
|
* @return The next piece queue, can be empty
|
|
*/
|
|
const std::vector<Piece>& getNextPieces() const;
|
|
|
|
private:
|
|
/**
|
|
* Sets the active piece to its spawn position
|
|
*/
|
|
void goToSpawnPosition();
|
|
|
|
public:
|
|
/**
|
|
* Stream output operator, adds the board, the hold box and the next queue
|
|
* @return A reference to the output stream
|
|
*/
|
|
friend std::ostream& operator<<(std::ostream& os, const GameBoard& gameboard);
|
|
};
|