# Hex

## Game logic

<details>

<summary>Game Logic code</summary>

```python
def init_game(game_settings):
    state = {
        'player_turn_idx':  0,
        'pieces':  []
    }
    return state

def place_piece(state, row, column):
    WIDTH = 11
    HEIGHT = 11
    INVALID_ACTION_NOT_YOUR_TURN = "Not your turn."
    INVALID_ACTION_OUT_OF_BOUND = "Location is out of bound."
    INVALID_ACTION_ALREADY_PLACED = "A piece is already placed here."
    if __is_out_of_bound(row, column, WIDTH, HEIGHT):
        raise InvalidActionError(INVALID_ACTION_OUT_OF_BOUND)
    for piece in state['pieces']:
        if piece['row'] == row and piece['column'] == column:
            raise InvalidActionError(INVALID_ACTION_ALREADY_PLACED)
    player_idx = state['player_turn_idx']
    state['pieces'].append({
        'row': row, 
        'column': column, 
        'value': player_idx
        })

    state['player_turn_idx'] = (player_idx + 1) % 2
    return state

def __is_bottom(coord, board_width, board_height):
    return coord[0] == 0

def __is_top(coord, board_width, board_height):
    return coord[0] == board_height - 1

def __is_left(coord, board_width, board_height):
    return coord[1] == 0

def __is_right(coord, board_width, board_height):
    return coord[1] == board_width - 1

def __has_path_to(state, is_initial_func, is_target_func, player_idx, board_width, board_height):
    """
    Does a dfs search to see if a piece that satisfies the initial func
    is connected to a piece that satisfies sthe target func.
    <is_initial_func> is a function that returns a boolean if a piece
    satisfies the initial condition.
    """
    visited = set()
    stack = []
    has_target = False
    piece_coords = set()
    for piece in state['pieces']:
        coord = (piece['row'], piece['column'])
        if piece['value'] == player_idx:
            piece_coords.add(coord)
        else:
            continue
        if is_initial_func(coord, board_width, board_height):
            stack.append(coord)
        if is_target_func(coord, board_width, board_height):
            has_target = True
        
    if not is_initial_func or not has_target:
        return False

    while len(stack) > 0:
        this_coord = stack.pop()
        if is_target_func(this_coord, board_width, board_height):
            return True
        if this_coord in visited:
            continue
        visited.add(this_coord)
        neighbors = __get_neighbors(this_coord[0], this_coord[1], board_width, board_height)
        for n in neighbors:
            if n in piece_coords:
                stack.append(n)
    return False

def __is_out_of_bound(row, column, board_width, board_height):
    return (row < 0 or row >= board_height
        or column < 0 or column >= board_width)

def __get_neighbors(row, column, board_width, board_height):
    if __is_out_of_bound(row, column, board_width, board_height):
        return []
    neighbors = []
    if column > 0:
        neighbors.append((row, column - 1))
    if column < board_width - 1:
        neighbors.append((row, column + 1))
    if row > 0:
        neighbors.append((row - 1, column))
        if column < board_width - 1:
            neighbors.append((row - 1, column + 1))
    if row < board_height - 1:
        neighbors.append((row + 1, column))
        if column > 0:
            neighbors.append((row + 1, column - 1))
    return neighbors

def get_game_result(state):
    WIDTH = 11
    HEIGHT = 11
    player1_has_path = __has_path_to(
        state, __is_left, __is_right, 0, WIDTH, HEIGHT)
    player2_has_path = __has_path_to(
        state, __is_top, __is_bottom, 1, WIDTH, HEIGHT)
    if (player1_has_path and player2_has_path):
        return {
            "game_result": "Draw"
        }
    elif (player1_has_path and not player2_has_path):
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    elif (player2_has_path and not player1_has_path):
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }
    else:
        return {
            "game_result": "NoWinnerYet"
        }
```

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

  // All the pieces on the board that a player has put down. Player idx 0 tries
  // to connect left to right (column = 0 to column = 10). Plyaer idx 1 tries
  // to connect bottom to top (row = 0 to row = 10). 
  repeated Piece pieces = 2;
}
```

```protobuf
message Piece {
  // Row of the piece that has been placed. 
  int32 row = 1;

  // Column of the piece that has been placed.
  int32 column = 2;

  // value is the player_idx who placed this piece, can be 0 or 1.
  int32 value = 3;
}
```

## Action schema

```javascript
place_piece(int row, int column)
```

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


---

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