Files
jminos/src/Core/GameBoard.h
2025-03-01 20:27:36 +01:00

155 lines
4.7 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
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
* @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);
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 is the active piece as a wall directly below one of its position
* @return If it touches a ground
*/
bool touchesGround();
/**
* 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 A copy of the board
*/
Board getBoard() const;
/**
* @return A copy of the active piece
*/
Piece getActivePiece() const;
/**
* @return A copy of the position of the active piece
*/
Position getActivePiecePosition() const;
/**
* @return A copy of the held piece
*/
Piece getHeldPiece() const;
/**
* @return A copy of the next piece queue
*/
std::vector<Piece> getNextPieces() const;
private:
/**
* 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 isActivePieceInWall(const Position& shift = Position{0, 0}) const;
/**
* 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 activePieceOverlapsOnePosition(const std::set<Position>& safePositions, const Position& shift = Position{0, 0}) const;
/**
* 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);
};