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 }