Create a streamlit app that plays the game of tic-tac-toe with an AI oppoenent. Do not use the package "tensorflow".
To upload files, please first save the app
import streamlit as st
import numpy as np
# Define constants
EMPTY = 0
PLAYER_X = 1
PLAYER_O = 2
# AI Player
class AI:
def __init__(self, player):
self.player = player
def get_best_move(self, board):
available_moves = [(i, j) for i in range(3) for j in range(3) if board[i, j] == EMPTY]
best_move = None
best_score = -np.inf
for move in available_moves:
board[move] = self.player
score = self.minimax(board, False)
board[move] = EMPTY
if score > best_score:
best_score = score
best_move = move
return best_move
def minimax(self, board, is_maximizing):
winner = self.check_winner(board)
if winner == self.player:
return 1
elif winner == (PLAYER_O if self.player == PLAYER_X else PLAYER_X):
return -1
elif np.all(board != EMPTY):
return 0
if is_maximizing:
best_score = -np.inf
for i in range(3):
for j in range(3):
if board[i, j] == EMPTY:
board[i, j] = self.player
score = self.minimax(board, False)
board[i, j] = EMPTY
best_score = max(best_score, score)
return best_score
else:
best_score = np.inf
for i in range(3):
for j in range(3):
if board[i, j] == EMPTY:
board[i, j] = (PLAYER_O if self.player == PLAYER_X else PLAYER_X)
score = self.minimax(board, True)
board[i, j] = EMPTY
best_score = min(best_score, score)
return best_score
def check_winner(self, board):
# Check rows, columns and diagonals
for i in range(3):
if np.all(board[i, :] == self.player):
return self.player
if np.all(board[:, i] == self.player):
return self.player
if board[1, 1] == self.player:
if (board[0, 0] == board[2, 2] == self.player) or (board[0, 2] == board[2, 0] == self.player):
return self.player
return None
# Streamlit app
st.title('Tic Tac Toe with AI')
# Initialize state
if 'board' not in st.session_state:
st.session_state.board = np.zeros((3, 3), dtype=int)
st.session_state.turn = PLAYER_X
st.session_state.ai = AI(PLAYER_O)
st.session_state.winner = None
# Function to handle player move
def make_move(row, col):
if st.session_state.board[row, col] == EMPTY and st.session_state.winner is None:
st.session_state.board[row, col] = st.session_state.turn
st.session_state.turn = PLAYER_O
st.session_state.winner = st.session_state.ai.check_winner(st.session_state.board)
if st.session_state.winner is None and np.any(st.session_state.board == EMPTY):
ai_move = st.session_state.ai.get_best_move(st.session_state.board)
st.session_state.board[ai_move] = PLAYER_O
st.session_state.winner = st.session_state.ai.check_winner(st.session_state.board)
st.session_state.turn = PLAYER_X
# Display the board
for i in range(3):
cols = st.columns(3)
for j in range(3):
if cols[j].button('X' if st.session_state.board[i, j] == PLAYER_X else 'O' if st.session_state.board[i, j] == PLAYER_O else '', key=f'{i}-{j}'):
make_move(i, j)
# Check for winner
if st.session_state.winner:
st.success('Player' + (' X' if st.session_state.winner == PLAYER_X else ' O') + ' wins!')
elif np.all(st.session_state.board != EMPTY):
st.warning('It is a tie!')
# Reset game
if st.button('Reset Game'):
st.session_state.board = np.zeros((3, 3), dtype=int)
st.session_state.turn = PLAYER_X
st.session_state.winner = None
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?