File indexing completed on 2025-10-12 04:59:55
0001 // bjgb_shoe.h -*-C++-*- 0002 #ifndef INCLUDED_BJGB_SHOE 0003 #define INCLUDED_BJGB_SHOE 0004 0005 //@PURPOSE: Provide a value-semantic type that represents a blackjack shoe. 0006 // 0007 //@CLASSES: 0008 // bjgb::Shoe: value-semantic type representing a blackjack shoe 0009 // 0010 //@SEE_ALSO: TBD 0011 // 0012 //@DESCRIPTION: This component defines a value-semantic class, 'bjgb::Shoe', 0013 // TBD 0014 // 0015 /// Usage 0016 ///----- 0017 // This section illustrates intended use of this component. 0018 // 0019 // TBD 0020 0021 #include <bjgb_rank.h> 0022 #include <bjgb_types.h> // 'Double' 0023 0024 #include <cassert> 0025 #include <cstdint> 0026 #include <iosfwd> 0027 0028 namespace bjgb { 0029 0030 // ========== 0031 // class Shoe 0032 // ========== 0033 0034 class Shoe { 0035 // TBD class-level doc 0036 0037 // DATA 0038 std::uint8_t d_rankCounts[1 + 10]; // 10 distinct ranks in blackjack; 0039 // unused 0th element is for 0040 // convenience of indexing 0041 0042 int d_totalCards; // maintained as the sum of 0043 // 'd_rankCounts[i]', 'i > 0' 0044 0045 Types::Double d_prob[1 + 10]; // maintained as the probability of 0046 // each 'd_rankCounts[i]', 'i > 0' 0047 0048 private: 0049 // PRIVATE MANIPULATORS 0050 void updateCache(); 0051 // Private method that updates 'd_totalCards' whenever 'd_rankCounts' 0052 // changes. 0053 0054 public: 0055 // CREATORS 0056 explicit Shoe(int numDecks = 6); 0057 // Create a shoe initially containing the optionally specified 0058 // 'numDecks'. If 'numDecks' is not specified, the shoe will initially 0059 // contain 6 decks. The behavior is undefined unless '1 <= numDecks' 0060 // and 'numDecks <= 8'. 0061 0062 explicit Shoe(const int *rankCounts); 0063 // Create a shoe whose initial number of cards of each rank is provided 0064 // by the specified 'rankCounts' array. 'rankCounts[0]' provides the 0065 // number of aces, 'rankCounts[1]' the number of 2s, etc. The 0066 // behavior is undefined unless '0 <= rankCounts[i] <= 32' for 'i < 9' 0067 // and '0 <= rankCounts[9] <= 128'. 0068 0069 Shoe(const Shoe& original) = default; 0070 // Create a shoe having the same value as that of the specified 0071 // 'original' object. 0072 0073 ~Shoe() = default; 0074 // Destroy this shoe object. 0075 0076 // MANIPULATORS 0077 Shoe& operator=(const Shoe& rhs) = default; 0078 // Assign to this object the value of the specified 'rhs' shoe, and 0079 // return a reference providing modifiable access to this object. 0080 0081 void setNumCardsOfEachRank(const int *rankCounts); 0082 // Set the current number of cards of each rank in this shoe as 0083 // provided by the specified 'rankCounts' array. 'rankCounts[0]' 0084 // provides the number of aces, 'rankCounts[1]' the number of 2s, etc. 0085 // The behavior is undefined unless '0 <= rankCounts[i] <= 32' for 0086 // 'i < 9' and '0 <= rankCounts[9] <= 128'. 0087 0088 void setNumCardsOfRank(const Rank& rank, int count); 0089 // Set the current number of cards in this shoe having the specified 0090 // 'rank' to the specified 'count'. The number of cards of other ranks 0091 // is not affected. The behavior is undefined unless 0092 // '0 <= count <= 32' for 9s and below and '0 <= count <= 128' for 10s. 0093 0094 // ACCESSORS 0095 int numCards(const Rank& rank) const; 0096 // Return the current number of cards in this shoe having the specified 0097 // 'rank'. 0098 0099 int numCardsTotal() const; 0100 // Return the current number of cards of all ranks in this shoe. 0101 0102 Types::Double prob(int rank) const; 0103 // TBD preferably this would take 'const Rank&' 0104 // TBD move this to bjgc::RankProb (or something) 0105 // Return the probability of receiving a card having the specified 0106 // 'rank' from this shoe. The behavior is undefined unless '1 <= rank' 0107 // and 'rank <= 10'. 0108 }; 0109 0110 // FREE OPERATORS 0111 bool operator==(const Shoe& lhs, const Shoe& rhs); 0112 // Return 'true' if the specified 'lhs' and 'rhs' shoes have the same value 0113 // and 'false' otherwise. Two 'Shoe' objects have the same value if the 0114 // quantity of each respective rank is the same in each shoe. 0115 0116 bool operator!=(const Shoe& lhs, const Shoe& rhs); 0117 // Return 'true' if the specified 'lhs' and 'rhs' shoes do not have the 0118 // same value and 'false' otherwise. Two 'Shoe' objects do not have the 0119 // same value if the quantity of some respective rank is different in each 0120 // shoe. 0121 0122 std::ostream& operator<<(std::ostream& stream, const Shoe& shoe); 0123 // Write the value of the specified 'shoe' object to the specified output 0124 // 'stream', and return a reference to 'stream'. Note that this 0125 // human-readable format is not fully specified and can change without 0126 // notice. 0127 0128 // ============================================================================ 0129 // INLINE DEFINITIONS 0130 // ============================================================================ 0131 0132 // ---------- 0133 // class Shoe 0134 // ---------- 0135 0136 // MANIPULATORS 0137 inline void Shoe::setNumCardsOfRank(const Rank& rank, int count) 0138 { 0139 assert(0 <= count); 0140 assert(count <= (10 == rank.value() ? 128 : 32)); 0141 0142 d_rankCounts[rank.value()] = count; 0143 0144 updateCache(); 0145 } 0146 0147 // ACCESSORS 0148 inline int Shoe::numCards(const Rank& rank) const 0149 { 0150 return d_rankCounts[rank.value()]; 0151 } 0152 0153 inline int Shoe::numCardsTotal() const 0154 { 0155 return d_totalCards; 0156 } 0157 0158 inline Types::Double Shoe::prob(int rank) const 0159 { 0160 assert(1 <= rank); 0161 assert(rank <= 10); 0162 0163 return d_prob[rank]; 0164 } 0165 0166 } // namespace bjgb 0167 0168 // FREE OPERATORS 0169 inline bool bjgb::operator!=(const Shoe& lhs, const Shoe& rhs) 0170 { 0171 return !(lhs == rhs); 0172 } 0173 0174 #endif