# Baccarat ## Code name `baccarat` ## About this game Please references: - A video at https://www.youtube.com/watch?v=juMyMuf7Cdo - A document at http://www.casinator.com/casino-games/learn-how-to-play-baccarat.php#3rd ![Normal Baccarat](./img/baccarat.jpg) Baccarat is a simple card game: In the regular version of baccarat (also called formal, traditional, or big baccarat), the croupier, or dealer, deals only two hands, no matter how many players are seated at the table — and as many as 14 can play. One hand is the player’s hand, and the other is the banker’s hand. The object of the game is to bet on which of the two hands will come closest to a total of 9 points, also called a natural (a total of 8 points is also a natural, but it loses to 9). Players make all bets before the croupier deals the cards. You have only three bets to choose from in baccarat. You can bet on: - The player’s hand: A winning bet on the player's hand pays event money (1 to 1). So a winning bet of $10 would receive another $10 - The banker’s hand: A win on the banker's hand also pays even money, minus a 5 percent commission. So a winning bet of $10 would actually end up netting only $9.50. However the croupier only charges this 5 percent commission on winning bets. - A tie: A winning wager on the tie bet pays 8 to 1. Both hands start with just two cards, and depending on the starting total, the banker or player hand sometimes draws one more card. Whichever hand comes closest to nine wins. Because 9 is the highest score, any amount of 10 or more automatically subtracts ten points; ten is actually worth 0, 11 is 1, 12 is 2, and so on. After the total reaches 10 or more, simply drop the first digit, and that’s the score of the hand The values of the cards are as follows: - K, Q, J, 10 = 0 points - Aces = 1 - All other cards = face value If neither hand has a total of 8 or 9, an additional card may be drawn on one or both hands, depending on the amount in the hand Following the player’s rules To draw an additional card, the banker’s hand is dependent on the total of the player’s hand | Value of Player’s Hand | What to Do | | ---------------------- | ------------------- | | 8 or 9 | Stands on a natural | | 6 or 7 | Stands | | 0 to 5 | Draws a card | Following the banker’s rules The banker’s hand follows these same player’s rules as long as the player’s hand does not draw a third card. If the player’s hand draws a third card, the situation gets a little more complicated, and the banker’s hand must follow special banker’s rules. The following section explains what happens when the player’s hand draws a third card Adhering to the banker’s rules The banker’s rules apply only to the banker’s hand, and only in those situations when the player’s hand draws a third card | Value of Banker's Two Cards | Banker’s Action | | --------------------------- | -------------------------------------- | | 8 or 9 | Stands on a natural | | 7 | Stands according to player’s rules | | 6 | Draws if player draws a third card and | | | player’s new hand total is 6 or 7 | | 5 | Draws if player draws a third card and | | | player’s new hand total is 4 through 7 | | 4 | Draws if player draws a third card and | | | player’s new hand total is 2 through 7 | | 3 | Draws if player draws a third card and | | | player’s new total is 0 through 9 | | 0, 1, or 2 | Draws a card | > Note: Neither the player nor the banker will ever have more than three cards > in hand, but the goal is simple: whichever hand has the higher total wins. > Note: Because a tie hand is a push (neither the player nor the banker wins), > your bet on either the player or the banker is also a push — and you won’t > lose any money for that hand. Examples: When the Banker Can Draw After a Player’s Third Card | Banker’s Score | Player’s Third Card | | -------------- | ------------------- | | | 0 1 2 3 4 5 6 7 8 9 | | 7 | S S S S S S S S S S | | 6 | S S S S S S D D S S | | 5 | S S S S D D D D S S | | 4 | S S D D D D D D S S | | 3 | D D D D D D D D S D | | 2 | D D D D D D D D D D | | 1 | D D D D D D D D D D | | 0 | D D D D D D D D D D | > S = STAND D = DRAW ## Technical solution ### DB 3 main tables: - `baccarat_game_record` - `id`, `ctime`: read-only, hence, no `mtime` - `user_id` - `reward_amount` - `result_type`: `UserWin` (1), `UserLost` (2), `Draw` (3) - `game_type`: `BaccaratGameBetOnPlayer` (1) or `BaccaratGameBetOnBanker` (2) or `BetBaccaratGameBetTie` (3),... - `bet_amount` - `baccarat_config` - `id`, `ctime`,`mtime` - `status` - `partner_id` - `bet_min` - `bet_max` - `baccarat_odds_config` - `baccarat_config_id`: ref to `baccarat_config` - `id`, `ctime`,`mtime` - `status` - `game_type`: `enum such as BaccaratGameBetOnPlayer, BaccaratGameBetOnBanker, ...` - `odds`: `1` ### Cards Enum We will prepend the letters C (clubs), S(spades), D(diamonds) and H(hearts) before the cards number of character to distinguish them. - Examples: "C1", "S2", "DJ", .. Note that Ace is just denoted as `1`. ### RPC API #### User to place bet ``` POST /api/game/baccarat/bet ``` ##### BetOnPlayer Odds: 1 to 1 Request: ```json { "game_type": 1, "bet_amount": 10 } ``` Response format for `UserWin` case: ```json { "player": ["CJ", "S10", "D5"], "banker": ["D1", "D3", "S9"], "reward_amount": 20, "game_type": 1, "bet_amount": 10 } ``` - Player score: 0 + 0 + 5 = 5 - Banker score: 1 + 3 + 9 = 3 Response format for `UserLose` case, note that `reward_amount` is 0 in this case: ```json { "player": ["S1", "HJ", "CJ"], "banker": ["D1", "C3"], "reward_amount": 0, "bet_amount": 10, "game_type": 1 } ``` - Player score: 1 + 0 + 0 = 1 - Banker score: 1 + 3 = 4 Response format for `Draw` case, note `reward_amount` is equal to the `bet_amount` from the request: ```json { "player": ["HJ", "41", "SQ"], "banker": ["D3", "CK", "H1"], "reward_amount": 10, "bet_amount": 10, "game_type": 1 } ``` - Player score: 0 + 4 + 0 = 4 - Banker score: 3 + 0 + 1 = 4 ##### BetOnBanker Odds: 0.95 to 1 Request, note that we change the `bet_amount` to 100 to avoid floating point number in the following examples: ```json { "game_type": 2, "bet_amount": 100 } ``` Response format for `UserWin` case, here `reward_amount` is `100+95` instead of `200` due to the rule: ```json { "player": ["S7", "C9"], "banker": ["H1", "C8"], "reward_amount": 195, "game_type": 2, "bet_amount": 100 } ``` - Player score: 7 + 9 = 16 module 10 = 6 - Banker score: 1 + 8 = 9 Response format for `UserLose` case, note that `reward_amount` is 0: ```json { "player": ["H10", "C6"], "banker": ["DK", "S1", "C2"], "reward_amount": 0, "game_type": 2, "bet_amount": 100 } ``` - Player score: 0 + 6 = 6 - Banker score: 0 + 1 + 2 = 3 Response format for `Draw` case, `reward_amount` is equal to the `bet_amount` from request: ```json { "player": ["C10", "S9"], "banker": ["D1", "D8"], "reward_amount": 100, "bet_amount": 100, "game_type": 2 } ``` - Player score: 0 + 9 = 9 - Banker score: 1 + 8 = 9 ##### BetTie Odds: 8 to 1. Request: ```json { "game_type": 3, "bet_amount": 10 } ``` Response format for `UserWin` case, here the `reward_amount` is `10 + 8*10`: ```json { "player": ["9s", "2s", "Jh"], "banker": ["5h", "6s", "Jc"], "reward_amount": 90, "game_type": 3, "bet_amount": 10 } ``` - Player score: 9 + 2 + 0 = 11 module 10 = 1 - Banker score: 5 + 6 + 0 = 11 module 10 = 1 Response format for `UserLose` case: ```json { "player": ["H1", "C9", "S3"], "banker": ["S4", "H6", "C10"], "reward_amount": 0, "game_type": 3, "bet_amount": 10 } ``` - Player score: 1 + 9 + 3 = 3 - Banker score: 4 + 6 + 10 = 0 There's no way a `Draw` result can happend with this type of bet. #### The baccarat configuration API ``` POST /api/game/baccarat_config ``` RPC `/api/game/baccarat_config` Request: ```json { "bet_min": 1, "bet_max": 1000 } ``` RPC `/api/game/baccarat_odds_config` Request: ```json [ { "baccarat_config_id": 1, "game_type": "BaccaratGameBetOnPlayer", "odds": 1 }, { "baccarat_config_id": 1, "game_type": "BaccaratGameBetOnBanker", "odds": 8 } ] ``` ### Implementation #### User to place bet - A user enter baccarat table and betting the banker or the player or tie - Card backend (CB) authorize user session. If session valid move to next step, otherwise return 401 - CB validate user's bets. If request valid move to next step, otherwise return 403 - validate whether `game_type` and `bet_amount` are valid - validate whether total bet amount exceed user's balance - CB generate two cards or three cards for player and banker follow the above rules - CB compute bet result, and reward if user win or draw that bet - CB create a `baccarat_game_record` - CB create a bet transaction - CB update user wallet, that the balance is deducted by total amount of user's bets - If the user win any bet, reward user - CB create a reward transaction, with change equal to total reward amount - CB update user wallet, that the balance is added up by total reward amount - CB return back to user #### The baccarat configuration API RPC `/api/game/baccarat_config`<br/> RPC `/api/game/baccarat_odds_config` - Authentication the request from partner - Validate the request - Save the configuration to DB