diff --git a/src/Core/Board.cpp b/src/Core/Board.cpp index ed9fca0..fae9891 100644 --- a/src/Core/Board.cpp +++ b/src/Core/Board.cpp @@ -8,9 +8,9 @@ Board::Board(int width, int height) : width(width), height(height) { - std::vector emptyRow; + std::vector emptyRow; for (int i = 0; i < width; i ++) { - emptyRow.push_back(NOTHING); + emptyRow.push_back(ColorEnum::NOTHING); } // initialize grid @@ -20,15 +20,15 @@ Board::Board(int width, int height) : width(width), height(height) { } } -void Board::addBlock(const Cell& position, Color block) { +void Board::addBlock(const Cell& position, ColorEnum block) { // if the block is out of bounds we discard it if (position.x < 0 || position.x >= this->width || position.y < 0) return; // resize the grid if needed if (position.y >= this->grid.size()) { - std::vector emptyRow; + std::vector emptyRow; for (int i = 0; i < width; i ++) { - emptyRow.push_back(NOTHING); + emptyRow.push_back(ColorEnum::NOTHING); } for (int j = this->grid.size(); j <= position.y; j++) { this->grid.push_back(emptyRow); @@ -40,9 +40,9 @@ void Board::addBlock(const Cell& position, Color block) { } int Board::clearRows() { - std::vector emptyRow; + std::vector emptyRow; for (int i = 0; i < width; i ++) { - emptyRow.push_back(NOTHING); + emptyRow.push_back(ColorEnum::NOTHING); } // check from top to bottom @@ -51,7 +51,7 @@ int Board::clearRows() { // check if a line has a block on every column bool isFull = true; for (int i = 0; i < this->width; i++) { - if (this->grid.at(j).at(i) == NOTHING) { + if (this->grid.at(j).at(i) == ColorEnum::NOTHING) { isFull = false; } } @@ -67,18 +67,20 @@ int Board::clearRows() { return clearedLines; } -Color Board::getBlock(const Cell& position) const { +ColorEnum Board::getBlock(const Cell& position) const { // if the block is out of bounds - if (position.x < 0 || position.x >= this->width || position.y < 0) return OUT_OF_BOUND; + if (position.x < 0 || position.x >= this->width || position.y < 0) + return ColorEnum::OUT_OF_BOUNDS; // if the block is higher than the current grid, since it can grow indefinitely we do as if it was there but empty - if (position.y >= this->grid.size()) return NOTHING; + if (position.y >= this->grid.size()) + return ColorEnum::NOTHING; // else get the color in the grid return this->grid.at(position.y).at(position.x); } -std::vector> Board::getBlocks() const { +std::vector> Board::getBlocks() const { return this->grid; } @@ -98,9 +100,9 @@ std::ostream& operator<<(std::ostream& os, const Board& board) { // print the board for (int y = board.grid.size() - 1; y >= 0; y--) { for (int x = 0; x < board.width; x++) { - Color block = board.grid.at(y).at(x); - os << COLOR_CODES[block]; - if (block != NOTHING) { + ColorEnum block = board.grid.at(y).at(x); + os << getColorCode(block); + if (block != ColorEnum::NOTHING) { os << "*"; } else { @@ -111,7 +113,7 @@ std::ostream& operator<<(std::ostream& os, const Board& board) { } // reset console color - os << COLOR_RESET; + os << getColorCode(ColorEnum::NOTHING); return os; } diff --git a/src/Core/Board.h b/src/Core/Board.h index 1c65170..daf5ce4 100644 --- a/src/Core/Board.h +++ b/src/Core/Board.h @@ -11,7 +11,7 @@ */ class Board { private: - std::vector> grid; // the grid, (0,0) is downleft + std::vector> grid; // the grid, (0,0) is downleft int width; // the width of the grid int height; // the base height of the grid, which can extends indefinitely @@ -24,7 +24,7 @@ class Board { /** * Change the color of the specified block, if the block is out of bounds it is simply ignored */ - void addBlock(const Cell& position, Color block); + void addBlock(const Cell& position, ColorEnum block); /** * Clears any complete row and moves down the rows on top, returns the number of cleared rows @@ -34,12 +34,12 @@ class Board { /** * Returns the color of the block at the specified position */ - Color getBlock(const Cell& position) const; + ColorEnum getBlock(const Cell& position) const; /** * Returns a copy of the grid */ - std::vector> getBlocks() const; + std::vector> getBlocks() const; /** * Returns the actual height of the grid diff --git a/src/Core/GameBoard.cpp b/src/Core/GameBoard.cpp index 4ffea4a..6902d4c 100644 --- a/src/Core/GameBoard.cpp +++ b/src/Core/GameBoard.cpp @@ -264,7 +264,8 @@ std::vector GameBoard::getNextPieces() const { bool GameBoard::isActivePieceInWall(const Cell& shift) const { // check if every cell of the active piece is in an empty spot for (Cell cell : this->activePiece->getPositions()) { - if (this->board.getBlock(cell + this->activePiecePosition + shift) != NOTHING) return true; + if (this->board.getBlock(cell + this->activePiecePosition + shift) != ColorEnum::NOTHING) + return true; } return false; } @@ -296,8 +297,8 @@ std::ostream& operator<<(std::ostream& os, const GameBoard& gameboard) { if (gameboard.activePiece != nullptr) { // change to the color of the active piece - Color pieceColor = gameboard.activePiece->getColor(); - os << COLOR_CODES[pieceColor]; + ColorEnum pieceColor = gameboard.activePiece->getColor(); + os << getColorCode(pieceColor); // print only the cell were the active piece is for (int y = gameboard.activePiecePosition.y + gameboard.activePiece->getLength() - 1; y >= gameboard.board.getBaseHeight(); y--) { @@ -315,22 +316,22 @@ std::ostream& operator<<(std::ostream& os, const GameBoard& gameboard) { } // print the board - Color pieceColor = (gameboard.activePiece == nullptr) ? NOTHING : gameboard.activePiece->getColor(); + ColorEnum pieceColor = (gameboard.activePiece == nullptr) ? ColorEnum::NOTHING : gameboard.activePiece->getColor(); for (int y = gameboard.board.getBaseHeight() - 1; y >= 0; y--) { for (int x = 0; x < gameboard.board.getWidth(); x++) { bool hasActivePiece = (gameboard.activePiece == nullptr) ? false : gameboard.activePiece->getPositions().contains(Cell{x, y} - gameboard.activePiecePosition); // if the active piece is on this cell, print it if (hasActivePiece) { - os << COLOR_CODES[pieceColor]; + os << getColorCode(pieceColor); os << "*"; } // else print the cell of the board else { - Color block = gameboard.board.getBlock(Cell{x, y}); - os << COLOR_CODES[block]; - if (block != NOTHING) { + ColorEnum block = gameboard.board.getBlock(Cell{x, y}); + os << getColorCode(block); + if (block != ColorEnum::NOTHING) { os << "*"; } else { @@ -354,7 +355,7 @@ std::ostream& operator<<(std::ostream& os, const GameBoard& gameboard) { } // reset console color - os << COLOR_RESET; + os << getColorCode(ColorEnum::NOTHING); return os; } diff --git a/src/Pieces/Color.cpp b/src/Pieces/Color.cpp new file mode 100644 index 0000000..d4433b7 --- /dev/null +++ b/src/Pieces/Color.cpp @@ -0,0 +1,38 @@ +#include "Color.h" + +static const Color C_NOTHING = {255, 255, 255}; +static const Color C_OUT_OF_BOUNDS = C_NOTHING; +static const Color C_GARBAGE = {150, 150, 150}; +static const Color C_PURPLE = {150, 0, 255}; +static const Color C_ORANGE = {255, 150, 0}; +static const Color C_CYAN = {0, 255, 0}; +static const Color C_PINK = {255, 0, 200}; +static const Color C_YELLOW = {255, 255, 0}; +static const Color C_RED = {255, 0, 0}; +static const Color C_BLUE = {0, 100, 255}; +static const Color C_GREEN = {0, 255, 0}; + +static const Color colors[] = { + C_NOTHING, + C_OUT_OF_BOUNDS, + C_GARBAGE, + C_PURPLE, + C_ORANGE, + C_CYAN, + C_PINK, + C_YELLOW, + C_RED, + C_BLUE, + C_GREEN +}; + +const Color& getColor(ColorEnum color) { + return colors[color]; +} + +void setNextPieceColor(ColorEnum& color) { + if (color == ColorEnum::GREEN) + color = ColorEnum::PURPLE; + else + color = ColorEnum(color + 1); +} \ No newline at end of file diff --git a/src/Pieces/Color.h b/src/Pieces/Color.h index a915ada..5bdc243 100644 --- a/src/Pieces/Color.h +++ b/src/Pieces/Color.h @@ -5,9 +5,9 @@ /** * Every possible colors a block can take */ -enum Color { +enum ColorEnum { NOTHING, - OUT_OF_BOUND, + OUT_OF_BOUNDS, GARBAGE, PURPLE, ORANGE, @@ -19,32 +19,30 @@ enum Color { GREEN }; +struct Color { + std::uint8_t r; + std::uint8_t g; + std::uint8_t b; +}; /** * Returns the first color a piece can take */ -inline Color firstPieceColor() { - return Color(PURPLE); +inline ColorEnum firstPieceColor() { + return ColorEnum::PURPLE; } +const Color& getColor(ColorEnum color); + /** * Sets the color to the next available piece color */ -inline void nextPieceColor(Color& color) { - color = (color == GREEN) ? PURPLE : Color(color + 1); +void setNextPieceColor(ColorEnum& color); + +inline std::string getColorCode(const Color& color) { + return "\033[38;2;" + std::to_string(color.r) + ";" + std::to_string(color.g) + ";" + std::to_string(color.b) + "m"; } -static const std::string COLOR_RESET = "\033[38;2;255;255;255m"; // color code to reset the console color -static const std::string COLOR_CODES[] = { // color codes to change the console color - COLOR_RESET, // NOTHING - COLOR_RESET, // OUT_OF_BOUND - "\033[38;2;150;150;150m", // GARBAGE - "\033[38;2;150;0;255m", // PURPLE - "\033[38;2;255;150;0m", // ORANGE - "\033[38;2;0;255;255m", // CYAN - "\033[38;2;255;0;200m", // PINK - "\033[38;2;255;255;0m", // YELLOW - "\033[38;2;255;0;0m", // RED - "\033[38;2;0;100;255m", // BLUE - "\033[38;2;0;255;0m" // GREEN -}; +inline std::string getColorCode(ColorEnum color) { + return getColorCode(color); +} \ No newline at end of file diff --git a/src/Pieces/Piece.cpp b/src/Pieces/Piece.cpp index ec4aa19..59b64fc 100644 --- a/src/Pieces/Piece.cpp +++ b/src/Pieces/Piece.cpp @@ -8,7 +8,7 @@ #include -Piece::Piece(const Polyomino& polyomino, Color color) : polyomino(polyomino), color(color) { +Piece::Piece(const Polyomino& polyomino, ColorEnum color) : polyomino(polyomino), color(color) { } void Piece::rotate(Rotation rotation) { @@ -28,11 +28,11 @@ int Piece::getLength() const { return this->polyomino.getLength(); } -Color Piece::getColor() const { +ColorEnum Piece::getColor() const { return this->color; } std::ostream& operator<<(std::ostream& os, const Piece& piece) { - os << COLOR_CODES[piece.color] << piece.polyomino << COLOR_RESET; + os << getColorCode(piece.color) << piece.polyomino << getColorCode(NOTHING); return os; } diff --git a/src/Pieces/Piece.h b/src/Pieces/Piece.h index c1ae83f..f724189 100644 --- a/src/Pieces/Piece.h +++ b/src/Pieces/Piece.h @@ -13,13 +13,13 @@ class Piece { private: Polyomino polyomino; // a polyomino representing the piece, (0, 0) is downleft - Color color; // the color of the piece + ColorEnum color; // the color of the piece public: /** * Creates a piece with a specified shape and color */ - Piece(const Polyomino& piece, Color color); + Piece(const Polyomino& piece, ColorEnum color); /** * Rotates the piece in the specified direction @@ -39,7 +39,7 @@ class Piece { /** * Returns the color of the piece */ - Color getColor() const; + ColorEnum getColor() const; /** * Stream output operator, adds a 2D grid representing the piece diff --git a/src/Pieces/PiecesFiles.cpp b/src/Pieces/PiecesFiles.cpp index da4b78d..f24a95f 100644 --- a/src/Pieces/PiecesFiles.cpp +++ b/src/Pieces/PiecesFiles.cpp @@ -38,8 +38,9 @@ bool PiecesFiles::savePieces(int order) const { std::sort(nMinos.begin(), nMinos.end()); // write pieces - Color pieceColor = firstPieceColor(); - for (int i = 0; i < order; i++) nextPieceColor(pieceColor); + ColorEnum pieceColor = firstPieceColor(); + for (int i = 0; i < order; i++) + setNextPieceColor(pieceColor); for (const Polyomino& nMino : nMinos) { // write polyomino length char lengthByte = nMino.getLength(); @@ -47,7 +48,7 @@ bool PiecesFiles::savePieces(int order) const { // write the type and color of the piece char infoByte = (nMino.isConvex() << 7) + (nMino.hasHole() << 6) + pieceColor; - nextPieceColor(pieceColor); + setNextPieceColor(pieceColor); piecesFile.write(&infoByte, 1); // write the cells of the piece @@ -96,7 +97,7 @@ bool PiecesFiles::loadPieces(int order, std::vector& pieces, std::vector< piecesFile.get(infoByte); bool isConvex = (infoByte & convexMask) >> 7; bool hasHole = (infoByte & holeMask) >> 6; - Color color = Color(infoByte & colorMask); + ColorEnum color = ColorEnum(infoByte & colorMask); // read cells std::set pieceCells;