ajouté interface textuelle

This commit is contained in:
2025-03-02 23:36:20 +01:00
parent 857f90d646
commit 1033f3a64c
21 changed files with 646 additions and 113 deletions

View File

@@ -72,15 +72,22 @@ bool GameBoard::moveDown() {
bool GameBoard::rotate(Rotation rotation) {
Piece stored = *this->activePiece;
this->rotate(rotation);
this->activePiece->rotate(rotation);
// before trying to kick, check if the piece can rotate without kicking
if (!this->activePieceInWall()) {
this->isLastMoveKick = false;
return true;
if (rotation == NONE) {
if (this->moveDown()) {
this->isLastMoveKick = false;
return true;
}
}
else {
if (!this->activePieceInWall()) {
this->isLastMoveKick = false;
return true;
}
}
// get the list of positions that touches the original piece
std::set<Position> safePositions;
for (Position position : stored.getPositions()) {
Position positionInGrid(position + this->activePiecePosition);
@@ -91,7 +98,10 @@ bool GameBoard::rotate(Rotation rotation) {
safePositions.insert(positionInGrid + Position{-1, 0});
}
// try kicking the piece down
// first try kicking the piece down
if (rotation == NONE) {
this->activePiecePosition.y -= 1;
}
bool suceeded = this->tryKicking(true, safePositions);
if (suceeded) {
this->isLastMoveKick = true;
@@ -99,6 +109,9 @@ bool GameBoard::rotate(Rotation rotation) {
}
// if it doesn't work try kicking the piece up
if (rotation == NONE) {
this->activePiecePosition.y += 1;
}
suceeded = this->tryKicking(false, safePositions);
if (suceeded) {
this->isLastMoveKick = true;
@@ -107,7 +120,10 @@ bool GameBoard::rotate(Rotation rotation) {
// if it still doesn't work, abort the rotation
this->activePiece = std::make_shared<Piece>(stored);
return false;
if (rotation == NONE) {
this->isLastMoveKick = false;
}
return (rotation == NONE);
}
bool GameBoard::tryKicking(bool testingBottom, const std::set<Position>& safePositions) {
@@ -118,9 +134,9 @@ bool GameBoard::tryKicking(bool testingBottom, const std::set<Position>& safePos
// we try from the center to the sides as long as the kicked piece touches the original
bool overlapsLeft = true;
bool overlapsRight = true;
int i = 0;
int i = (j == 0) ? 1 : 0;
do {
// check right before right arbitrarly, we don't decide this with rotations since it would still be arbitrary with 180° rotations
// check right before left arbitrarly, we don't decide this with rotations since it would still be arbitrary with 180° rotations
if (overlapsRight) {
Position shift{+i, j};
if (!this->activePieceOverlaps(safePositions, shift)) {
@@ -175,21 +191,23 @@ bool GameBoard::hold(Rotation initialRotation) {
}
}
this->goToSpawnPosition();
Piece stored = *this->activePiece;
Position storedPosition = this->activePiecePosition;
this->goToSpawnPosition();
this->rotate(initialRotation);
// if the piece can't spawn, abort initial rotation
if (this->activePieceInWall()) {
this->activePiece = std::make_shared<Piece>(stored);
this->goToSpawnPosition();
// if the piece still can't spawn, abort holding
if (this->activePieceInWall()) {
if (isFirstTimeHolding) {
this->activePiece = nullptr;
}
std::swap(this->activePiece, this->heldPiece);
this->activePiecePosition = storedPosition;
return false;
}
}
@@ -200,6 +218,8 @@ bool GameBoard::hold(Rotation initialRotation) {
this->nextQueue.erase(this->nextQueue.begin());
}
this->heldPiece->defaultRotation();
// this piece has done nothing yet
this->isLastMoveKick = false;
@@ -207,10 +227,7 @@ bool GameBoard::hold(Rotation initialRotation) {
}
bool GameBoard::spawnNextPiece() {
// generate a new piece
this->nextQueue.push_back(this->generator.getNext());
// get next piece from queue
this->activePiece = std::make_shared<Piece>(this->nextQueue.front());
this->nextQueue.erase(this->nextQueue.begin());
@@ -219,13 +236,22 @@ bool GameBoard::spawnNextPiece() {
// this piece has done nothing yet
this->isLastMoveKick = false;
return !this->activePieceInWall();
return this->activePieceInWall();
}
bool GameBoard::touchesGround() {
bool GameBoard::touchesGround() const {
return this->activePieceInWall(Position{0, -1});
}
Position GameBoard::lowestPosition() const {
Position shift = Position{0, -1};
while (!activePieceInWall(shift)) {
shift.y -= 1;
}
shift.y += 1;
return (this->activePiecePosition + shift);
}
LineClear GameBoard::lockPiece() {
bool isLockedInPlace = (this->activePieceInWall(Position{0, 1}) && this->activePieceInWall(Position{1, 0})
&& this->activePieceInWall(Position{-1, 0}) && this->activePieceInWall(Position{0, -1}));
@@ -248,23 +274,23 @@ void GameBoard::addGarbageRows(int number) {
}
}
Board GameBoard::getBoard() const {
const Board& GameBoard::getBoard() const {
return this->board;
}
Piece GameBoard::getActivePiece() const {
return *this->activePiece;
const std::shared_ptr<Piece>& GameBoard::getActivePiece() const {
return this->activePiece;
}
Position GameBoard::getActivePiecePosition() const {
const Position& GameBoard::getActivePiecePosition() const {
return this->activePiecePosition;
}
Piece GameBoard::getHeldPiece() const {
return *this->heldPiece;
const std::shared_ptr<Piece>& GameBoard::getHeldPiece() const {
return this->heldPiece;
}
std::vector<Piece> GameBoard::getNextPieces() const {
const std::vector<Piece>& GameBoard::getNextPieces() const {
return this->nextQueue;
}
@@ -293,6 +319,8 @@ void GameBoard::goToSpawnPosition() {
// center the piece horizontally, biased towards left
this->activePiecePosition.x = (this->board.getWidth() - this->activePiece->getLength()) / 2;
this->activePiece->defaultRotation();
}
std::ostream& operator<<(std::ostream& os, const GameBoard& gameboard) {