# Gomoku

## Game logic

<details>

<summary>Game Logic code</summary>

```python
def init_game(game_settings):
    state = {
        'player_turn_idx': 0,
        'board': [-1] * (15*15)
    }
    return state

def place_piece(state, index):
    if index < 0 or index > 224:
        raise InvalidActionError("index out of bound")
    if state['board'][index] != -1:
        raise InvalidActionError("someone already placed a piece here")
    
    player_idx = state['player_turn_idx']
    state['player_turn_idx'] = (player_idx + 1) % 2
    state['board'][index] = player_idx
    return state

def get_game_result(state):
    if __has_line(state, 0):
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    if __has_line(state, 1):
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }
    for item in state['board']:
        if item == -1:
            return {
                "game_result": "NoWinnerYet"
            }
    return {
        "game_result": "Draw"
    }

def __has_line(state, value):
    for i in range(0,15):
        for j in range(0, 11):
            #horizontal 5, i rows, j cols
            for k in range(0, 5):
                if state['board'][i*15+j+k] != value:
                    break
                if k == 4:
                    return True
            #vertical 5, i columns, j rows
            for m in range(0, 5):
                if state['board'][i+(j+m)*15] != value:
                    break
                if m == 4:
                    return True
    #down to left diagonal
    #4- 13
    if __diagnal_side(4, 14, state, 14, 0, value):
        return True
    #down to left bottom
    #14-164
    if __diagnal_bottom(14, 179, 15, state, 14, value):
        return True
    #down to right diagonal
    #1-10
    if __diagnal_side(1, 11, state, 16, 14, value):
        return True
    #down to right bottom
    #0-150
    if __diagnal_bottom(0, 165, 15, state, 16, value):
        return True
    return False

def __diagnal_side(s, e, state, interval, remainder, value):
    for i in range(s, e):
        k = 0
        while True:
            for j in range(k, k+5):
                if state['board'][i + interval*j] != value:
                    break
                if j-k == 4:
                    return True
            if (i+(k+4)*interval) % 15 == remainder:
                break
            k = k+1

def __diagnal_bottom(s, e, stp, state, interval, value):
    for i in range(s, e, stp):
        k = 0
        while True:
            for j in range(k, k+5):
                if state['board'][i + interval*j] != value:
                    break
                if j-k == 4:
                    return True
            if 224 - (i+(k+4)*interval) < 15:
                break
            k = k+1
```

</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;

/*
  Array of size 225 initialized to -1, representing an empty 15 by 15 board.
  The values of board can be -1, 0, or 1. 
  Placing a piece in index x will set the value of board[x] to the player's index.
  Array is row major order: index 0 is top left, index 14 is top right, index 210 is 
  bottom left, and index 224 is bottom right.
*/
  repeated int32 board = 2;
}

```

## Action schema

```javascript
place_piece(int index)
```

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


---

# 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/gomoku.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.
