diff options
| author | Aiden Woodruff <aiden@aidenw.net> | 2024-12-12 13:06:32 -0500 |
|---|---|---|
| committer | Aiden Woodruff <aiden@aidenw.net> | 2024-12-12 13:06:32 -0500 |
| commit | eda6ef9e4f7c68d2f5281fb6ca3d832bea761d62 (patch) | |
| tree | e5c39ada55d7863ec1558ed336b383fa090f9366 | |
| parent | e50625cfb28c71be7c9ea1780ee9a3da588d4e38 (diff) | |
| download | wcards-eda6ef9e4f7c68d2f5281fb6ca3d832bea761d62.tar.gz wcards-eda6ef9e4f7c68d2f5281fb6ca3d832bea761d62.tar.bz2 wcards-eda6ef9e4f7c68d2f5281fb6ca3d832bea761d62.zip | |
add gin meld information
- gin.h (isRun): add helper function to check if a meld is a run.
- (isSet): add helper function to check if meld is a set.
- (gin::Hand): add melds vector of sets.
- (gin::Hand::Hand): reserve melds size.
- (gin::Hand::remove): add wrapper around Hand<10>::remove to disolve melds.
- (gin::Hand::meld): add function to form a new meld and disolve others with
the same cards.
- (gin::Hand): add std::ostream operator<< friend.
- print melds and then other cards.
Signed-off-by: Aiden Woodruff <aiden@aidenw.net>
| -rw-r--r-- | gin.h | 79 |
1 files changed, 75 insertions, 4 deletions
| @@ -1,4 +1,6 @@ | |||
| 1 | #include <ostream> | 1 | #include <ostream> |
| 2 | #include <set> | ||
| 3 | #include <vector> | ||
| 2 | 4 | ||
| 3 | #include "card.h" | 5 | #include "card.h" |
| 4 | #include "deck.h" | 6 | #include "deck.h" |
| @@ -13,9 +15,28 @@ namespace gin { | |||
| 13 | printf("FIXME (aiden@aidenw.net): add rules\n"); | 15 | printf("FIXME (aiden@aidenw.net): add rules\n"); |
| 14 | } | 16 | } |
| 15 | 17 | ||
| 18 | bool isRun(const std::vector<wcards::Card>& meld) { | ||
| 19 | if (meld.size() < 3) return false; | ||
| 20 | for (size_t i = 1; i < meld.size(); ++i) { | ||
| 21 | if (meld[i - 1].suit() != meld[i].suit()) return false; | ||
| 22 | if (meld[i - 1].rank() != meld[i].rank() - 1) return false; | ||
| 23 | } | ||
| 24 | return true; | ||
| 25 | } | ||
| 26 | |||
| 27 | bool isSet(const std::vector<wcards::Card>& meld) { | ||
| 28 | if (meld.size() != 3 && meld.size() != 4) return false; | ||
| 29 | for (size_t i = 1; i < meld.size(); ++i) { | ||
| 30 | if (meld[i - 1].rank() != meld[i].rank()) return false; | ||
| 31 | } | ||
| 32 | return true; | ||
| 33 | } | ||
| 34 | |||
| 16 | class Hand : public wcards::Hand<10> { | 35 | class Hand : public wcards::Hand<10> { |
| 17 | public: | 36 | public: |
| 18 | Hand(wcards::Deck& deck): wcards::Hand<10>::Hand(deck, 10) {} | 37 | Hand(wcards::Deck& deck): wcards::Hand<10>::Hand(deck, 10) { |
| 38 | melds.reserve(10); | ||
| 39 | } | ||
| 19 | bool canGin(void) const noexcept { | 40 | bool canGin(void) const noexcept { |
| 20 | //FIXME | 41 | //FIXME |
| 21 | return true; | 42 | return true; |
| @@ -33,9 +54,42 @@ namespace gin { | |||
| 33 | } | 54 | } |
| 34 | return sum; | 55 | return sum; |
| 35 | } | 56 | } |
| 57 | void remove(const Card& c) { | ||
| 58 | // Disolve any melds with c. | ||
| 59 | for (auto it = melds.begin(); it != melds.end();) { | ||
| 60 | if (it->count(c)) it = melds.erase(it); | ||
| 61 | else ++it; | ||
| 62 | } | ||
| 63 | // Remove card from cards. | ||
| 64 | wcards::Hand<10>::remove(c); | ||
| 65 | } | ||
| 36 | void meld(const std::vector<wcards::Card>& mcards) { | 66 | void meld(const std::vector<wcards::Card>& mcards) { |
| 37 | printf("FIXME(aiden@aidenw.net): meld interface"); | 67 | // Confirm this hand has all mcards. |
| 68 | for (auto it = mcards.begin(); it != mcards.end(); ++it) { | ||
| 69 | if (!has(*it)) { | ||
| 70 | std::cout << "WARN: this hand does not contain " << *it << std::endl; | ||
| 71 | return; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | // Confirm mcards is a valid meld. | ||
| 75 | if (!isRun(mcards) && !isSet(mcards)) { | ||
| 76 | printf("WARN: not a valid meld.\n"); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | // Disolve any other melds with any of mcards. | ||
| 80 | for (const Card& c : mcards) { | ||
| 81 | for (auto it = melds.begin(); it != melds.end();) { | ||
| 82 | if (it->count(c)) it = melds.erase(it); | ||
| 83 | else ++it; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | // Insert the new meld. | ||
| 87 | std::set<wcards::Card> smcards(mcards.begin(), mcards.end()); | ||
| 88 | melds.push_back(smcards); | ||
| 38 | } | 89 | } |
| 90 | friend std::ostream& operator<<(std::ostream& str, const Hand& hand); | ||
| 91 | private: | ||
| 92 | std::vector<std::set<wcards::Card>> melds; | ||
| 39 | }; | 93 | }; |
| 40 | 94 | ||
| 41 | void knock(const Hand& hand) { | 95 | void knock(const Hand& hand) { |
| @@ -46,8 +100,25 @@ namespace gin { | |||
| 46 | } | 100 | } |
| 47 | 101 | ||
| 48 | std::ostream& operator<<(std::ostream& str, const Hand& hand) { | 102 | std::ostream& operator<<(std::ostream& str, const Hand& hand) { |
| 49 | for (size_t i = 0; i < 10; ++i) { | 103 | std::set<wcards::Card> mcards; |
| 50 | if (!hand.card(i).isNone()) str << ' ' << hand.card(i); | 104 | for (size_t i = 0; i < hand.melds.size(); ++i) { |
| 105 | mcards.insert(hand.melds[i].begin(), hand.melds[i].end()); | ||
| 106 | if (i) str << ' '; | ||
| 107 | str << i << '('; | ||
| 108 | for (auto it = hand.melds[i].begin(); it != hand.melds[i].end(); ++it) { | ||
| 109 | if (it != hand.melds[i].begin()) str << ' '; | ||
| 110 | str << *it; | ||
| 111 | } | ||
| 112 | str << ')'; | ||
| 113 | } | ||
| 114 | if (!mcards.empty()) str << ' '; | ||
| 115 | for (size_t i = 0, first = 1; i < hand.size(); ++i) { | ||
| 116 | auto it = mcards.find(hand.card(i)); | ||
| 117 | if (!mcards.count(hand.card(i))) { | ||
| 118 | if (!first) str << ' '; | ||
| 119 | first = 0; | ||
| 120 | str << hand.card(i); | ||
| 121 | } | ||
| 51 | } | 122 | } |
| 52 | return str; | 123 | return str; |
| 53 | } | 124 | } |
