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(); qDebug() << "Attempting auto-move of thrown card " << cardToMove->toString();
// Try moving the card into the foundation // 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"; qDebug() << "> Moving failed, no available move found";
return false; return false;
} }
@ -291,11 +292,11 @@ bool GameState::autoMoveThrownCard() {
emit throwawayPileChanged(); emit throwawayPileChanged();
// We don't know which pile the card was moved to, to be safe, emit switch (changed.value().destinationType) {
// a change from both case AutoMoveResult::DestinationType::Foundation: emit foundationChanged(); break;
// NOTE: consider returning what changed from tryAutoMoveSingleCard case AutoMoveResult::DestinationType::Column: emit columnsChanged(); break;
emit columnsChanged(); default: assert(false); break;
emit foundationChanged(); }
incrementMoveAmt(); incrementMoveAmt();
return true; return true;
@ -320,7 +321,8 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
// This is a single card move (last card) // This is a single card move (last card)
PlayingCard* cardToMove = col->card(); PlayingCard* cardToMove = col->card();
qDebug() << "Attempting auto-move of column " << columnId << " card " << cardToMove->toString(); 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"; qDebug() << "> Moving failed, no available move found";
return false; return false;
} }
@ -331,12 +333,13 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
ensureColumnRevealed(columnId); ensureColumnRevealed(columnId);
qDebug() << "> Moving complete"; 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(); 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(); incrementMoveAmt();
return true; return true;
@ -350,7 +353,7 @@ bool GameState::autoMoveColumnCard(int columnId, int cardIndex) {
selectedCards.append(curCol->card()); selectedCards.append(curCol->card());
} }
if (!tryAutoMoveMultipleCards(selectedCards, columnId)) { if (!tryAutoMoveMultipleCards(selectedCards, columnId).has_value()) {
qDebug() << "> Moving failed, no available move found"; qDebug() << "> Moving failed, no available move found";
return false; return false;
} }
@ -512,13 +515,13 @@ QString GameState::generateStateHash() const {
return stateHash; 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 // 1. Try moving the card to the foundation
const int foundationId = static_cast<int>(cardToMove.suit()); const int foundationId = static_cast<int>(cardToMove.suit());
if (isFoundationMoveValid(cardToMove, foundationId)) { if (isFoundationMoveValid(cardToMove, foundationId)) {
m_foundation[foundationId].prepend(&cardToMove); m_foundation[foundationId].prepend(&cardToMove);
qDebug() << "* Auto-moved card " << cardToMove.toString() << " to foundation " << foundationId; 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 // 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); ColumnSlot* col = new ColumnSlot(&cardToMove, true, this);
m_columns[columnId].append(col); m_columns[columnId].append(col);
qDebug() << "* Auto-moved card " << cardToMove.toString() << " to column " << columnId; qDebug() << "* Auto-moved card " << cardToMove.toString() << " to column " << columnId;
return true; return AutoMoveResult{AutoMoveResult::DestinationType::Column, columnId};
} }
} }
// No available auto-move // No available auto-move
qDebug() << "* Auto-move failed, no available moves"; 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); assert(cards.size() > 1);
// If we can move the first (selected) card to another column, // 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"; qDebug() << "* Auto-move failed, no available moves";
return false; return std::nullopt;
} }
bool GameState::isFoundationMoveValid(const PlayingCard& cardToMove, int foundationId) const { 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; std::pair<std::optional<bool>, int> m_isWinnable;
bool m_enableWinnabilitySim; bool m_enableWinnabilitySim;
struct AutoMoveResult {
enum class DestinationType {
Foundation,
Column
};
DestinationType destinationType;
int destinationId;
};
GameState* clone(bool enableWinnabilitySim = false) const; GameState* clone(bool enableWinnabilitySim = false) const;
void cleanupBoard(bool emitChanges); void cleanupBoard(bool emitChanges);
QString generateStateHash() const; QString generateStateHash() const;
bool tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId = -1); std::optional<AutoMoveResult> tryAutoMoveSingleCard(PlayingCard& cardToMove, int skipColumnId = -1);
bool tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId); std::optional<AutoMoveResult> tryAutoMoveMultipleCards(const QList<PlayingCard*>& cards, int skipColumnId);
bool isFoundationMoveValid(const PlayingCard& cardToMove, int foundationId) const; bool isFoundationMoveValid(const PlayingCard& cardToMove, int foundationId) const;
bool isColumnMoveValid(const PlayingCard& cardToMove, int columnId) const; bool isColumnMoveValid(const PlayingCard& cardToMove, int columnId) const;