Make automove return what changed

This allows us to optimize the emitted signals, as we will know what has
changed after an automove.
This commit is contained in:
ItsDrike 2024-12-12 20:45:34 +01:00
parent 1ecfd36598
commit a52681c0b3
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
2 changed files with 32 additions and 20 deletions

View file

@ -280,7 +280,8 @@ bool GameState::autoMoveThrownCard() {
qDebug() << "Attempting auto-move of thrown card " << cardToMove->toString();
// Try moving the card into the foundation
if (!tryAutoMoveSingleCard(*cardToMove)) {
auto changed = tryAutoMoveSingleCard(*cardToMove);
if (!changed.has_value()) {
qDebug() << "> Moving failed, no available move found";
return false;
}
@ -291,11 +292,11 @@ bool GameState::autoMoveThrownCard() {
emit throwawayPileChanged();
// We don't know which pile the card was moved to, to be safe, emit
// a change from both
// NOTE: consider returning what changed from tryAutoMoveSingleCard
emit columnsChanged();
emit foundationChanged();
switch (changed.value().destinationType) {
case AutoMoveResult::DestinationType::Foundation: emit foundationChanged(); break;
case AutoMoveResult::DestinationType::Column: emit columnsChanged(); break;
default: assert(false); break;
}
incrementMoveAmt();
return true;
@ -320,7 +321,8 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
// This is a single card move (last card)
PlayingCard* cardToMove = col->card();
qDebug() << "Attempting auto-move of column " << columnId << " card " << cardToMove->toString();
if (!tryAutoMoveSingleCard(*cardToMove, columnId)) {
auto changed = tryAutoMoveSingleCard(*cardToMove, columnId);
if (!changed.has_value()) {
qDebug() << "> Moving failed, no available move found";
return false;
}
@ -331,12 +333,13 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
ensureColumnRevealed(columnId);
qDebug() << "> Moving complete";
// Columns always change, we're moving from them, if the move is to another column
// that's all, if it's to a foundation, also emit foundation change
emit columnsChanged();
if (changed.value().destinationType == AutoMoveResult::DestinationType::Foundation) {
emit foundationChanged();
}
// we don't know where the card was moved, it could've been the foundation too
// to be safe, emit a change signal for it too
// NOTE: consider returning what changed from tryAutoMoveSingleCard
emit foundationChanged();
incrementMoveAmt();
return true;
@ -350,7 +353,7 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
selectedCards.append(curCol->card());
}
if (!tryAutoMoveMultipleCards(selectedCards, columnId)) {
if (!tryAutoMoveMultipleCards(selectedCards, columnId).has_value()) {
qDebug() << "> Moving failed, no available move found";
return false;
}
@ -512,13 +515,13 @@ QString GameState::generateStateHash() const {
return stateHash;
}
bool GameState::tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId) {
std::optional<GameState::AutoMoveResult> GameState::tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId) {
// 1. Try moving the card to the foundation
const int foundationId = static_cast<int>(cardToMove.suit());
if (isFoundationMoveValid(cardToMove, foundationId)) {
m_foundation[foundationId].prepend(&cardToMove);
qDebug() << "* Auto-moved card " << cardToMove.toString() << " to foundation " << foundationId;
return true;
return AutoMoveResult{AutoMoveResult::DestinationType::Foundation, foundationId};
}
// 2. Try moving the card to another column
@ -530,16 +533,16 @@ bool GameState::tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId)
ColumnSlot* col = new ColumnSlot(&cardToMove, true, this);
m_columns[columnId].append(col);
qDebug() << "* Auto-moved card " << cardToMove.toString() << " to column " << columnId;
return true;
return AutoMoveResult{AutoMoveResult::DestinationType::Column, columnId};
}
}
// No available auto-move
qDebug() << "* Auto-move failed, no available moves";
return false;
return std::nullopt;
}
bool GameState::tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId) {
std::optional<GameState::AutoMoveResult> GameState::tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId) {
assert(cards.size() > 1);
// If we can move the first (selected) card to another column,
@ -564,7 +567,7 @@ bool GameState::tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int s
}
qDebug() << "* Auto-move failed, no available moves";
return false;
return std::nullopt;
}
bool GameState::isFoundationMoveValid(const PlayingCard& cardToMove, int foundationId) const {

View file

@ -83,12 +83,21 @@ class GameState : public QObject {
std::pair<std::optional<bool>, int> m_isWinnable;
bool m_enableWinnabilitySim;
struct AutoMoveResult {
enum class DestinationType {
Foundation,
Column
};
DestinationType destinationType;
int destinationId;
};
GameState* clone(bool enableWinnabilitySim = false) const;
void cleanupBoard(bool emitChanges);
QString generateStateHash() const;
bool tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId = -1);
bool tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId);
std::optional<AutoMoveResult> tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId = -1);
std::optional<AutoMoveResult> tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId);
bool isFoundationMoveValid(const PlayingCard& cardToMove, int foundationId) const;
bool isColumnMoveValid(const PlayingCard& cardToMove, int columnId) const;