# Chinese Checker

## Game logic

<details>

<summary>Game Logic code</summary>

```python
def init_game(game_settings):
    state = {
        "player_turn_idx": 0,
        "board": [[-1]*9 for i in range(9)],
        "players": [[None]*10, [None]*10],
        "last_jumped": None,
        "turn": 0
    }
    count = 0
    for i in range(4):
        for j in range(i+1):
            _set_piece(state, 0, count, 3 - i, j)
            _set_piece(state, 1, count, 5 + i, 8 - j)
            count += 1
    return state

def move(state, piece_idx, x, y):
    if not _within_bound(x, y):
        raise InvalidActionError("Coordinte out of bound. Should be between 0 and 8.")
    if piece_idx < 0 or piece_idx >= 10:
        raise InvalidActionError("piece_idx out of bound. Should be between 0 and 9.")
    board = state['board']
    if board[x][y] != -1:
        raise InvalidActionError("There is already a piece at this target coordinate.")
    player_turn_idx = state['player_turn_idx']
    start = state['players'][player_turn_idx][piece_idx]
    start_x = start['x']
    start_y = start['y']

    if _is_adjacent(start_x, start_y, x, y):
        if state['last_jumped'] is not None:
            raise InvalidActionError("This piece must be used to jump over another piece.")
        board[start_x][start_y] = -1
        _set_piece(state, player_turn_idx, piece_idx, x, y)
        state['player_turn_idx'] = (player_turn_idx + 1)%2
        state['turn'] += 1
        return state
    skipped = _is_skip_adjacent(start_x, start_y, x, y)
    if skipped and board[skipped[0]][skipped[1]] != -1:
        if state['last_jumped'] is not None:
            last_jumped = state['last_jumped']
            if last_jumped['piece_idx'] != piece_idx:
                raise InvalidActionError(f"Must use piece {piece_idx} to jump or make a done_move.")
            if last_jumped['last_x'] == x and last_jumped['last_y'] == y:
                raise InvalidActionError(f"Cannot jump back to a previous location.")
        state['board'][start_x][start_y] = -1
        _set_piece(state, player_turn_idx, piece_idx, x, y)
        state['last_jumped'] = {
            'piece_idx': piece_idx,
            'last_x': start_x,
            'last_y': start_y
        }
        return state
    raise InvalidActionError("Cannot move this piece to the target position.")

def done_move(state):
    if state['last_jumped'] is None:
        raise InvalidActionError(f"Cannot make a done_move when you haven't jumped previously.")
    state['player_turn_idx'] = (state['player_turn_idx'] + 1)%2
    state['last_jumped'] = None
    state['turn'] += 1
    return state

def get_game_result(state):
    board = state['board']
    count_player_1 = 0
    count_player_2 = 0
    for i in range(4):
        for j in range(i+1):
            if board[3-i][j] == 1:
                count_player_2 += 1
            if board[5+i][8-j] == 0:
                count_player_1 += 1
    if count_player_1 == 10:
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    elif count_player_2 == 10:
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }
    if state['turn'] >= 300:
        if count_player_1 == 0 and count_player_2 == 0:
            return {
                "game_result": "Draw",
            }
        return {
            "game_result": "Winner",
            "winner_idx": 0 if count_player_1 > count_player_2 else 1
        }
    return {
        "game_result": "NoWinnerYet",
    }


def _within_bound(x, y):
    if x < 0 or y < 0 or x >= 9 or y >= 9:
        return False
    return True

def _set_piece(state, player_idx, piece_idx, x, y):
    state["board"][x][y] = player_idx
    state["players"][player_idx][piece_idx] = {
        "x": x,
        "y": y
    }

def _is_adjacent(start_x, start_y, target_x, target_y):
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, -1), (-1, 1)]
    for dir_x, dir_y in directions:
        if target_x - start_x == dir_x and target_y - start_y == dir_y:
            return True
    return False

def _is_skip_adjacent(start_x, start_y, target_x, target_y):
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, -1), (-1, 1)]
    for dir_x, dir_y in directions:
        if target_x - start_x == dir_x*2 and target_y - start_y == dir_y*2:
            return (start_x + dir_x, start_y + dir_y)
    return None
```

</details>

## Game state schema

```protobuf
message State {
  // Required field to indicate the player who should be making the next move
  // Values = 0 or 1
  int32 player_turn_idx = 1;

  repeated int32 board = 2;
}
```

## Action schema

```javascript
move(int piece_idx, int x, int y)
done_move()
```

[Start building now](https://botpot.ai/game/chinesechecker)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.botpot.ai/games/explore/chinese-checker.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
