fixed game logic

This commit is contained in:
2025-03-05 19:02:51 +01:00
parent 2fbe4a6052
commit 74797e935a
15 changed files with 186 additions and 138 deletions

View File

@@ -26,6 +26,8 @@ void Bag::jumpToNextBag() {
this->currentBag.push_back(pieceIndex);
}
this->nextBag.clear();
this->prepareNext();
}
Piece Bag::lookNext() {

View File

@@ -64,6 +64,7 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
if (this->leftARETime == 0) {
if (AREJustEnded) {
this->lost = this->board.spawnNextPiece();
this->resetPiece(true);
}
/* IRS and IHS */
@@ -73,33 +74,17 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
+ ((this->initialActions.contains(ROTATE_CCW)) ? COUNTERCLOCKWISE : NONE);
if (this->initialActions.contains(HOLD)) {
if (this->board.hold(initialRotation)) {
this->subVerticalPosition = 0;
this->totalLockDelay = 0;
this->heldARR = 0;
}
else {
this->lost = true;
}
this->lost = (!this->board.hold(initialRotation));
}
else {
if (initialRotation != NONE || this->initialActions.contains(ROTATE_0)) {
Position before = this->board.getActivePiecePosition();
if (this->board.rotate(initialRotation)) {
this->totalLockDelay = 0;
if (before != this->board.getActivePiecePosition()) {
this->subVerticalPosition = 0;
}
}
else {
this->lost = true;
}
if ((initialRotation != NONE) || this->initialActions.contains(ROTATE_0)) {
this->lost = (!this->board.rotate(initialRotation));
}
}
if (this->lost) {
if (initialRotation == NONE && (!this->initialActions.contains(ROTATE_0))) {
this->board.rotate(NONE);
if (initialRotation == NONE) {
this->lost = (!this->board.rotate(initialRotation));
}
}
if (this->lost) {
@@ -110,23 +95,22 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
/* HOLD */
if (playerActions.contains(HOLD) && (!this->heldActions.contains(HOLD))) {
if (this->board.hold()) {
this->subVerticalPosition = 0;
this->totalLockDelay = 0;
this->heldARR = 0;
this->resetPiece(false);
}
}
/* MOVE LEFT/RIGHT */
Position before = this->board.getActivePiecePosition();
if (playerActions.contains(MOVE_LEFT)) {
this->movePiece(-1);
if (this->heldDAS >= 0) {
if (playerActions.contains(MOVE_LEFT) && (!heldActions.contains(MOVE_LEFT))) this->movePiece(-1);
else if (playerActions.contains(MOVE_RIGHT)) this->movePiece(1);
else this->heldDAS = 0;
}
else if (playerActions.contains(MOVE_RIGHT)) {
this->movePiece(1);
}
else {
this->heldDAS = 0;
else if (this->heldDAS < 0) {
if (playerActions.contains(MOVE_RIGHT) && (!heldActions.contains(MOVE_RIGHT))) this->movePiece(1);
else if (playerActions.contains(MOVE_LEFT)) this->movePiece(-1);
else this->heldDAS = 0;
}
if (before != this->board.getActivePiecePosition()) {
@@ -134,31 +118,17 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
}
/* ROTATIONS */
before = this->board.getActivePiecePosition();
if (playerActions.contains(ROTATE_0) && (!this->heldActions.contains(ROTATE_0))) {
if (this->board.rotate(NONE)) {
this->totalLockDelay = 0;
}
this->rotatePiece(NONE);
}
if (playerActions.contains(ROTATE_CW) && (!this->heldActions.contains(ROTATE_CW))) {
if (this->board.rotate(CLOCKWISE)) {
this->totalLockDelay = 0;
}
this->rotatePiece(CLOCKWISE);
}
if (playerActions.contains(ROTATE_180) && (!this->heldActions.contains(ROTATE_180))) {
if (this->board.rotate(DOUBLE)) {
this->totalLockDelay = 0;
}
this->rotatePiece(DOUBLE);
}
if (playerActions.contains(ROTATE_CCW) && (!this->heldActions.contains(ROTATE_CCW))) {
if (this->board.rotate(COUNTERCLOCKWISE)) {
this->totalLockDelay = 0;
}
}
if (before != this->board.getActivePiecePosition()) {
this->subVerticalPosition = 0;
this->rotatePiece(COUNTERCLOCKWISE);
}
/* SOFT DROP */
@@ -238,45 +208,61 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
this->initialActions.insert(action);
}
if (playerActions.contains(MOVE_LEFT)) {
this->heldDAS = std::min(-1, this->heldDAS - 1);
if (this->heldDAS >= 0) {
if (playerActions.contains(MOVE_LEFT)) this->heldDAS = -1;
else if (playerActions.contains(MOVE_RIGHT)) this->heldDAS++;
else this->heldDAS = 0;
}
else if (playerActions.contains(MOVE_RIGHT)) {
this->heldDAS = std::max(1, this->heldDAS + 1);
}
else {
this->heldDAS = 0;
else if (this->heldDAS < 0) {
if (playerActions.contains(MOVE_RIGHT)) this->heldDAS = +1;
else if (playerActions.contains(MOVE_LEFT)) this->heldDAS--;
else this->heldDAS = 0;
}
}
}
void Game::resetPiece(bool newPiece) {
int appliedDAS = this->parameters.getDAS();
this->subVerticalPosition = 0;
this->totalLockDelay = 0;
if (newPiece) {
this->totalForcedLockDelay = 0;
}
if (abs(this->heldDAS) > appliedDAS) {
this->heldDAS = (this->heldDAS > 0) ? (+appliedDAS) : (-appliedDAS);
}
this->heldARR = 0;
}
void Game::movePiece(int movement) {
std::cout << movement << std::endl;
int appliedDAS = this->parameters.getDAS();
int appliedARR = this->parameters.getARR();
if ((this->heldDAS * movement) <= 0) {
this->heldDAS = movement;
this->heldARR = 0;
if (movement == -1) this->board.moveLeft();
if (movement == 1) this->board.moveRight();
}
else {
this->heldDAS += movement;
}
if (abs(this->heldDAS) == appliedDAS + 1) {
if (movement == -1) this->board.moveLeft();
if (movement == 1) this->board.moveRight();
}
if (abs(this->heldDAS) > appliedDAS + 1) {
if (abs(this->heldDAS) > appliedDAS) {
// ARR=0 -> instant movement
if (appliedARR == 0) {
if (movement == -1) while (this->board.moveLeft());
if (movement == 1) while (this->board.moveRight());
}
// ARR>1 -> move by specified amount
else {
this->heldARR++;
if (this->heldARR == appliedARR) {
if (abs(this->heldDAS) > appliedDAS + 1) {
this->heldARR++;
}
if ((this->heldARR == appliedARR) || (abs(this->heldDAS) == (appliedDAS + 1))) {
this->heldARR = 0;
if (movement == -1) this->board.moveLeft();
if (movement == 1) this->board.moveRight();
@@ -285,6 +271,17 @@ void Game::movePiece(int movement) {
}
}
void Game::rotatePiece(Rotation rotation) {
Position before = this->board.getActivePiecePosition();
if (this->board.rotate(rotation)) {
this->totalLockDelay = 0;
if (before != this->board.getActivePiecePosition()) {
this->subVerticalPosition = 0;
}
}
}
void Game::lockPiece() {
LineClear clear = this->board.lockPiece();
this->parameters.clearLines(clear.lines);
@@ -300,16 +297,12 @@ void Game::lockPiece() {
this->score += clearScore;
}
this->B2BChain = B2BConditionsAreMet;
this->subVerticalPosition = 0;
this->totalLockDelay = 0;
this->totalForcedLockDelay = 0;
this->heldARR = 0;
if (!this->hasWon()) {
this->leftARETime = this->parameters.getARE();
if (this->leftARETime == 0) {
this->lost = this->board.spawnNextPiece();
this->resetPiece(true);
}
}
}

View File

@@ -61,10 +61,20 @@ class Game {
private:
/**
* Move the piece in the specified direction
* Resets the piece's parameter
*/
void resetPiece(bool newPiece);
/**
* Moves the piece in the specified direction (1 for right and -1 for left)
*/
void movePiece(int movement);
/**
* Rotates the piece with the specified rotation
*/
void rotatePiece(Rotation rotation);
/**
* Locks the piece, updates level and score and spawns the next piece if necessary
*/

View File

@@ -4,17 +4,17 @@
#include "Player.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 app 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
/**
* The interface between the UI and the core of the game
* The interface between an UI and the core of the app
*/
class Menu {
private:
std::shared_ptr<PiecesList> piecesList; // the list of pieces in the game
std::shared_ptr<PiecesList> piecesList; // the list of pieces used by the app
Player playerControls; // the controls of the player
int boardWidth; // the width of the board for the next game
int boardHeight; // the height of the board for the next game