Connect-X / app.py
alperugurcan's picture
Update app.py
2de04bc verified
raw
history blame
4.14 kB
import gradio as gr
import numpy as np
from game_logic import my_agent, Configuration, Observation
def initialize_game():
return np.zeros((6, 7), dtype=int)
def make_move(board, column, player):
"""Make a move on the board"""
for row in range(5, -1, -1):
if board[row][column] == 0:
board[row][column] = player
return board
return board
def format_board(board):
"""Convert board to player-friendly visualization"""
symbols = {0: "⚪", 1: "🔴", 2: "🟡"}
return [[symbols[cell] for cell in row] for row in board]
def check_winner(board):
"""Check if there's a winner"""
board = np.array(board)
def check_line(line):
return (len(line) >= 4 and
(any(np.all(line[i:i+4] == 1) for i in range(len(line)-3)) or
any(np.all(line[i:i+4] == 2) for i in range(len(line)-3))))
# Horizontal
for row in board:
if check_line(row):
return True
# Vertical
for col in board.T:
if check_line(col):
return True
# Diagonals
for offset in range(-2, 4):
diag = np.diagonal(board, offset)
if check_line(diag):
return True
diag = np.diagonal(np.fliplr(board), offset)
if check_line(diag):
return True
return False
def play_game(board, col, state):
if state["game_over"]:
return board, "Game is over! Click 'New Game' to play again."
# Convert Dataframe to numpy array for game logic
board_array = np.array([[0 if cell == "⚪" else 1 if cell == "🔴" else 2 for cell in row]
for row in board.values.tolist()])
# Player move
board_array = make_move(board_array, col, 1)
if check_winner(board_array):
state["game_over"] = True
return format_board(board_array), "You win! 🎉"
# AI move
config = Configuration({"rows": 6, "columns": 7, "inarow": 4})
obs = Observation({"board": board_array.flatten().tolist(), "mark": 2})
ai_col = my_agent(obs, config)
board_array = make_move(board_array, ai_col, 2)
if check_winner(board_array):
state["game_over"] = True
return format_board(board_array), "AI wins! 🤖"
return format_board(board_array), "Your turn!"
def create_ui():
with gr.Blocks(css=css) as demo:
gr.Markdown("# Play Connect Four Against AI")
gr.Markdown(f"You are {SYMBOLS[PLAYER]}, AI is {SYMBOLS[AI]}")
state = gr.State({"game_over": False})
with gr.Row(elem_classes="button-row"):
buttons = [gr.Button(str(i), size="sm") for i in range(BOARD_SIZE[1])]
board = gr.Dataframe(
value=format_board(initialize_game()),
interactive=False,
show_label=False,
headers=None,
wrap=True,
elem_id="board",
row_count=BOARD_SIZE[0],
col_count=BOARD_SIZE[1]
)
message = gr.Textbox(value="Your turn!", label="Status")
new_game = gr.Button("New Game")
def reset_game():
state = {"game_over": False}
return format_board(initialize_game()), "Your turn!", state
new_game.click(
reset_game,
outputs=[board, message, state]
)
for i, button in enumerate(buttons):
button.click(
play_game,
inputs=[board, gr.Number(value=i, visible=False), state],
outputs=[board, message]
)
return demo
# CSS definition
css = """
#board {
max-width: 400px;
margin: 20px auto;
}
#board table {
width: 100%;
table-layout: fixed;
}
#board td {
text-align: center;
font-size: 32px;
padding: 12px;
width: 14.28%; /* 100% / 7 columns */
}
.button-row {
max-width: 400px;
margin: 0 auto;
display: flex;
justify-content: space-between;
gap: 10px;
}
.button-row button {
flex: 1;
min-width: 40px;
}
"""
demo = create_ui()
demo.launch()