import streamlit as st
import sqlite3
import pandas as pd
import numpy as np
from random import choice
# Global state class to store game data
class GlobalState:
def __init__(self):
self.conn = sqlite3.connect("tictactoe.db")
self.create_tables()
def create_tables(self):
cursor = self.conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS game_history (
id INTEGER PRIMARY KEY,
opponent TEXT,
difficulty TEXT,
result TEXT
)
""")
self.conn.commit()
def add_game(self, opponent, difficulty, result):
cursor = self.conn.cursor()
cursor.execute("""
INSERT INTO game_history (opponent, difficulty, result)
VALUES (?, ?, ?)
""", (opponent, difficulty, result))
self.conn.commit()
def get_game_history(self):
cursor = self.conn.cursor()
cursor.execute("SELECT * FROM game_history")
return pd.DataFrame(cursor.fetchall(), columns=["id", "opponent", "difficulty", "result"])
# Initialize global state
state = GlobalState()
# Game logic functions
def init_board():
return np.full((3, 3), "")
def check_win(board):
for row in board:
if len(set(row)) == 1 and row[0] != "":
return True
for col in board.T:
if len(set(col)) == 1 and col[0] != "":
return True
if len(set(board.diagonal())) == 1 and board[0, 0] != "":
return True
if len(set(np.fliplr(board).diagonal())) == 1 and board[0, 2] != "":
return True
return False
def check_draw(board):
return not np.any(board == "")
def make_move(board, row, col, symbol):
if board[row, col] == "":
board[row, col] = symbol
return True
return False
def ai_move(board, difficulty):
if difficulty == "easy":
empty_cells = np.argwhere(board == "")
return choice(empty_cells)
elif difficulty == "medium":
# Implement medium difficulty AI logic
pass
elif difficulty == "hard":
# Implement hard difficulty AI logic
pass
return None
# Main app layout
st.title("TicTacToe Master")
st.write("Play the classic TicTacToe game against an AI opponent or another human player.")
opponent = st.sidebar.selectbox("Choose your opponent", ["AI", "Human"])
if opponent == "AI":
difficulty = st.sidebar.selectbox("AI difficulty", ["easy", "medium", "hard"])
else:
difficulty = None
if st.sidebar.button("Restart Game"):
board = init_board()
else:
board = state.board if hasattr(state, "board") else init_board()
for i in range(3):
row_data = board[i]
row_result = st.button(row_data[0], key=f"cell_0_{i}") or st.button(row_data[1], key=f"cell_1_{i}") or st.button(row_data[2], key=f"cell_2_{i}")
if row_result:
col = int(row_result.split("_")[1])
row = int(row_result.split("_")[2])
if opponent == "Human":
symbol = "X" if state.turn == "X" else "O"
if make_move(board, row, col, symbol):
state.turn = "O" if state.turn == "X" else "X"
else:
if make_move(board, row, col, "X"):
if not check_win(board) and not check_draw(board):
ai_row, ai_col = ai_move(board, difficulty)
make_move(board, ai_row, ai_col, "O")
if check_win(board):
st.write("Game Over: Win")
state.add_game(opponent, difficulty, "win")
elif check_draw(board):
st.write("Game Over: Draw")
state.add_game(opponent, difficulty, "draw")
else:
st.write("Game in Progress")
game_history = state.get_game_history()
st.write("Game History")
st.write(game_history)
state.board = board
I asked him to build a tictactoe game, it doesn't work but the interface looks great. I guess it should try to test the interface and correct mistakes