meilleurs coms ig

This commit is contained in:
2025-03-03 22:34:46 +01:00
parent d029589c21
commit 2fbe4a6052
13 changed files with 56 additions and 78 deletions

View File

@@ -11,23 +11,19 @@
Bag::Bag(const std::shared_ptr<PiecesList>& piecesList) : Bag::Bag(const std::shared_ptr<PiecesList>& piecesList) :
piecesList(piecesList) { piecesList(piecesList) {
// initialize bags
this->currentBag = this->piecesList->getSelectedPieces(); this->currentBag = this->piecesList->getSelectedPieces();
this->nextBag.clear(); this->nextBag.clear();
// prepare first piece
this->prepareNext(); this->prepareNext();
} }
void Bag::jumpToNextBag() { void Bag::jumpToNextBag() {
// if the bag is empty switch to the next bag if (this->currentBag.size() < this->nextBag.size()) {
if (this->currentBag.empty()) {
std::swap(this->currentBag, this->nextBag); std::swap(this->currentBag, this->nextBag);
} }
// get the already used pieces back to the current bag
for (const std::pair<int, int>& pieceIndex : this->nextBag) { for (const std::pair<int, int>& pieceIndex : this->nextBag) {
this->currentBag.emplace_back(pieceIndex); this->currentBag.push_back(pieceIndex);
} }
this->nextBag.clear(); this->nextBag.clear();
} }
@@ -37,27 +33,21 @@ Piece Bag::lookNext() {
} }
Piece Bag::getNext() { Piece Bag::getNext() {
// get the piece to return
std::pair<int, int> nextIndex = this->next; std::pair<int, int> nextIndex = this->next;
// prepare the piece even after the next
this->prepareNext(); this->prepareNext();
// return the next piece
return this->piecesList->getPiece(nextIndex); return this->piecesList->getPiece(nextIndex);
} }
void Bag::prepareNext() { void Bag::prepareNext() {
// if the bag is empty switch to the next bag
if (this->currentBag.empty()) { if (this->currentBag.empty()) {
std::swap(this->currentBag, this->nextBag); std::swap(this->currentBag, this->nextBag);
} }
// pick a random piece from the current bag
int indexIndex = std::rand() % this->currentBag.size(); int indexIndex = std::rand() % this->currentBag.size();
this->next = this->currentBag.at(indexIndex); this->next = this->currentBag.at(indexIndex);
// move the piece over to the next bag
this->nextBag.push_back(this->next); this->nextBag.push_back(this->next);
this->currentBag.erase(this->currentBag.begin() + indexIndex); this->currentBag.erase(this->currentBag.begin() + indexIndex);
} }

View File

