# Connect Four

## Game logic

<details>

<summary>Game Logic code</summary>

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

def __index(r, c):
    return r * 7 + c

def drop_piece(state, column):
    if column < 0 or column > 7:
        raise InvalidActionError("column out of bound")

    row_to_place_disk = None
    for r in range(6):
        if state['board'][__index(r, column)] == -1:
            row_to_place_disk = r
            break  

    if row_to_place_disk is None:          
        raise InvalidActionError("column is full") 
  
    state['board'][__index(row_to_place_disk, column)] = state['player_turn_idx']       
    state["player_turn_idx"] = (state["player_turn_idx"] + 1) % 2
    return state

def get_game_result(state):
    if __has_line_horizontal(state, 0):
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    if __has_line_horizontal(state, 1):
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }

    if __has_line_vertical(state, 0):
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    if __has_line_vertical(state, 1):
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }

    if __has_line_diagonal(state, 0):
        return {
            "game_result": "Winner",
            "winner_idx": 0
        }
    if __has_line_diagonal(state, 1):
        return {
            "game_result": "Winner",
            "winner_idx": 1
        }

    for value in state['board']:
        if value == -1:
            return {
                "game_result": "NoWinnerYet"
            }
    return {
        "game_result": "Draw"
    }

def __has_line_horizontal(state, value):
    board = state['board']
    #check horizontal locations for win
    for c in range(7 - 3):
        for r in range(6):
            if board[__index(r, c)] == value and board[__index(r, c + 1)] == value and board[__index(r, c + 2)] == value and board[__index(r, c + 3)] == value:
                return True
    return False 

def __has_line_vertical(state, value):
    board = state['board']
    #check vertical locations for win 
    for c in range(7):
        for r in range(6 - 3):
            if board[__index(r, c)] == value and board[__index(1 + r, c)] == value and board[__index(2 + r, c)] == value and board[__index(3 + r, c)] == value:
                return True
    return False 

def __has_line_diagonal(state, value):
    board = state['board']
    #check negatively sloped diagonals 
    for c in range(7 - 3):
        for r in range (3, 6):
            if board[__index(r, c)] == value and board[__index(r - 1, c + 1)] == value and board[__index(r - 2, c + 2)] == value and board[__index(r - 3, c + 3)] == value:
                return True

    #check positively sloped diagonals 
    for c in range (7 - 3):
        for r in range(6 - 3):
            if board[__index(r, c)] == value and board[__index(r + 1, c + 1)] == value and board[__index(r + 2, c + 2)] == value and board[__index(r + 3, c + 3)] == value:
                return True            
    return False
```

</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 42 initialized to -1, representing an empty 6 by 7 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 from the bottom up: 
  • index 0 is bottom left
  • index 6 is bottom right
  • index 35 is top left
  • index 41 is top right
  */
  repeated int32 board = 2;
}
```

## Action schema

```javascript
drop_piece(int column)
```

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


---

# 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/connect-four.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.
