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