File indexing completed on 2024-05-12 08:00:35

0001 /*
0002  *  Copyright (C) 2010 Parker Coates <coates@kde.org>
0003  *
0004  *  This program is free software; you can redistribute it and/or
0005  *  modify it under the terms of the GNU General Public License as
0006  *  published by the Free Software Foundation; either version 2 of
0007  *  the License, or (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  *
0017  */
0018 
0019 #include "pileutils.h"
0020 
0021 // KCardGame
0022 #include <KCard>
0023 #include <KCardDeck>
0024 
0025 namespace
0026 {
0027 inline int alternateColor(int color)
0028 {
0029     return color == KCardDeck::Red ? KCardDeck::Black : KCardDeck::Red;
0030 }
0031 }
0032 
0033 bool isSameSuitAscending(const QList<KCard *> &cards)
0034 {
0035     if (cards.size() <= 1)
0036         return true;
0037 
0038     int suit = cards.first()->suit();
0039     int lastRank = cards.first()->rank();
0040 
0041     for (int i = 1; i < cards.size(); ++i) {
0042         ++lastRank;
0043         if (cards[i]->suit() != suit || cards[i]->rank() != lastRank)
0044             return false;
0045     }
0046     return true;
0047 }
0048 
0049 int countSameSuitDescendingSequences(const QList<KCard *> &cards)
0050 {
0051     if (cards.size() <= 1)
0052         return 0;
0053 
0054     int suit = cards.first()->suit();
0055     int lastRank = cards.first()->rank();
0056 
0057     int count = 1;
0058 
0059     for (int i = 1; i < cards.size(); ++i) {
0060         --lastRank;
0061 
0062         if (cards[i]->rank() != lastRank)
0063             return -1;
0064 
0065         if (cards[i]->suit() != suit) {
0066             count++;
0067             suit = cards[i]->suit();
0068         }
0069     }
0070     return count;
0071 }
0072 
0073 bool isSameSuitDescending(const QList<KCard *> &cards)
0074 {
0075     if (cards.size() <= 1)
0076         return true;
0077 
0078     int suit = cards.first()->suit();
0079     int lastRank = cards.first()->rank();
0080 
0081     for (int i = 1; i < cards.size(); ++i) {
0082         --lastRank;
0083         if (cards[i]->suit() != suit || cards[i]->rank() != lastRank)
0084             return false;
0085     }
0086     return true;
0087 }
0088 
0089 bool isAlternateColorDescending(const QList<KCard *> &cards)
0090 {
0091     if (cards.size() <= 1)
0092         return true;
0093 
0094     int lastColor = cards.first()->color();
0095     int lastRank = cards.first()->rank();
0096 
0097     for (int i = 1; i < cards.size(); ++i) {
0098         lastColor = alternateColor(lastColor);
0099         --lastRank;
0100 
0101         if (cards[i]->color() != lastColor || cards[i]->rank() != lastRank)
0102             return false;
0103     }
0104     return true;
0105 }
0106 
0107 bool isRankDescending(const QList<KCard *> &cards)
0108 {
0109     if (cards.size() <= 1)
0110         return true;
0111 
0112     int lastRank = cards.first()->rank();
0113 
0114     for (int i = 1; i < cards.size(); ++i) {
0115         --lastRank;
0116         if (cards[i]->rank() != lastRank)
0117             return false;
0118     }
0119     return true;
0120 }
0121 
0122 bool checkAddSameSuitAscendingFromAce(const QList<KCard *> &oldCards, const QList<KCard *> &newCards)
0123 {
0124     if (!isSameSuitAscending(newCards))
0125         return false;
0126 
0127     if (oldCards.isEmpty())
0128         return newCards.first()->rank() == KCardDeck::Ace;
0129     else
0130         return newCards.first()->suit() == oldCards.last()->suit() && newCards.first()->rank() == oldCards.last()->rank() + 1;
0131 }
0132 
0133 bool checkAddAlternateColorDescending(const QList<KCard *> &oldCards, const QList<KCard *> &newCards)
0134 {
0135     return isAlternateColorDescending(newCards)
0136         && (oldCards.isEmpty()
0137             || (newCards.first()->color() == alternateColor(oldCards.last()->color()) && newCards.first()->rank() == oldCards.last()->rank() - 1));
0138 }
0139 
0140 bool checkAddAlternateColorDescendingFromKing(const QList<KCard *> &oldCards, const QList<KCard *> &newCards)
0141 {
0142     if (!isAlternateColorDescending(newCards))
0143         return false;
0144 
0145     if (oldCards.isEmpty())
0146         return newCards.first()->rank() == KCardDeck::King;
0147     else
0148         return newCards.first()->color() == alternateColor(oldCards.last()->color()) && newCards.first()->rank() == oldCards.last()->rank() - 1;
0149 }
0150 
0151 QString suitToString(int s)
0152 {
0153     switch (s) {
0154     case KCardDeck::Clubs:
0155         return QStringLiteral("C");
0156     case KCardDeck::Hearts:
0157         return QStringLiteral("H");
0158     case KCardDeck::Diamonds:
0159         return QStringLiteral("D");
0160     case KCardDeck::Spades:
0161         return QStringLiteral("S");
0162     default:
0163         exit(-1);
0164     }
0165     return QString();
0166 }
0167 
0168 QString rankToString(int r)
0169 {
0170     switch (r) {
0171     case KCardDeck::King:
0172         return QStringLiteral("K");
0173     case KCardDeck::Ace:
0174         return QStringLiteral("A");
0175     case KCardDeck::Jack:
0176         return QStringLiteral("J");
0177     case KCardDeck::Queen:
0178         return QStringLiteral("Q");
0179     case KCardDeck::Ten:
0180         return QStringLiteral("T");
0181     default:
0182         return QString::number(r);
0183     }
0184 }
0185 
0186 QString cardToRankSuitString(const KCard *const card)
0187 {
0188     return rankToString(card->rank()) + suitToString(card->suit());
0189 }
0190 
0191 void cardsListToLine(QString &output, const QList<KCard *> &cards)
0192 {
0193     bool first = true;
0194     for (QList<KCard *>::ConstIterator it = cards.constBegin(); it != cards.constEnd(); ++it) {
0195         if (!first) {
0196             output += QLatin1Char(' ');
0197         }
0198         first = false;
0199         output += cardToRankSuitString(*it);
0200     }
0201     output += QLatin1Char('\n');
0202 }