# 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

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