@@ -20,7 +20,6 @@ Board::Board(int width, int height) :
} }
void Board::changeBlock(const Position& position, Block block) { void Board::changeBlock(const Position& position, Block block) {
// if the block is out of bounds we discard it
if (position.x < 0 || position.x >= this->width || position.y < 0) return; if (position.x < 0 || position.x >= this->width || position.y < 0) return;
// resize the grid if needed // resize the grid if needed
@@ -62,7 +61,7 @@ int Board::clearRows() {
if (lineIsFull) { if (lineIsFull) {
this->grid.erase(this->grid.begin() + j); this->grid.erase(this->grid.begin() + j);
if(this->grid.size() < height) { if(this->grid.size() < this->height) {
this->grid.push_back(this->emptyRow); this->grid.push_back(this->emptyRow);
} }
clearedLines++; clearedLines++;
@@ -74,7 +73,7 @@ int Board::clearRows() {
void Board::clearBoard() { void Board::clearBoard() {
this->grid.clear(); this->grid.clear();
for (int j = 0; j < height; j++) { for (int j = 0; j < this->height; j++) {
this->grid.push_back(this->emptyRow); this->grid.push_back(this->emptyRow);
} }
} }

View File

@@ -230,17 +230,14 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
return; return;
} }
} }
// update remembered actions for next frame this->heldActions = playerActions;
if ((!this->started) || this->leftARETime > 0) { if ((!this->started) || this->leftARETime > 0) {
for (Action action : playerActions) { for (Action action : playerActions) {
this->initialActions.insert(action); this->initialActions.insert(action);
} }
}
this->heldActions = playerActions;
if (this->leftARETime > 0) {
if (playerActions.contains(MOVE_LEFT)) { if (playerActions.contains(MOVE_LEFT)) {
this->heldDAS = std::min(-1, this->heldDAS - 1); this->heldDAS = std::min(-1, this->heldDAS - 1);
} }

View File

@@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <memory> #include <memory>
#include <utility>
#include <cstdlib> #include <cstdlib>
@@ -150,7 +151,6 @@ bool GameBoard::tryKicking(bool testingBottom, const std::set<Position>& safePos
} }
} }
// do the same on the left side
if (overlapsLeft) { if (overlapsLeft) {
Position shift{-i, j}; Position shift{-i, j};
if (!this->activePieceOverlaps(safePositions, shift)) { if (!this->activePieceOverlaps(safePositions, shift)) {
@@ -220,7 +220,6 @@ bool GameBoard::hold(Rotation initialRotation) {
this->heldPiece->defaultRotation(); this->heldPiece->defaultRotation();
// this piece has done nothing yet
this->isLastMoveKick = false; this->isLastMoveKick = false;
return true; return true;
@@ -232,8 +231,6 @@ bool GameBoard::spawnNextPiece() {
this->nextQueue.erase(this->nextQueue.begin()); this->nextQueue.erase(this->nextQueue.begin());
this->goToSpawnPosition(); this->goToSpawnPosition();
// this piece has done nothing yet
this->isLastMoveKick = false; this->isLastMoveKick = false;
return this->activePieceInWall(); return this->activePieceInWall();

View File

@@ -12,7 +12,6 @@ GameParameters::GameParameters(Gamemode gamemode, const Player& controls) :
} }
void GameParameters::reset() { void GameParameters::reset() {
// initialize lines and level
this->clearedLines = 0; this->clearedLines = 0;
switch (this->gamemode) { switch (this->gamemode) {
// lowest gravity // lowest gravity
@@ -26,17 +25,14 @@ void GameParameters::reset() {
default : this->level = 1; default : this->level = 1;
} }
// initialize stats
this->updateStats(); this->updateStats();
} }
void GameParameters::clearLines(int lineNumber) { void GameParameters::clearLines(int lineNumber) {
// update lines and level
switch (this->gamemode) { switch (this->gamemode) {
// modes where level increases // modes where level increases
case MARATHON : case MARATHON :
case MASTER : { case MASTER : {
// update cleared lines
int previousLines = this->clearedLines; int previousLines = this->clearedLines;
this->clearedLines += lineNumber; this->clearedLines += lineNumber;

View File

@@ -10,9 +10,8 @@
Menu::Menu() { Menu::Menu() {
this->piecesList = std::make_shared<PiecesList>(PiecesList()); this->piecesList = std::make_shared<PiecesList>(PiecesList());
// default board size this->boardWidth = DEFAULT_BOARD_WIDTH;
this->boardHeight = 20; this->boardHeight = DEFAULT_BOARD_HEIGHT;
this->boardWidth = 10;
} }
Game Menu::startGame(Gamemode gamemode) const { Game Menu::startGame(Gamemode gamemode) const {

View File

@@ -4,7 +4,9 @@
#include "Player.h" #include "Player.h"
#include "Game.h" #include "Game.h"
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the game were choosen with this number in mind static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the game were choosen with this number in mind
static const int DEFAULT_BOARD_WIDTH = 10; // the default width of the board when starting the menu
static const int DEFAULT_BOARD_HEIGHT = 20; // the default height of the board when starting the menu
/** /**

View File

@@ -1,12 +1,5 @@
#include "Player.h" #include "Player.h"
static const int DAS_MIN_VALUE = 0; // 0ms
static const int DAS_MAX_VALUE = 30; // 500ms
static const int ARR_MIN_VALUE = 0; // 0ms
static const int ARR_MAX_VALUE = 30; // 500ms
static const int SDR_MIN_VALUE = 0; // 0ms
static const int SDR_MAX_VALUE = 6; // 100ms
Player::Player() { Player::Player() {
// default settings // default settings

View File

@@ -1,5 +1,12 @@
#pragma once #pragma once
static const int DAS_MIN_VALUE = 0; // the minimal selectable DAS value, equals to 0ms
static const int DAS_MAX_VALUE = 30; // the maximal selectable DAS value, equals to 500ms
static const int ARR_MIN_VALUE = 0; // the minimal selectable ARR value, equals to 0ms
static const int ARR_MAX_VALUE = 30; // the maximal selectable ARR value, equals to 500ms
static const int SDR_MIN_VALUE = 0; // the minimal selectable SDR value, equals to 0ms
static const int SDR_MAX_VALUE = 6; // the maximal selectable SDR value, equals to 100ms
/** /**
* The controls of a player * The controls of a player

View File

@@ -18,7 +18,7 @@ std::vector<Polyomino> Generator::generatePolyominos(int polyominoSize) {
// a polyomino has at least 1 square // a polyomino has at least 1 square
if (polyominoSize < 1) return this->validPolyominos; if (polyominoSize < 1) return this->validPolyominos;
// start generating from the monomino // always place the first cell at (0, 0)
this->currentTestedShape.insert(Position{0, 0}); this->currentTestedShape.insert(Position{0, 0});
std::map<Position, int> candidatePositions; std::map<Position, int> candidatePositions;
@@ -57,7 +57,7 @@ void Generator::generate(int polyominoSize, int lastAddedPositionNumber, int nex
this->tryToAddCandidatePosition(Position{position.x - 1, position.y}, nextAvaibleNumber, candidatePositions); this->tryToAddCandidatePosition(Position{position.x - 1, position.y}, nextAvaibleNumber, candidatePositions);
} }
// generate polyominos for all positions with a higher number than the last one // try adding a square only to positions with a higher number than the last one
for (auto [key, val] : candidatePositions) { for (auto [key, val] : candidatePositions) {
if (val > lastAddedPositionNumber) { if (val > lastAddedPositionNumber) {
this->currentTestedShape.insert(key); this->currentTestedShape.insert(key);

View File

@@ -64,6 +64,7 @@ bool PiecesFiles::loadPieces(int polyominoSize, std::vector<Piece>& pieces, std:
holelessPieces.clear(); holelessPieces.clear();
otherPieces.clear(); otherPieces.clear();
// we shift the first color of each size so that the small polyominos (size 1-2-3) don't all have the same color
Block pieceBlock = firstPieceBlockType(); Block pieceBlock = firstPieceBlockType();
for (int i = 0; i < polyominoSize; i++) { for (int i = 0; i < polyominoSize; i++) {
nextPieceBlockType(pieceBlock); nextPieceBlockType(pieceBlock);

View File

@@ -7,10 +7,10 @@
#include <iostream> #include <iostream>
#include <climits> #include <climits>
#include <algorithm> #include <algorithm>
#include <utility>
Polyomino::Polyomino(const std::set<Position>& positions) { Polyomino::Polyomino(const std::set<Position>& positions) {
// find min/max
int minX = INT_MAX; int minX = INT_MAX;
int maxX = INT_MIN; int maxX = INT_MIN;
int minY = INT_MAX; int minY = INT_MAX;
@@ -22,15 +22,14 @@ Polyomino::Polyomino(const std::set<Position>& positions) {
if (position.y > maxY) maxY = position.y; if (position.y > maxY) maxY = position.y;
} }
// normalize this->length = std::max(maxX - minX + 1, maxY - minY + 1);
// we normalize here instead of calling this->normalize() to reduce the number of calculations for the generation algorithm
std::set<Position> newPositions; std::set<Position> newPositions;
for (Position position : positions) { for (Position position : positions) {
newPositions.insert(Position{position.x - minX, position.y - minY}); newPositions.insert(Position{position.x - minX, position.y - minY});
} }
this->positions = std::move(newPositions); this->positions = std::move(newPositions);
// set polyomino length
this->length = std::max(maxX - minX + 1, maxY - minY + 1);
} }
Polyomino::Polyomino(const std::set<Position>& positions, int length) : Polyomino::Polyomino(const std::set<Position>& positions, int length) :
@@ -39,7 +38,6 @@ Polyomino::Polyomino(const std::set<Position>& positions, int length) :
} }
void Polyomino::normalize() { void Polyomino::normalize() {
// find min values
int minX = INT_MAX; int minX = INT_MAX;
int minY = INT_MAX; int minY = INT_MAX;
for (Position position : this->positions) { for (Position position : this->positions) {
@@ -47,7 +45,6 @@ void Polyomino::normalize() {
if (position.y < minY) minY = position.y; if (position.y < minY) minY = position.y;
} }
// translate the polyomino to the lowest unsigned values
std::set<Position> newPositions; std::set<Position> newPositions;
for (Position position : this->positions) { for (Position position : this->positions) {
newPositions.insert(Position{position.x - minX, position.y - minY}); newPositions.insert(Position{position.x - minX, position.y - minY});
@@ -82,6 +79,7 @@ void Polyomino::rotateCCW() {
void Polyomino::goToSpawnPosition() { void Polyomino::goToSpawnPosition() {
// initialize array // initialize array
std::vector<std::vector<int>> linesCompleteness; std::vector<std::vector<int>> linesCompleteness;
linesCompleteness.reserve(4);
std::vector<int> empty; std::vector<int> empty;
for (int j = 0; j < this->length; j++) { for (int j = 0; j < this->length; j++) {
empty.push_back(0); empty.push_back(0);
@@ -98,15 +96,15 @@ void Polyomino::goToSpawnPosition() {
linesCompleteness.at(3).at(position.x) += 1; // 3 = left to right = CCW linesCompleteness.at(3).at(position.x) += 1; // 3 = left to right = CCW
} }
// count empty lines // count empty lines and push the non-empty lines to the start of each vector
int horizontalEmptyLines = 0; int horizontalEmptyLines = 0;
int verticalEmptyLines = 0; int verticalEmptyLines = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = this->length - 1; j >= 0; j--) { for (int j = this->length - 1; j >= 0; j--) {
if (linesCompleteness.at(i).at(j) == 0) { if (linesCompleteness.at(i).at(j) == 0) {
// push the non-empty lines to the start of each vector
linesCompleteness.at(i).erase(linesCompleteness.at(i).begin() + j); linesCompleteness.at(i).erase(linesCompleteness.at(i).begin() + j);
linesCompleteness.at(i).push_back(0); linesCompleteness.at(i).push_back(0);
if (i == 0) horizontalEmptyLines++; if (i == 0) horizontalEmptyLines++;
if (i == 1) verticalEmptyLines++; if (i == 1) verticalEmptyLines++;
} }
@@ -124,11 +122,11 @@ void Polyomino::goToSpawnPosition() {
currentFlattestSides[3] = false; currentFlattestSides[3] = false;
} }
// checks for the flattest sides // checks for the flattest side
int sideToBeOn = -1; int sideToBeOn = -1;
this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, false); this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, false);
// if all sides are as flat, checks for the most left-biased side // if ther's no winner, checks for the side which has the flattest side to its left
if (sideToBeOn == -1) { if (sideToBeOn == -1) {
this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, true); this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, true);
} }
@@ -148,12 +146,16 @@ void Polyomino::goToSpawnPosition() {
sideToBeOn = candidateSides.at(std::distance(candidateRotations.begin(), std::min_element(candidateRotations.begin(), candidateRotations.end()))); sideToBeOn = candidateSides.at(std::distance(candidateRotations.begin(), std::min_element(candidateRotations.begin(), candidateRotations.end())));
} }
// do the correct rotation switch (sideToBeOn) {
if (sideToBeOn == 1) this->rotateCW(); case 1 : {this->rotateCW(); break;}
if (sideToBeOn == 2) this->rotate180(); case 2 : {this->rotate180(); break;}
if (sideToBeOn == 3) this->rotateCCW(); case 3 : {this->rotateCCW(); break;}
default: break;
}
if (sideToBeOn % 2 == 1) {
std::swap(verticalEmptyLines, horizontalEmptyLines);
}
// find min
int minX = INT_MAX; int minX = INT_MAX;
int minY = INT_MAX; int minY = INT_MAX;
for (Position position : this->positions) { for (Position position : this->positions) {
@@ -161,10 +163,7 @@ void Polyomino::goToSpawnPosition() {
if (position.y < minY) minY = position.y; if (position.y < minY) minY = position.y;
} }
// center the piece with an up bias if it is assymetric // center the piece with an up bias
if (sideToBeOn % 2 == 1) {
std::swap(verticalEmptyLines, horizontalEmptyLines);
}
std::set<Position> newPositions; std::set<Position> newPositions;
for (Position position : positions) { for (Position position : positions) {
newPositions.insert(Position{(position.x - minX) + (verticalEmptyLines / 2), (position.y - minY) + ((horizontalEmptyLines + 1) / 2)}); newPositions.insert(Position{(position.x - minX) + (verticalEmptyLines / 2), (position.y - minY) + ((horizontalEmptyLines + 1) / 2)});
@@ -174,19 +173,17 @@ void Polyomino::goToSpawnPosition() {
void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesCompleteness, bool currentFlattestSides[4], int& sideToBeOn, bool checkLeftSide) const { void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesCompleteness, bool currentFlattestSides[4], int& sideToBeOn, bool checkLeftSide) const {
for (int j = 0; j < this->length; j++) { for (int j = 0; j < this->length; j++) {
// we check which sides are the flattest on this line
int max = 0; int max = 0;
std::set<int> maxOwners; std::set<int> maxOwners;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
// only the candidate sides are compared
if (!currentFlattestSides[i]) continue; if (!currentFlattestSides[i]) continue;
// if we need to check the flatness of the side to the left
int sideToCheck = i; int sideToCheck = i;
if (checkLeftSide) { if (checkLeftSide) {
sideToCheck = (i + 3) % 4; sideToCheck = (i + 3) % 4;
} }
// we check which sides are the flattest
if (linesCompleteness.at(sideToCheck).at(j) > max) { if (linesCompleteness.at(sideToCheck).at(j) > max) {
max = linesCompleteness.at(sideToCheck).at(j); max = linesCompleteness.at(sideToCheck).at(j);
maxOwners.clear(); maxOwners.clear();
@@ -203,7 +200,7 @@ void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesC
return; return;
} }
// else we only keep the flattest from this round and ignore the others // else we only keep the flattest on this line and ignore the others
else { else {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
currentFlattestSides[i] = currentFlattestSides[i] && maxOwners.contains(i); currentFlattestSides[i] = currentFlattestSides[i] && maxOwners.contains(i);
@@ -213,14 +210,12 @@ void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesC
} }
bool Polyomino::isConvex() const { bool Polyomino::isConvex() const {
// for each line and column we check if every squares are adjacent to each others
for (int j = 0; j < this->length; j++) { for (int j = 0; j < this->length; j++) {
bool startedLine = false; bool startedLine = false;
bool completedLine = false; bool completedLine = false;
bool startedColumn = false; bool startedColumn = false;
bool completedColumn = false; bool completedColumn = false;
for (int i = 0; i < this->length; i++) { for (int i = 0; i < this->length; i++) {
// line check
if (this->positions.contains(Position{i, j})) { if (this->positions.contains(Position{i, j})) {
if (completedLine) return false; if (completedLine) return false;
else startedLine = true; else startedLine = true;
@@ -228,7 +223,7 @@ bool Polyomino::isConvex() const {
else { else {
if (startedLine) completedLine = true; if (startedLine) completedLine = true;
} }
// column check
if (this->positions.contains(Position{j, i})) { if (this->positions.contains(Position{j, i})) {
if (completedColumn) return false; if (completedColumn) return false;
else startedColumn = true; else startedColumn = true;
@@ -282,7 +277,6 @@ int Polyomino::getPolyominoSize() const {
bool Polyomino::operator<(const Polyomino& other) const { bool Polyomino::operator<(const Polyomino& other) const {
if (this->length != other.length) return this->length < other.length; if (this->length != other.length) return this->length < other.length;
// we check for all positions from left to right and top to bottom, until one has a square that the other doesn't
for (int y = this->length - 1; y >= 0; y--) { for (int y = this->length - 1; y >= 0; y--) {
for (int x = 0; x < this->length; x++) { for (int x = 0; x < this->length; x++) {
bool hasThisPosition = this->positions.contains(Position{x, y}); bool hasThisPosition = this->positions.contains(Position{x, y});

View File

@@ -10,12 +10,12 @@
#include <cstdlib> #include <cstdlib>
#include <exception> #include <exception>
static const int FRAMES_PER_INPUT = FRAMES_PER_SECOND / 2; static const int FRAMES_PER_INPUT = FRAMES_PER_SECOND / 2; // the number of frames that will pass everytime the player gives an input
static const int MAXIMUM_PIECE_SIZE = 10; static const int MAXIMUM_PIECE_SIZE = 10; // the maximum size of pieces that will be loaded and utilizable
static const int DEFAULT_PIECE_SIZE = 4; static const int DEFAULT_PIECE_SIZE = 4; // the default size of pieces that will be selected when first running the app
static const int MAXIMUM_BOARD_WIDTH = 30; static const int MAXIMUM_BOARD_WIDTH = 30; // the maximum selectable width of the board
static const int MAXIMUM_BOARD_HEIGHT = 40; static const int MAXIMUM_BOARD_HEIGHT = 40; // the maximum selectable height of the board
static const Gamemode DEFAULT_GAMEMODE = SPRINT; static const Gamemode DEFAULT_GAMEMODE = SPRINT; // the gamemode that will be used when starting a new game
TextApp::TextApp() { TextApp::TextApp() {
@@ -31,8 +31,6 @@ TextApp::TextApp() {
void TextApp::run() { void TextApp::run() {
bool quit = false; bool quit = false;
std::string answer;
int selectedAnswer = 0;
while (!quit) { while (!quit) {
std::cout << "\n\n\n"; std::cout << "\n\n\n";
std::cout << "===| WELCOME TO JMINOS! |===" << std::endl; std::cout << "===| WELCOME TO JMINOS! |===" << std::endl;
@@ -42,7 +40,10 @@ void TextApp::run() {
std::cout << "4- Start game" << std::endl; std::cout << "4- Start game" << std::endl;
std::cout << "5- Quit" << std::endl; std::cout << "5- Quit" << std::endl;
std::cout << "Choice: "; std::cout << "Choice: ";
std::string answer;
std::getline(std::cin, answer); std::getline(std::cin, answer);
int selectedAnswer = 0;
try { try {
selectedAnswer = std::stoi(answer); selectedAnswer = std::stoi(answer);
} }
@@ -232,6 +233,7 @@ void TextApp::printGame(const Game& game) const {
for (int y = maxHeight; y >= 0; y--) { for (int y = maxHeight; y >= 0; y--) {
for (int x = 0; x < game.getBoard().getWidth(); x++) { for (int x = 0; x < game.getBoard().getWidth(); x++) {
/* BOARD PRINTING */
bool isActivePieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.getActivePiecePosition())); bool isActivePieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.getActivePiecePosition()));
bool isGhostPieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.ghostPiecePosition())); bool isGhostPieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.ghostPiecePosition()));
Block block = (isActivePieceHere || isGhostPieceHere) ? game.getActivePiece()->getBlockType() : game.getBoard().getBlock(Position{x, y}); Block block = (isActivePieceHere || isGhostPieceHere) ? game.getActivePiece()->getBlockType() : game.getBoard().getBlock(Position{x, y});
@@ -262,6 +264,7 @@ void TextApp::printGame(const Game& game) const {
} }
if (y < game.getBoard().getGridHeight()) { if (y < game.getBoard().getGridHeight()) {
/* SIDEBAR PRINTING */
std::cout << " "; std::cout << " ";
if (!lineCountPrinted) { if (!lineCountPrinted) {
std::cout << getResetConsoleColorCode() << "Lines: " << game.getClearedLines(); std::cout << getResetConsoleColorCode() << "Lines: " << game.getClearedLines();