fix pawn stacking at home, update&fix isMoveLegal, introduce tryTakingPiece and Doxyfile, shorten timeouts in debug mode.

This commit is contained in:
2025-01-28 21:38:36 +01:00
parent 0f141e1475
commit 5eb61f5818
5 changed files with 3041 additions and 8 deletions

View File

@@ -181,6 +181,11 @@ void Board::updateAndRender() {
}
void Board::smartSleep(int millis) {
#ifdef DEBUG
millis /= 10;
#endif
for (int i = 0; i < millis / 10; i++) {
sf::sleep(sf::milliseconds(10));
this->update();

View File

@@ -199,7 +199,6 @@ void Engine::nextTurn() {
// Nie potrzebujemy, aby gracz wskazał jedyny pionek na planszy,
// dlatego ruszamy go za niego.
pickAPlace = false;
// TODO: znajdź ten pionek i ustaw selectedField na niego!!!
for (int i = 0; i < 4; i++) {
short* relativePawns = currentPlayer.getRelativePawns();
@@ -358,6 +357,13 @@ bool Engine::isMoveLegal(short color, short pawnId, short steps) {
if (this->players[color].getRelativePawns()[pawnId] + steps < 44) {
short newField = relPosToField(color, this->players[color].getRelativePawns()[pawnId] + steps);
short occupyingColor = fieldToColor(newField);
// Nie pozwól na stackowanie pionków w domku
if (this->players[color].getRelativePawns()[pawnId] + steps > 39) {
for (int i = 0; i < 4; i++) {
if (this->players[color].getRelativePawns()[pawnId] + steps == this->players[color].getRelativePawns()[i]) return false;
}
}
if (occupyingColor != -1 && relPosToField(occupyingColor, 0) == newField) return false;
}
for (int i = 0; i < 4; i++) {
@@ -366,7 +372,26 @@ bool Engine::isMoveLegal(short color, short pawnId, short steps) {
}
if (this->board.fields[field][pawnId] == color + 4) {
short relPos = fieldToRelPos(color, field);
if (relPos + steps < 44) return true;
if (relPos + steps < 44) {
short newField = relPosToField(color, relPos + steps);
bool isNewFieldOccupied = false;
short occupyingColor = -1;
for (int j = 0; j < 4; j++) {
if (this->board.fields[newField][j] != 0) {
isNewFieldOccupied = true;
occupyingColor = this->board.fields[newField][j] - 4;
break;
}
}
short takenPawns = -1;
if (isNewFieldOccupied && color != occupyingColor) {
// w zamian za takePawns()
takenPawns = tryTakingPawns(occupyingColor, newField);
if (takenPawns == -1) return false;
}
return true;
}
else return false;
}
return false;
@@ -452,6 +477,28 @@ short Engine::spawnPiece(short color, short pawnId) {
return false;
}
/**
* @brief Try taking pawns down
*
* @param[in] field Field inside field matrix
*
* @return Pawns that can be taken down
*/
short Engine::tryTakingPawns(short color, short field) {
// Spróbuj zbić pionki
short counter = 0;
// Nie można zbić pionka w polu startowym.
if (field == relPosToField(color, 0)) {
return -1;
}
for (int i = 0; i < 4; i++) {
if (this->board.fields[field][i] > 0) counter++;
}
return counter;
}
/**
* @brief Take pawns down
*
@@ -503,7 +550,7 @@ short Engine::takePawns(short color, short field) {
* @return Returns true on success, false on failure.
*/
bool Engine::movePiece(short color, short field, short steps) { // podajemy color dla sanity-checku, czy użytkownik nie chce ruszyć nie swojego pionka
// Jeśli ruch, który chcemy wykonać zbiłby pionki w chronionym polu, zwróć false.
if (fieldToRelPos(color, field) + steps < 44) {
short newField = relPosToField(color, fieldToRelPos(color, field) + steps);
@@ -526,6 +573,14 @@ bool Engine::movePiece(short color, short field, short steps) { // podajemy colo
short newField = relPosToField(color, relPos + steps);
bool isNewFieldOccupied = false;
short occupyingColor = -1;
// Nie pozwól na stackowanie pionków w domku!
if (relPos + steps > 39) {
for (int i = 0; i < 4; i++) {
if (relPos + steps == this->players[color].getRelativePawns()[i]) return false;
}
}
// - czy tam, gdzie chcemy przenieść pionek gracza
// inny gracz nie ma swojego
for (int j = 0; j < 4; j++) {
@@ -537,10 +592,12 @@ bool Engine::movePiece(short color, short field, short steps) { // podajemy colo
}
// - jeśli ma, musimy go (/je) zbić
short takenPawns = -1;
if (isNewFieldOccupied && color != occupyingColor) takenPawns = takePawns(occupyingColor, newField);
// - uwaga! jeśli nie zbiliśmy żadnego pionka, to dlatego, ponieważ pionki są w chronionym polu!!!
// musimy to uszanować, dlatego kończymy metodę zwracając false
if (isNewFieldOccupied && takenPawns == -1) return false;
if (isNewFieldOccupied && color != occupyingColor) {
takenPawns = takePawns(occupyingColor, newField);
// - uwaga! jeśli nie zbiliśmy żadnego pionka, to dlatego, ponieważ pionki są w chronionym polu!!!
// musimy to uszanować, dlatego kończymy metodę zwracając false
if (takenPawns == -1) return false;
}
// - w końcu, dopisujemy pionek bieżącego gracza
this->board.fields[newField][i] = color + 4;
this->players[this->currentPlayerIndex].unsafeMovePiece(i, steps);

View File

@@ -26,6 +26,7 @@ class Engine {
int rollDice(unsigned int seed, unsigned int moveNumber);
short spawnPiece(short color, short pawnId);
short takePawns(short color, short field);
short tryTakingPawns(short color, short field);
bool movePiece(short color, short field, short steps);
short getFirstPawnAtBase(short color);
short getFirstPawnNotAtBase(short color);

View File

@@ -103,7 +103,7 @@ void Player::sendToBoard(short pawnNumber) {
void Player::unsafeMovePiece(short pawnNumber, short steps) {
// to dopełnia obecną w Engine.cpp movePiece()
// metoda jest "unsafe" ponieważ nie sprawdza danych, tylko ufa movePiece()
if (this->relativePawns[pawnNumber] >= 39 && this->isPawnAtHome(pawnNumber)) {
if (this->relativePawns[pawnNumber] >= 39 && !this->isPawnAtHome(pawnNumber)) {
this->pawnsActive--;
this->pawnsAtHome++;
}

2970
Doxyfile Normal file

File diff suppressed because it is too large Load Diff