Raylib Bubbles
C++11 Raylib bubble shooter game.
GameBoard Class Reference

Represents the game board and provides public methods to interact with it. More...

#include <board.hpp>

Classes

struct  BubbleCell
 Represents a bubble cell on the game board. More...
 
struct  BubbleEventVector
 Holds a vector of bubble events and the type of event that occurred. More...
 

Public Member Functions

 GameBoard (const size_t rows, const size_t cols)
 Constructor for the GameBoard class. More...
 
Getters for the board properties.
size_t getRows () const
 Getter for the number of rows in the game board. More...
 
size_t getCols () const
 Getter for the maximum number of columns in the game board (column amount alternates on row index). More...
 
size_t getColAlign (const size_t row) const
 Returns the number of columns in the game board on the requested row. More...
 
size_t getGridSize (const size_t nRows) const
 Returns the total number of cells of the game board. More...
 
Getters and setters for the board cells.
size_t get (const size_t row, const size_t col) const
 Getter for the hue of a bubble on the game board. More...
 
size_t getNbrs (const size_t row, const size_t col) const
 Getter for the number of neighbors of a bubble on the game board. More...
 
void set (const size_t row, const size_t col, const size_t hue)
 Sets the hue of a bubble at the specified location on the board. More...
 
Board sanity checks.
size_t count () const
 Returns the number of non-empty board cells. More...
 
bool oob (const size_t row, const size_t col) const
 Checks if a specific row and column are out of bounds. More...
 
Main board interactions and checks.
bool canAttach (const size_t row, const size_t col) const
 Checks if a bubble can be attached to a specific location on the board. More...
 
bool attach (const size_t row, const size_t col, const size_t hue)
 Attaches a bubble to a specific location on the board. More...
 
bool pop (const size_t row, const size_t col, const size_t matches=0)
 Pops same-colored bubbles starting from the specified cell on the board. More...
 
void dropFloating ()
 Drops floating bubbles on the board. More...
 
bool reachedBottom () const
 Checks if the board has a bubble in its lowest row. More...
 
bool update (const size_t row, const size_t col, const size_t hue, const size_t matches=0)
 Applies all transformations for a game loop iteration, while allowing for a new bubble to be attached. More...
 
void fill (const size_t hue)
 Fills the game board data structure. More...
 
Board events stack.
bool hasEvents () const
 Checks if the board has any event vectors that other modules might want to process. More...
 
BubbleEventVector popEventVec ()
 Pops and returns the first event vector from the board event list. More...
 

Detailed Description

Represents the game board and provides public methods to interact with it.

This class represents the game board, which is a hexagonal offset grid of bubbles. The board is setup as a 1D vector of BubbleCell objects, which contain the hue of the bubble and the number of neighbors it has. To work as a 1D vector, the board is indexed using a 2D coordinate system, with the at() method converting 2D coordinates to a 1D offset index.

The board provides methods to attach a bubble to it, pop bubbles, and drop floating bubbles. It also allows checking if a bubble can be attached to a specific location, checking if the board has reached the bottom, and updating the board with a new bubble, as well as to fill or clear the board.

Note
An important characteristic of the board is that it can have different numbers of columns in each row, which depends on the number of columns the board has been created with. The getColAlign() method is used to determine how many columns each row is allowed to have, but make sure to keep in mind that an even number of columns will cause every second row to have one less column at the end, while an odd number of columns does not!
Note
Some methods, such as attach(), pop(), and dropFloating(), return a boolean value indicating success. They might not accept the operation if it would result in an invalid board state. The update() method combines these three methods and returns the result of the attach() method, which can be conveniently used in a loop to update the board.
Warning
The at() method can throw an out of bounds exception in multiple places where an out of bounds set of arguments is requested. Use is internal only. In case an out of bounds check is needed, use the public oob() method instead, which will not throw an exception.
Todo:
The BubbleCell::neighbors variable is only used in the canAttach() method to quickly attach (check) bubbles, but I'm unsure if using neighbor logic is the best way to solve this problem, as persistent neighbor updating might perform worse than checking on the fly when attaching (check) is needed. Consider that on each call to canAttach(). the applyNbrs() method is called to update the neighbor states. This might result in worse performance.
See also
getColAlign(), GameActionMgr::ActionType::step()

