# Rock Paper Scissors API

A minimal API for a two-player Rock Paper Scissors game.

## Base flow

1. Player 1 creates a game.
2. The API generates a random room code.
3. Player 1 is redirected to the room URL.
4. Player 2 opens the same room URL and joins the game.
5. Both players choose `rock`, `paper`, or `scissors`.
6. When both players have chosen, the API returns the result.
7. Either player can restart the round.

---

## Game states

A game can have one of the following statuses:

```text
waiting_for_player
waiting_for_choices
finished
```

### State flow

```text
POST /games
    ↓
waiting_for_player
    ↓
POST /games/{roomCode}/join
    ↓
waiting_for_choices
    ↓
Both players choose
    ↓
finished
    ↓
POST /games/{roomCode}/restart
    ↓
waiting_for_choices
```

---

# Endpoints

## Create game

Creates a new game and assigns the creator as Player 1.

```http
POST /games/create
```

### Request body

No request body required.

### Response

```json
{
  "room_code": "AdDWewD",
  "player_id": "p1",
  "player_token": "abc123",
  "status": "waiting_for_player"
}
```

The frontend can then redirect the player to:

```text
/AdDWewD
```

---

## Join game

Adds Player 2 to an existing game.

```http
POST /games/{roomCode}/join
```

Example:

```http
POST /games/AdDWewD/join
```

### Response

```json
{
  "room_code": "AdDWewD",
  "player_id": "p2",
  "player_token": "def456",
  "status": "waiting_for_choices"
}
```

### Game full

If two players have already joined:

```json
{
  "error": "game_full"
}
```

---

## Get game

Returns the current state of the game.

```http
GET /games/{roomCode}
```

Example:

```http
GET /games/AdDWewD
```

### Waiting for choices

```json
{
  "room_code": "AdDWewD",
  "status": "waiting_for_choices",
  "players": {
    "player_1": {
      "has_chosen": true
    },
    "player_2": {
      "has_chosen": false
    }
  }
}
```

A player's actual choice should not be returned until both players have chosen.

### Finished game

```json
{
  "room_code": "AdDWewD",
  "status": "finished",
  "players": {
    "player_1": {
      "choice": "rock"
    },
    "player_2": {
      "choice": "scissors"
    }
  },
  "result": {
    "winner": "player_1"
  }
}
```

For a draw:

```json
{
  "result": {
    "winner": null
  }
}
```

---

## Make choice

Submits a player's choice for the current round.

```http
POST /games/{roomCode}/choice
```

### Request body

```json
{
  "player_token": "abc123",
  "choice": "rock"
}
```

Allowed values for `choice`:

```text
rock
paper
scissors
```

### Response

If waiting for the other player:

```json
{
  "success": true,
  "status": "waiting_for_choices"
}
```

If both players have now chosen:

```json
{
  "success": true,
  "status": "finished"
}
```

The frontend should fetch the current game state using:

```http
GET /games/{roomCode}
```

to retrieve the final result.

---

## Restart game

Clears the choices and starts a new round with the same players.

```http
POST /games/{roomCode}/restart
```

### Request body

No request body required.

### Response

```json
{
  "room_code": "AdDWewD",
  "status": "waiting_for_choices"
}
```

The API should reset:

```text
player_1_choice = null
player_2_choice = null
winner = null
```

---

# Suggested game resource

A minimal internal game resource could look like this:

```json
{
  "room_code": "AdDWewD",
  "status": "waiting_for_choices",
  "player_1_token": "abc123",
  "player_2_token": "def456",
  "player_1_choice": null,
  "player_2_choice": null,
  "winner": null
}
```

---

# Endpoints summary

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/games/create` | Create a new game |
| `POST` | `/games/{roomCode}/join` | Join as Player 2 |
| `GET` | `/games/{roomCode}` | Get current game state |
| `POST` | `/games/{roomCode}/choice` | Submit rock, paper, or scissors |
| `POST` | `/games/{roomCode}/restart` | Start a new round |


### Game does not exist

If game code does not match an existing room:

```json
{
  "error": "does_not_exist"
}
```

---

# Notes

- `room_code` should be randomly generated and unique among active games.
- `player_token` identifies which player is making a request.
- Do not expose a player's choice before both players have chosen.
- The backend should determine the winner rather than the frontend.
- For the minimal implementation, the frontend can poll `GET /games/{roomCode}` to detect when the other player has joined or made a choice.
