aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <aiden@aidenw.net>2024-12-12 13:06:32 -0500
committerAiden Woodruff <aiden@aidenw.net>2024-12-12 13:06:32 -0500
commiteda6ef9e4f7c68d2f5281fb6ca3d832bea761d62 (patch)
treee5c39ada55d7863ec1558ed336b383fa090f9366
parente50625cfb28c71be7c9ea1780ee9a3da588d4e38 (diff)
downloadwcards-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.h79
1 files changed, 75 insertions, 4 deletions
diff --git a/gin.h b/gin.h
index 1521b23..52cccf0 100644
--- a/gin.h
+++ b/gin.h
@@ -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 }