Constructor & Destructor Documentation

◆ GameBoard()

GameBoard::GameBoard ( const size_t  rows,
const size_t  cols 
)
inline

Constructor for the GameBoard class.

Parameters
rowsThe number of rows in the game board.
colsThe number of columns in the game board.

This constructor initializes a GameBoard object with the given number of rows and columns. It also initializes the matches to pop, which is the number of same-hue bubbles required for a pop and is read from the configuration file, and the board by calculating the grid size as a 1D vector.

See also
GameUtils

Member Function Documentation

◆ attach()

bool GameBoard::attach ( const size_t  row,
const size_t  col,
const size_t  hue 
)

Attaches a bubble to a specific location on the board.

Parameters
rowThe row index to attach the bubble to.
colThe column index to attach the bubble to.
hueThe hue of the bubble to attach.

This method combines a call to set() with a check to canAttach(). The return value is from the latter, which will also decide whether to set the attaching bubble at the specified location.

Returns
True if the bubble was successfully attached, false otherwise.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.
See also
canAttach(), set()

◆ canAttach()

bool GameBoard::canAttach ( const size_t  row,
const size_t  col 
) const

Checks if a bubble can be attached to a specific location on the board.

Parameters
rowThe row index to check.
colThe column index to check.
Returns
True if a bubble can be attached to the location, false otherwise.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.

◆ count()

size_t GameBoard::count ( ) const

Returns the number of non-empty board cells.

Returns
The number of non-empty board cells.

◆ dropFloating()

void GameBoard::dropFloating ( )

Drops floating bubbles on the board.

This method drops floating bubbles on the board, which are bubbles that are not connected to the top of the board.

Todo:
I don't remember how I implemented this new refactor anymore... remember to come back for docs writing.

◆ fill()

void GameBoard::fill ( const size_t  hue)

Fills the game board data structure.

Parameters
hueThe hue to fill the board with, zero for clearing the board.

◆ get()

size_t GameBoard::get ( const size_t  row,
const size_t  col 
) const

Getter for the hue of a bubble on the game board.

Parameters
rowThe row of the bubble cell.
colThe column of the bubble cell.
Returns
The hue of the bubble, including zero for an empty cell.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.

◆ getColAlign()

size_t GameBoard::getColAlign ( const size_t  row) const

Returns the number of columns in the game board on the requested row.

Parameters
rowThe row to get the aligned number of columns for.

This method returns the number columns (cells) in a specific row, and is required because hexagonal grids have different numbers of columns in each row. There are two possible alignments:

  • If cols is an even number, the rows alternate between cols and cols - 1 columns (cells) in them.
  • If cols is an odd number, the rows all have cols columns (cells) in them.

Drawing shifted rows falls outside the scope of this method, but the correct number of columns (cells) is returned.

Returns
The number of columns in the game board on the requested row.

◆ getCols()

size_t GameBoard::getCols ( ) const

Getter for the maximum number of columns in the game board (column amount alternates on row index).

Returns
The maximum number of columns in the game board.
See also
getColAlign()

◆ getGridSize()

size_t GameBoard::getGridSize ( const size_t  nRows) const

Returns the total number of cells of the game board.

Parameters
nRowsThe number of rows we want to calculate the grid size for.

This method calculates the total number of cells in the game board for a given number of rows.

Returns
The total number of cells in the game board for the given number of rows.

◆ getNbrs()

size_t GameBoard::getNbrs ( const size_t  row,
const size_t  col 
) const

