Connect Four

Game logic

Game Logic code
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

Game state schema

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

drop_piece(int column)

Start building now

Last updated