# Rock paper scissors
## Code name
`rps` (using abbreviation because the full name is terribly long.)
## About this game
Please references:
- A document at https://en.wikipedia.org/wiki/Rock_paper_scissors

Rock paper scissors (also known as scissors rock paper, paper rock scissors and
scissors paper stone) is a hand game usually played between two people, in which
each player simultaneously forms one of three shapes with an outstretched hand.
These shapes are "rock" (a closed fist), "paper" (a flat hand), and "scissors"
(a fist with the index finger and middle finger extended, forming a V).
"Scissors" is identical to the two-fingered V sign (also indicating "victory" or
"peace") except that it is pointed horizontally instead of being held upright in
the air. A simultaneous, zero-sum game, it has only two possible outcomes: a
draw, or a win for one player and a loss for the other.
The rules of games:
 A player
who decides to play rock will beat another player who has chosen scissors ("rock
crushes scissors" or sometimes "blunts scissors"[1]), but will lose to one who
has played paper ("paper covers rock"); a play of paper will lose to a play of
scissors ("scissors cuts paper"). If both players choose the same shape, the
game is tied and is usually immediately replayed to break the tie
## Technical solution
### DB
4 main tables:
- `rock_paper_scissors_game_record`
- `id`, `ctime`: read-only, hence, no `mtime`
- `user_id`
- `partner_id`
- `total_bet_amount`
- `total_reward_amount`
- `left_hand`: `ROCK`, `PAPER`, `SCISSORS`
- `right_hand`: `ROCK`, `PAPER`, `SCISSORS`
- `rock_paper_scissors_bet_record`
- `id`, `ctime`: read-only, hence, no `mtime`
- `rock_paper_scissors_game_record_id`
- `game_type`: `LEFT_HANDED_SCISSORS`, `LEFT_HANDED_ROCK`
- `result_type`: `UserWin` (1), `UserLost` (2), `Draw` (3)
- `bet_amount`
- `reward_amount`
- `rock_paper_scissors_config`
- `id`, `ctime`,`mtime`
- `status`
- `partner_id`
- `bet_min`
- `bet_max`
- `rock_paper_scissors_game_type_config`
- `rock_paper_scissors_config_id`: ref to `rock_paper_scissors_config`
- `id`, `ctime`,`mtime`
- `status`
- `game_type`: `enum such as LEFT_HANDED_SCISSORS, LEFT_HANDED_ROCK, ...`
- `odds`: `1`
### Enum
- LEFT_HANDED_SCISSORS
- LEFT_HANDED_ROCK
- LEFT_HANDED_PAPER
- RIGHT_HANDED_SCISSORS
- RIGHT_HANDED_ROCK
- RIGHT_HANDED_PAPER
- LEFT_HANDED
- RIGHT_HANDED
- DRAW
### RPC API
#### User to place bet
```
POST /api/game/rock_paper_scissors/bet
```
##### The bet on `LEFT_HANDED_SCISSORS`, `DRAW`
Request:
```json
{
"bets": [
{ "bet_amount": 10, "game_type": "LEFT_HANDED_SCISSORS" },
{ "bet_amount": 20, "game_type": "DRAW" }
]
}
```
Response
```json
{
"left_handed": "SCISSORS",
"right_handed": "PAPER",
"bet_records": [
{
"bet_amount": 10,
"game_type": "LEFT_HANDED_SCISSORS",
"game_result": 1,
"reward_amount": 20
},
{
"bet_amount": 20,
"game_type": "DRAW",
"game_result": 2,
"reward_amount": 0
}
],
"total_reward_amount": 20,
"total_bet_amount": 30
}
```
##### The bet on `LEFT_HANDED_PAPER`, `DRAW`
Request:
```json
{
"bets": [
{ "bet_amount": 10, "game_type": "LEFT_HANDED_PAPER" },
{ "bet_amount": 20, "game_type": "DRAW" }
]
}
```
Response
```json
{
"left_handed": "SCISSORS",
"right_handed": "SCISSORS",
"bet_records": [
{
"bet_amount": 10,
"game_type": "LEFT_HANDED_PAPER",
"game_result": 2,
"reward_amount": 0
},
{
"bet_amount": 20,
"game_type": "DRAW",
"game_result": 1,
"reward_amount": 40
}
],
"total_reward_amount": 40,
"total_bet_amount": 30
}
```
#### The Rock paper scissors configuration API
```
POST /api/game/rock_paper_scissors_config
```
Request:
```json
{
"partner_id": 1,
"status": 1,
"bet_min": 1,
"bet_max": 1000
}
```
### Implementation
#### User to place bet
- A user enter rock_paper_scissors table and betting one of nine box
(LEFT_HANDED_SCISSORS, LEFT_HANDED_ROCK, ...)
- 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 of three shapes (rock, paper, scissors)
- CB compute bet result, and reward if user win or draw that bet
- CB create a `rock_paper_scissors_game_record`, `rock_paper_scissors_bet_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 Rock paper scissors configuration API
POST `/api/game/rock_paper_scissors_config`<br/>
POST `/api/game/rock_paper_scissors_game_type_config`<br/>
- Authentication the request from partner
- Validate the request
- Save the configuration to DB