Getter for the number of neighbors of a bubble on the game board.

Parameters
rowThe row of the bubble cell.
colThe column of the bubble cell.
Returns
The number of neighbors the bubble has.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.

◆ getRows()

size_t GameBoard::getRows ( ) const

Getter for the number of rows in the game board.

Returns
The number of rows in the game board.

◆ hasEvents()

bool GameBoard::hasEvents ( ) const

Checks if the board has any event vectors that other modules might want to process.

Returns
True if there are events, false otherwise.

◆ oob()

bool GameBoard::oob ( const size_t  row,
const size_t  col 
) const

Checks if a specific row and column are out of bounds.

Parameters
rowThe row index to check.
colThe column index to check.
Note
This method will not throw an exception.
Returns
True if the row or column is out of bounds, false otherwise.

◆ pop()

bool GameBoard::pop ( const size_t  row,
const size_t  col,
const size_t  matches = 0 
)

Pops same-colored bubbles starting from the specified cell on the board.

Parameters
rowThe row index to pop the bubbles from.
colThe column index to pop the bubbles from.
matchesThe number of same-hue bubbles required to pop the bubble.

This method pops same-colored bubbles starting from the specified cell on the board.

Note
Internally, the method uses a depth-first search to explore the board and pop bubbles. It temporarily sets the hue of the bubbles to zero to mark them as popped, which can save time if the bubbles can actually be popped, instead of using a visited set (unsure about this).
Warning
The matches parameter defaults (or when set to zero) to the configuration file value MATCHES_TO_POP.
Returns
True if the bubbles were sufficient and successfully popped, false otherwise.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.

◆ popEventVec()

GameBoard::BubbleEventVector GameBoard::popEventVec ( )

Pops and returns the first event vector from the board event list.

Todo:
This is inefficiently making a copy of a vector instead of giving ownership (or is it? Check the move constructor?)
Returns
The first event vector in the list (by a copy of BubbleEventVector to keep the interface simple).
Exceptions
std::runtime_errorif the event vector list is empty.

◆ reachedBottom()

bool GameBoard::reachedBottom ( ) const

Checks if the board has a bubble in its lowest row.

Returns
True if it does, false otherwise.

◆ set()

void GameBoard::set ( const size_t  row,
const size_t  col,
const size_t  hue 
)

Sets the hue of a bubble at the specified location on the board.

Parameters
rowThe row index of the bubble.
colThe column index of the bubble.
hueThe new hue value to set for the bubble.

This method assigns a new hue value to the bubble located at the given row and column. It first checks if the current hue at the location is the same as the new hue to avoid unnecessary operations. If a change is needed, it updates the hue and then applies some logic to neighboring bubbles.

Note
The method applies additional logic to neighboring bubbles through applyNbrs, which may also depend on the at() method for accessing specific board positions.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.

◆ update()

bool GameBoard::update ( const size_t  row,
const size_t  col,
const size_t  hue,
const size_t  matches = 0 
)

Applies all transformations for a game loop iteration, while allowing for a new bubble to be attached.

Parameters
rowThe row index to attach the bubble to.
colThe column index to attach the bubble to.
hueThe hue of the bubble to attach.
matchesThe number of same-hue bubbles required to pop the bubble.

Combines calls to attach(), pop() and dropFloating(), while returning the result of attach(). This method is useful for updating the board in a loop, as it allows for a new bubble to be attached and the board to be updated accordingly, while also popping bubbles and dropping floating ones.

Since all these actions occur when a new bubble is attached, the combination method returns the result of the attach().

Warning
The matches parameter defaults (or when set to zero) to the configuration file value MATCHES_TO_POP.
Returns
True if the bubble was successfully attached, false otherwise.
Exceptions
std::out_of_rangeindirectly through the private at() method if the specified row or column is out of the board's bounds.
See also
attach(), pop(), dropFloating()

The documentation for this class was generated from the following files: