Add logic for auto-moves

This commit is contained in:
ItsDrike 2024-12-03 01:55:54 +01:00
parent c47f973873
commit 69c3b43834
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
2 changed files with 81 additions and 0 deletions

View file

@ -146,6 +146,60 @@ bool GameState::moveColumnCardToFoundation(int columnId, PlayingCard::Suit found
}
bool GameState::autoMoveThrownCard()
{
// NOTE: This method is very similar to moveThrownCardToFoundation,
// consider reducing the repetitino here somehow.
if (m_throwawayPile.isEmpty()) {
// Consider raising an exception here instead
qWarning() << "Attempted to move thrown card to foundation with empty throwaway pile";
return false;
}
// We'll be moving the last card in the foundation pile (maybe)
PlayingCard *cardToMove = m_throwawayPile.last();
// Try moving the card into the foundation
if (!tryAutoMoveCard(cardToMove))
return false;
// We succeeded, the card is now in the appropriate foundation pile,
// let's remove the card from the throwaway pile.
m_throwawayPile.removeLast();
emit throwawayPileChanged();
return true;
}
bool GameState::autoMoveColumnCard(int columnId)
{
// NOTE: This method is very similar to moveColumnCardToFoundation,
// consider reducing the repetitino here somehow.
assert(columnId >= 0 && columnId < 7);
if (m_columns[columnId].isEmpty()) {
// Consider raising an exception here instead
qWarning() << "Attempted to move card to foundation from an empty column";
return false;
}
// We'll be moving the top card in the column (maybe)
PlayingCard *cardToMove = m_columns[columnId].first()->card();
if (!tryAutoMoveCard(cardToMove))
return false;
// We succeeded, the card is now in the appropriate foundation pile,
// let's remove the column slot.
m_columns[columnId].removeFirst();
ensureColumnRevealed(columnId);
emit columnsChanged();
return true;
}
void GameState::onFoundationChanged()
{
// Check if the game is won (can only happen on a foundation pile change)
@ -199,6 +253,24 @@ bool GameState::tryMoveCardToFoundation(PlayingCard::Suit foundationId, PlayingC
return true;
}
bool GameState::tryAutoMoveCard(PlayingCard *cardToMove)
{
// 1. Try moving the card to the foundation
for (PlayingCard::Suit suit : {PlayingCard::Suit::Clubs, PlayingCard::Suit::Diamonds, PlayingCard::Suit::Hearts, PlayingCard::Suit::Spades})
if (cardToMove->suit() == suit && tryMoveCardToFoundation(suit, cardToMove))
return true;
// 2. Try moving the card to another column
for (int columnId = 0; columnId < m_columns.size(); ++columnId)
if (isMoveToColumnLegal(cardToMove, columnId)) {
moveCardToColumn(columnId);
return true;
}
// No available auto-move
return false;
}
bool GameState::isMoveToColumnLegal(PlayingCard *cardToMove, int columnId)
{
assert(columnId >= 0 && columnId < 7);

View file

@ -17,18 +17,26 @@ class GameState : public QObject
public:
explicit GameState(QObject *parent = nullptr);
// Getters
QList<PlayingCard*> drawPile() const;
QList<PlayingCard*> throwawayPile() const;
QList<QList<ColumnSlot*>> columns() const;
QList<QList<PlayingCard*>> foundation() const;
bool gameWon() const;
// General functions
void dealCards();
void drawNextCard();
// Manual moves (from X to Y)
bool moveCardToColumn(int columnId);
bool moveThrownCardToFoundation(PlayingCard::Suit foundationId);
bool moveColumnCardToFoundation(int columnId, PlayingCard::Suit foundationId);
// Automatic moves (from X to auto)
bool autoMoveThrownCard();
bool autoMoveColumnCard(int columnId);
signals:
void drawPileChanged();
void throwawayPileChanged();
@ -47,6 +55,7 @@ private:
bool m_gameWon;
bool tryMoveCardToFoundation(PlayingCard::Suit foundationId, PlayingCard* cardToMove);
bool tryAutoMoveCard(PlayingCard* cardToMove);
bool isMoveToColumnLegal(PlayingCard* cardToMove, int columnId);
void ensureColumnRevealed(int columnId);
};