File indexing completed on 2025-10-12 04:59:55

0001 // bjgb_rules.h                                                       -*-C++-*-
0002 #ifndef INCLUDED_BJGB_RULES
0003 #define INCLUDED_BJGB_RULES
0004 
0005 //@PURPOSE: Provide a value-semantic type to represent the rules of blackjack.
0006 //
0007 //@CLASSES:
0008 //  bjgb::Rules: value-semantic type representing blackjack rules
0009 //
0010 //@SEE_ALSO:
0011 //
0012 //@DESCRIPTION: This component defines a value-semantic class, 'bjgb::Rules',
0013 // TBD
0014 //
0015 /// Usage
0016 ///-----
0017 // This section illustrates intended use of this component.
0018 //
0019 // TBD
0020 
0021 #include <bjgb_state.h>
0022 #include <bjgb_types.h> // 'Double'
0023 
0024 #include <cassert>
0025 #include <iosfwd>
0026 
0027 namespace bjgb {
0028 
0029 // ===========
0030 // class Rules
0031 // ===========
0032 
0033 class Rules {
0034     // This value-semantic attribute type represents the rules of blackjack.
0035 
0036     // DATA
0037     bool d_dealerStandsOnSoft17; // dealer must stand on soft 17
0038 
0039     bool d_playerMaySurrender; // player may surrender on any two
0040                                // cards (to an A or T dealer up card)
0041 
0042     bool d_oneCardToSplitAce; // player gets one card to a split Ace
0043 
0044     bool d_playerMayResplitAces; // player may resplit Aces
0045 
0046     bool d_playerCanLoseDouble; // player can lose double when
0047                                 // doubling down against a 10 or Ace
0048                                 // dealer up card
0049 
0050     bool d_playerMayDoubleAny2Cards; // player may double down on any
0051                                      // 2-card hand; if 'false', check
0052                                      // 'd_doubleableHand' array
0053 
0054     // TBD this needs to be rethought; bjgb_rule should not depend on
0055     // bjgb_state nor is populating this array convenient for the client
0056     bool d_doubleableHand[State::k_NUM_STATES];
0057     // array of (2-card) hands for which
0058     // player may double down; should be
0059     // queried when
0060     // 'd_playerMayDoubleAny2Cards' is
0061     // 'false'
0062 
0063     int d_playerMaxNumHands; // maximum number of player hands; one
0064                              // more than maximum splits allowed
0065 
0066     Types::Double d_playerBjPayout; // blackjack payout
0067 
0068     // FRIENDS
0069     friend bool operator==(const Rules&, const Rules&);
0070     friend std::ostream& operator<<(std::ostream&, const Rules&);
0071 
0072   public:
0073     // CREATORS
0074     Rules();
0075     // Create a 'Rules' object and initialize it with the rules in effect
0076     // on the high-rollers' tables at the casinos in Atlantic City, New
0077     // Jersey.
0078 
0079     Rules(const Rules& original) = default;
0080     // Create a 'Rules' object having the same value as that of the
0081     // specified 'original' object.
0082 
0083     // MANIPULATORS
0084     Rules& operator=(const Rules& rhs) = default;
0085     // Assign to this object the value of the specified 'rhs' object, and
0086     // return a reference providing modifiable access to this object.
0087 
0088     void reset();
0089     // Reset this object to the default-constructed state.
0090 
0091     // Dealer Rules
0092 
0093     void setDealerStandsOnSoft17(bool value);
0094     // Set the "DealerStandsOnSoft17" attribute of this 'Rules' object to
0095     // have the specified 'value'.
0096 
0097     // Player Rules
0098 
0099     void setPlayerBlackjackPayout(Types::Double value);
0100     // Set the "PlayerBlackjackPayout" attribute of this 'Rules' object to
0101     // have the specified 'value'.  The behavior is undefined unless
0102     // '1.0 <= value';
0103 
0104     void setPlayerCanLoseDouble(bool value);
0105     // Set the "PlayerCanLoseDouble" attribute of this 'Rules' object to
0106     // have the specified 'value'.
0107 
0108     void setPlayerMayDoubleOnAnyTwoCards(bool value);
0109     // Set the "PlayerMayDoubleOnAnyTwoCards" attribute of this 'Rules'
0110     // object to have the specified 'value'.
0111 
0112     void setPlayerMayDoubleOnTheseTwoCards(const bool *doubleableHand);
0113     // Set the "PlayerMayDoubleOnTheseTwoCards" attribute of this 'Rules'
0114     // object to have the contents of the specified 'doubleableHand'
0115     // array.
0116 
0117     void setPlayerMayResplitAces(bool value);
0118     // Set the "PlayerMayResplitAces" attribute of this 'Rules' object to
0119     // have the specified 'value'.
0120 
0121     void setPlayerMaySurrender(bool value);
0122     // Set the "PlayerMaySurrender" attribute of this 'Rules' object to
0123     // have the specified 'value'.
0124 
0125     void setPlayerGetsOneCardOnlyToSplitAce(bool value);
0126     // Set the "PlayerGetsOneCardOnlyToSplitAce" attribute of this 'Rules'
0127     // object to have the specified 'value'.
0128 
0129     void setPlayerMaxNumHands(int value);
0130     // Set the "PlayerMaxNumHands" attribute of this 'Rules' object to have
0131     // the specified 'value'.  The behavior is undefined unless
0132     // '0 > value'.
0133 
0134     // ACCESSORS
0135 
0136     // Dealer Rules
0137 
0138     bool dealerStandsOnSoft17() const;
0139     // Return the value of the "DealerStandsOnSoft17" attribute of this
0140     // 'Rules' object.
0141 
0142     // Player Rules
0143 
0144     Types::Double playerBlackjackPayout() const;
0145     // Return the value of the "PlayerBlackjackPayout" attribute of this
0146     // 'Rules' object.
0147 
0148     bool playerCanLoseDouble() const;
0149     // Return the value of the "PlayerCanLoseDouble" attribute of this
0150     // 'Rules' object.
0151 
0152     bool playerMayDoubleOnAnyTwoCards() const;
0153     // Return the value of the "PlayerMayDoubleOnAnyTwoCards" attribute of
0154     // this 'Rules' object.
0155 
0156     bool playerMayDoubleOnTheseTwoCards(int handValue, bool isSoftCount) const;
0157     // Return 'true' if the "PlayerMayDoubleOnTheseTwoCards" attribute of
0158     // this 'Rules' object indicates that a player may double on a 2-card
0159     // hand having the specified 'handValue', and 'false' otherwise.  If
0160     // the specified 'isSoftCount' flag is 'true' then 'handValue' is
0161     // interpreted as a soft count, otherwise 'handValue' is interpreted as
0162     // a hard count.  The behavior is undefined unless '2 <= handValue',
0163     // 'handValue <= 20', 'handValue >= 4 || isSoftCount', and
0164     // 'handValue <= 11 || !isSoftCount'.  Note that this method need not
0165     // be called if 'playerMayDoubleOnAnyTwoCards' returns 'true'.
0166 
0167     bool playerMayResplitAces() const;
0168     // Return the value of the "PlayerMayResplitAces" attribute of this
0169     // 'Rules' object.
0170 
0171     bool playerMaySurrender() const;
0172     // Return the value of the "PlayerMaySurrender" attribute of this
0173     // 'Rules' object.
0174 
0175     bool playerGetsOneCardOnlyToSplitAce() const;
0176     // Return the value of the "PlayerGetsOneCardOnlyToSplitAce" attribute
0177     // of this 'Rules' object.
0178 
0179     int playerMaxNumHands() const;
0180     // Return the value of the "PlayerMaxNumHands" attribute of this
0181     // 'Rules' object.
0182 };
0183 
0184 // FREE OPERATORS
0185 bool operator==(const Rules& lhs, const Rules& rhs);
0186 // Return 'true' if the specified 'lhs' and 'rhs' 'Rules' objects have the
0187 // same value and 'false' otherwise.  Two 'Rules' objects have the same
0188 // value if each of their attributes (respectively) have the same value.
0189 
0190 bool operator!=(const Rules& lhs, const Rules& rhs);
0191 // Return 'true' if the specified 'lhs' and 'rhs' 'Rules' objects do not
0192 // have the same value and 'false' otherwise.  Two 'Rules' objects do not
0193 // have the same value if any of their attributes (respectively) do not
0194 // have the same value.
0195 
0196 std::ostream& operator<<(std::ostream& stream, const Rules& rules);
0197 // Write the value of the specified 'rules' object to the specified output
0198 // 'stream', and return a reference to 'stream'.  Note that this
0199 // human-readable format is not fully specified and can change without
0200 // notice.
0201 
0202 // ============================================================================
0203 //                              INLINE DEFINITIONS
0204 // ============================================================================
0205 
0206 // -----------
0207 // class Rules
0208 // -----------
0209 
0210 // MANIPULATORS
0211 
0212 // Dealer Rules
0213 
0214 inline void Rules::setDealerStandsOnSoft17(bool value)
0215 {
0216     d_dealerStandsOnSoft17 = value;
0217 }
0218 
0219 // Player Rules
0220 
0221 inline void Rules::setPlayerBlackjackPayout(Types::Double value)
0222 {
0223     assert(1.0 <= value);
0224 
0225     d_playerBjPayout = value;
0226 }
0227 
0228 inline void Rules::setPlayerCanLoseDouble(bool value)
0229 {
0230     d_playerCanLoseDouble = value;
0231 }
0232 
0233 inline void Rules::setPlayerMayDoubleOnAnyTwoCards(bool value)
0234 {
0235     d_playerMayDoubleAny2Cards = value;
0236 }
0237 
0238 inline void Rules::setPlayerMayResplitAces(bool value)
0239 {
0240     d_playerMayResplitAces = value;
0241 }
0242 
0243 inline void Rules::setPlayerMaySurrender(bool value)
0244 {
0245     d_playerMaySurrender = value;
0246 }
0247 
0248 inline void Rules::setPlayerGetsOneCardOnlyToSplitAce(bool value)
0249 {
0250     d_oneCardToSplitAce = value;
0251 }
0252 
0253 inline void Rules::setPlayerMaxNumHands(int value)
0254 {
0255     assert(0 < value);
0256 
0257     d_playerMaxNumHands = value;
0258 }
0259 
0260 // ACCESSORS
0261 
0262 // Dealer Rules
0263 
0264 inline bool Rules::dealerStandsOnSoft17() const
0265 {
0266     return d_dealerStandsOnSoft17;
0267 }
0268 
0269 // Player Rules
0270 
0271 inline Types::Double Rules::playerBlackjackPayout() const
0272 {
0273     return d_playerBjPayout;
0274 }
0275 
0276 inline bool Rules::playerCanLoseDouble() const
0277 {
0278     return d_playerCanLoseDouble;
0279 }
0280 
0281 inline bool Rules::playerMayDoubleOnAnyTwoCards() const
0282 {
0283     return d_playerMayDoubleAny2Cards;
0284 }
0285 
0286 inline bool Rules::playerMayResplitAces() const
0287 {
0288     return d_playerMayResplitAces;
0289 }
0290 
0291 inline bool Rules::playerMaySurrender() const
0292 {
0293     return d_playerMaySurrender;
0294 }
0295 
0296 inline bool Rules::playerGetsOneCardOnlyToSplitAce() const
0297 {
0298     return d_oneCardToSplitAce;
0299 }
0300 
0301 inline int Rules::playerMaxNumHands() const
0302 {
0303     return d_playerMaxNumHands;
0304 }
0305 
0306 } // namespace bjgb
0307 
0308 // FREE OPERATORS
0309 inline bool bjgb::operator!=(const Rules& lhs, const Rules& rhs)
0310 {
0311     return !(lhs == rhs);
0312 }
0313 
0314 #endif