Updated AI tac_tac_toe agent
This commit is contained in:
parent
81b75cf72c
commit
aa49a0dcc9
8 changed files with 320 additions and 657 deletions
|
|
@ -1,32 +1,23 @@
|
||||||
# 🎮 Agent X vs Agent O: Tic-Tac-Toe Game
|
# 🎮 Agent X vs Agent O: Tic-Tac-Toe Game
|
||||||
|
|
||||||
An interactive Tic-Tac-Toe game where two AI agents powered by different language models compete against each other built on Agno Agent Framework and Streamlit as UI. Watch as GPT-4O battles against either DeepSeek V3 or Google's Gemini 1.5 Flash in this classic game.
|
An interactive Tic-Tac-Toe game where two AI agents powered by different language models compete against each other built on Agno Agent Framework and Streamlit as UI.
|
||||||
|
|
||||||
|
This example shows how to build an interactive Tic Tac Toe game where AI agents compete against each other. The application showcases how to:
|
||||||
|
- Coordinate multiple AI agents in a turn-based game
|
||||||
|
- Use different language models for different players
|
||||||
|
- Create an interactive web interface with Streamlit
|
||||||
|
- Handle game state and move validation
|
||||||
|
- Display real-time game progress and move history
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
- Multiple AI models support (GPT-4, Claude, Gemini, etc.)
|
||||||
|
- Real-time game visualization
|
||||||
|
- Move history tracking with board states
|
||||||
|
- Interactive player selection
|
||||||
|
- Game state management
|
||||||
|
- Move validation and coordination
|
||||||
|
|
||||||
### Multi-Agent System
|
## How to Run?
|
||||||
- Player X: OpenAI's Gemini Flash 2.0
|
|
||||||
- Player O: DeepSeek v3
|
|
||||||
- Judge: GPT-4o for game outcome validation
|
|
||||||
|
|
||||||
### Interactive Interface
|
|
||||||
- Real-time game board visualization
|
|
||||||
- Move-by-move analysis
|
|
||||||
- Agent response tracking
|
|
||||||
- Clear game status updates
|
|
||||||
|
|
||||||
### Strategic Gameplay
|
|
||||||
- AI-powered move decisions
|
|
||||||
- Winning strategy implementation
|
|
||||||
- Opponent move blocking
|
|
||||||
- Victory condition monitoring
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
- Python 3.8+
|
|
||||||
- OpenAI API key
|
|
||||||
- Either DeepSeek API key or Google API key (for Player O)
|
|
||||||
|
|
||||||
## How to Run
|
|
||||||
|
|
||||||
1. **Setup Environment**
|
1. **Setup Environment**
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -38,40 +29,78 @@ An interactive Tic-Tac-Toe game where two AI agents powered by different languag
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Configure API Keys**
|
### 2. Install dependencies
|
||||||
- Get OpenAI API key from [OpenAI Platform](https://platform.openai.com)
|
|
||||||
- Get Google API key from [Google AI Studio](https://aistudio.google.com) (if using Gemini)
|
|
||||||
- Get DeepSeek API key from DeepSeek platform [Deepseek platform](https://www.deepseek.com) (if using DeepSeek v3 model)
|
|
||||||
|
|
||||||
4. **Run the Application**
|
```shell
|
||||||
```bash
|
pip install -r requirements.txt
|
||||||
streamlit run ai_tic_tac_toe_agent.py
|
```
|
||||||
```
|
|
||||||
|
|
||||||
5. **Using the Interface**
|
### 3. Export API Keys
|
||||||
- Enter your API keys in the sidebar
|
|
||||||
- Click "Start Game" to begin
|
|
||||||
- Watch as the AI agents battle it out!
|
|
||||||
- Monitor the game progress and final results
|
|
||||||
|
|
||||||
## Game Components
|
The game supports multiple AI models. Export the API keys for the models you want to use:
|
||||||
|
|
||||||
- **Game Board**
|
```shell
|
||||||
- 3x3 interactive grid
|
# Required for OpenAI models
|
||||||
- Real-time move visualization
|
export OPENAI_API_KEY=***
|
||||||
- Clear symbol placement (X/O)
|
|
||||||
|
|
||||||
- **AI Agent Players**
|
# Optional - for additional models
|
||||||
- Player X: Strategic offensive moves
|
export ANTHROPIC_API_KEY=*** # For Claude models
|
||||||
- Player O: Defensive countermoves since this agent started later
|
export GOOGLE_API_KEY=*** # For Gemini models
|
||||||
- AI Judge: Game outcome validation
|
export GROQ_API_KEY=*** # For Groq models
|
||||||
|
```
|
||||||
|
|
||||||
- **Game Flow**
|
### 4. Run the Game
|
||||||
- Alternating turns between AIs
|
|
||||||
- Move validation and error handling
|
|
||||||
- Winner determination
|
|
||||||
- Draw detection
|
|
||||||
|
|
||||||
## Disclaimer ⚠️
|
```shell
|
||||||
|
streamlit run app.py
|
||||||
|
```
|
||||||
|
|
||||||
This is a demonstration project showcasing AI capabilities in game playing. API costs will apply based on your usage of the OpenAI, DeepSeek, or Google APIs.
|
- Open [localhost:8501](http://localhost:8501) to view the game interface
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
The game consists of three agents:
|
||||||
|
|
||||||
|
1. **Master Agent (Referee)**
|
||||||
|
- Coordinates the game
|
||||||
|
- Validates moves
|
||||||
|
- Maintains game state
|
||||||
|
- Determines game outcome
|
||||||
|
|
||||||
|
2. **Two Player Agents**
|
||||||
|
- Make strategic moves
|
||||||
|
- Analyze board state
|
||||||
|
- Follow game rules
|
||||||
|
- Respond to opponent moves
|
||||||
|
|
||||||
|
## Available Models
|
||||||
|
|
||||||
|
The game supports various AI models:
|
||||||
|
- GPT-4o (OpenAI)
|
||||||
|
- GPT-o3-mini (OpenAI)
|
||||||
|
- Gemini (Google)
|
||||||
|
- Llama 3 (Groq)
|
||||||
|
- Claude (Anthropic)
|
||||||
|
|
||||||
|
## Game Features
|
||||||
|
|
||||||
|
1. **Interactive Board**
|
||||||
|
- Real-time updates
|
||||||
|
- Visual move tracking
|
||||||
|
- Clear game status display
|
||||||
|
|
||||||
|
2. **Move History**
|
||||||
|
- Detailed move tracking
|
||||||
|
- Board state visualization
|
||||||
|
- Player action timeline
|
||||||
|
|
||||||
|
3. **Game Controls**
|
||||||
|
- Start/Pause game
|
||||||
|
- Reset board
|
||||||
|
- Select AI models
|
||||||
|
- View game history
|
||||||
|
|
||||||
|
4. **Performance Analysis**
|
||||||
|
- Move timing
|
||||||
|
- Strategy tracking
|
||||||
|
- Game statistics
|
||||||
|
|
|
||||||
|
|
@ -1,259 +0,0 @@
|
||||||
import re
|
|
||||||
import streamlit as st
|
|
||||||
from agno.agent import Agent
|
|
||||||
from agno.models.openai import OpenAIChat
|
|
||||||
from agno.models.deepseek import DeepSeek
|
|
||||||
from agno.models.google import Gemini
|
|
||||||
|
|
||||||
# Streamlit App Title
|
|
||||||
st.title("🎮 Agent X vs Agent O: Tic-Tac-Toe Game")
|
|
||||||
|
|
||||||
# Enhanced Welcome Message
|
|
||||||
with st.chat_message("assistant"):
|
|
||||||
st.markdown("""
|
|
||||||
**Welcome to the Tic-Tac-Toe AI Battle!** 🎮
|
|
||||||
This project pits two advanced AI agents against each other in a classic game of Tic-Tac-Toe.
|
|
||||||
Here's what you need to know:
|
|
||||||
""")
|
|
||||||
st.info("""
|
|
||||||
- **Player X**: Powered by Google's Gemini Flash 2.0.
|
|
||||||
- **Player O**: Powered by DeepSeek v3.
|
|
||||||
- **How to Play**: Enter your API keys in the sidebar, click **Start Game**, and watch the AI battle it out!
|
|
||||||
- **Goal**: The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins.
|
|
||||||
- **Draw**: If the board fills up without a winner, the game ends in a draw.
|
|
||||||
""")
|
|
||||||
st.markdown("Ready to see who wins? Click the **Start Game** button below! 🚀")
|
|
||||||
|
|
||||||
# Initialize the game board in session state
|
|
||||||
if 'board' not in st.session_state:
|
|
||||||
st.session_state.board = [[None, None, None],
|
|
||||||
[None, None, None],
|
|
||||||
[None, None, None]]
|
|
||||||
|
|
||||||
# Function to display the board with better styling
|
|
||||||
def display_board(board):
|
|
||||||
st.markdown("""
|
|
||||||
<style>
|
|
||||||
.board {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 50px);
|
|
||||||
grid-template-rows: repeat(3, 50px);
|
|
||||||
gap: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.cell {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
""", unsafe_allow_html=True)
|
|
||||||
|
|
||||||
st.write("Current Board:")
|
|
||||||
board_html = '<div class="board">'
|
|
||||||
for row in board:
|
|
||||||
for cell in row:
|
|
||||||
cell_value = cell if cell is not None else " "
|
|
||||||
board_html += f'<div class="cell">{cell_value}</div>'
|
|
||||||
board_html += '</div>'
|
|
||||||
st.markdown(board_html, unsafe_allow_html=True)
|
|
||||||
|
|
||||||
# Function to get the board state as a string
|
|
||||||
def get_board_state(board):
|
|
||||||
rows = []
|
|
||||||
for i, row in enumerate(board):
|
|
||||||
row_str = " | ".join([f"({i},{j}) {cell or ' '}" for j, cell in enumerate(row)])
|
|
||||||
rows.append(f"Row {i}: {row_str}")
|
|
||||||
return "\n".join(rows)
|
|
||||||
|
|
||||||
# Function to check for a winner
|
|
||||||
def check_winner(board):
|
|
||||||
# Check rows
|
|
||||||
for row in board:
|
|
||||||
if row[0] == row[1] == row[2] and row[0] is not None:
|
|
||||||
return row[0]
|
|
||||||
# Check columns
|
|
||||||
for col in range(3):
|
|
||||||
if board[0][col] == board[1][col] == board[2][col] and board[0][col] is not None:
|
|
||||||
return board[0][col]
|
|
||||||
# Check diagonals
|
|
||||||
if board[0][0] == board[1][1] == board[2][2] and board[0][0] is not None:
|
|
||||||
return board[0][0]
|
|
||||||
if board[0][2] == board[1][1] == board[2][0] and board[0][2] is not None:
|
|
||||||
return board[0][2]
|
|
||||||
# Check for draw
|
|
||||||
if all(cell is not None for row in board for cell in row):
|
|
||||||
return "Draw"
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Sidebar for API keys
|
|
||||||
st.sidebar.header("API Keys")
|
|
||||||
openai_api_key = st.sidebar.text_input("Enter your OpenAI API Key", type="password")
|
|
||||||
deepseek_api_key = st.sidebar.text_input("Enter your DeepSeek API Key", type="password")
|
|
||||||
google_api_key = st.sidebar.text_input("Enter your Google API Key (for Gemini)", type="password")
|
|
||||||
|
|
||||||
if openai_api_key:
|
|
||||||
st.session_state.openai_api_key = openai_api_key
|
|
||||||
if deepseek_api_key:
|
|
||||||
st.session_state.deepseek_api_key = deepseek_api_key
|
|
||||||
if google_api_key:
|
|
||||||
st.session_state.google_api_key = google_api_key
|
|
||||||
|
|
||||||
# Initialize agents if API keys are provided
|
|
||||||
if 'openai_api_key' in st.session_state:
|
|
||||||
player_x = Agent(
|
|
||||||
name="Player X",
|
|
||||||
model=Gemini(id="gemini-2.0-flash-exp", api_key=st.session_state.google_api_key),
|
|
||||||
instructions=[
|
|
||||||
"You are a Tic-Tac-Toe player using the symbol 'X'.",
|
|
||||||
"Your opponent is using the symbol 'O'. Block their potential winning moves.",
|
|
||||||
"Make your move in the format 'row, col' based on the current board state.",
|
|
||||||
"Strategize to win by placing your symbol in a way that blocks your opponent from forming a straight line.",
|
|
||||||
"Do not include any explanations or extra text. Only provide the move.",
|
|
||||||
"Row and column indices start from 0.",
|
|
||||||
],
|
|
||||||
markdown=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Initialize Player O with DeepSeek or Google Gemini
|
|
||||||
if 'deepseek_api_key' in st.session_state:
|
|
||||||
player_o = Agent(
|
|
||||||
name="Player O",
|
|
||||||
model=DeepSeek(id="deepseek-chat", api_key=st.session_state.deepseek_api_key),
|
|
||||||
instructions=[
|
|
||||||
"You are a Tic-Tac-Toe player using the symbol 'O'.",
|
|
||||||
"Your opponent is using the symbol 'X'. Block their potential winning moves.",
|
|
||||||
"Make your move in the format 'row, col' based on the current board state.",
|
|
||||||
"Strategize to win by placing your symbol in a way that blocks your opponent from forming a straight line.",
|
|
||||||
"Do not include any explanations or extra text. Only provide the move.",
|
|
||||||
"Row and column indices start from 0.",
|
|
||||||
],
|
|
||||||
markdown=True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
st.warning("Please provide either a DeepSeek API key or a Google API key for Player O.")
|
|
||||||
|
|
||||||
judge = Agent(
|
|
||||||
name="Judge",
|
|
||||||
model=OpenAIChat(id="gpt-4o", temperature=0.1, api_key=st.session_state.openai_api_key),
|
|
||||||
instructions=[
|
|
||||||
"You are the judge of a Tic-Tac-Toe game.",
|
|
||||||
"The board is presented as rows with positions separated by '|'.",
|
|
||||||
"Rows are labeled from 0 to 2, and columns from 0 to 2.",
|
|
||||||
"Example board state:",
|
|
||||||
"Row 0: (0,0) X | (0,1) | (0,2) O",
|
|
||||||
"Row 1: (1,0) O | (1,1) X | (1,2) X",
|
|
||||||
"Row 2: (2,0) X | (2,1) O | (2,2) O",
|
|
||||||
"Determine the winner based on this board state.",
|
|
||||||
"The winner is the player with three of their symbols in a straight line (row, column, or diagonal).",
|
|
||||||
"If the board is full and there is no winner, declare a draw.",
|
|
||||||
"Provide only the result (e.g., 'Player X wins', 'Player O wins', 'Draw').",
|
|
||||||
],
|
|
||||||
markdown=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Function to extract the move from the agent's response
|
|
||||||
def extract_move(response):
|
|
||||||
content = response.content.strip()
|
|
||||||
match = re.search(r'\d\s*,\s*\d', content)
|
|
||||||
if match:
|
|
||||||
move = match.group().replace(' ', '')
|
|
||||||
return move
|
|
||||||
numbers = re.findall(r'\d+', content)
|
|
||||||
if len(numbers) >= 2:
|
|
||||||
row = int(numbers[0])
|
|
||||||
col = int(numbers[1])
|
|
||||||
return f"{row},{col}"
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Game loop
|
|
||||||
def play_game():
|
|
||||||
if 'current_player' not in st.session_state:
|
|
||||||
st.session_state.current_player = player_x
|
|
||||||
if 'symbol' not in st.session_state:
|
|
||||||
st.session_state.symbol = "X"
|
|
||||||
if 'move_count' not in st.session_state:
|
|
||||||
st.session_state.move_count = 0
|
|
||||||
|
|
||||||
max_moves = 9
|
|
||||||
winner = None # Initialize winner variable
|
|
||||||
|
|
||||||
while st.session_state.move_count < max_moves:
|
|
||||||
# Display the board
|
|
||||||
display_board(st.session_state.board)
|
|
||||||
|
|
||||||
# Prepare the board state for the agent
|
|
||||||
board_state = get_board_state(st.session_state.board)
|
|
||||||
move_prompt = (
|
|
||||||
f"Current board state:\n{board_state}\n"
|
|
||||||
f"{st.session_state.current_player.name}'s turn. Make your move in the format 'row, col'."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get the current player's move
|
|
||||||
with st.chat_message("assistant"):
|
|
||||||
st.write(f"**{st.session_state.current_player.name}'s turn:**")
|
|
||||||
move_response = st.session_state.current_player.run(move_prompt)
|
|
||||||
st.code(f"Agent {st.session_state.current_player.name} response:\n{move_response.content}", language="markdown")
|
|
||||||
move = extract_move(move_response)
|
|
||||||
st.write(f"**Extracted move:** {move}")
|
|
||||||
|
|
||||||
if move is None:
|
|
||||||
st.error("Invalid move! Please use the format 'row, col'.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
row, col = map(int, move.split(','))
|
|
||||||
if st.session_state.board[row][col] is not None:
|
|
||||||
st.error("Invalid move! Cell already occupied.")
|
|
||||||
continue
|
|
||||||
st.session_state.board[row][col] = st.session_state.symbol
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
st.error("Invalid move! Please use the format 'row, col'.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Check for a winner or draw
|
|
||||||
winner = check_winner(st.session_state.board)
|
|
||||||
if winner:
|
|
||||||
break # Exit the loop if there's a winner
|
|
||||||
|
|
||||||
# Switch players
|
|
||||||
st.session_state.current_player = player_o if st.session_state.current_player == player_x else player_x
|
|
||||||
st.session_state.symbol = "O" if st.session_state.symbol == "X" else "X"
|
|
||||||
st.session_state.move_count += 1
|
|
||||||
|
|
||||||
# After the game loop, display the final board and involve the judge agent
|
|
||||||
st.write("**Final Board:**")
|
|
||||||
display_board(st.session_state.board)
|
|
||||||
|
|
||||||
if winner:
|
|
||||||
st.success(f"**Result:** {winner}")
|
|
||||||
else:
|
|
||||||
st.success("**Result:** Draw")
|
|
||||||
|
|
||||||
# Judge's announcement
|
|
||||||
st.write("\n**Game Over. Judge is determining the result...**")
|
|
||||||
st.write("**Final board state passed to judge:**")
|
|
||||||
st.code(get_board_state(st.session_state.board), language="markdown")
|
|
||||||
judge_prompt = (
|
|
||||||
f"Final board state:\n{get_board_state(st.session_state.board)}\n"
|
|
||||||
f"Determine the winner and announce the result."
|
|
||||||
)
|
|
||||||
judge_response = judge.run(judge_prompt)
|
|
||||||
st.code(f"Judge's raw response:\n{judge_response.content}", language="markdown")
|
|
||||||
announcement = judge_response.content.strip()
|
|
||||||
st.success(f"**Judge's Announcement:** {announcement}")
|
|
||||||
|
|
||||||
# Start Game Button
|
|
||||||
if st.button("Start Game"):
|
|
||||||
st.session_state.board = [[None, None, None],
|
|
||||||
[None, None, None],
|
|
||||||
[None, None, None]]
|
|
||||||
st.session_state.current_player = player_x
|
|
||||||
st.session_state.symbol = "X"
|
|
||||||
st.session_state.move_count = 0
|
|
||||||
play_game()
|
|
||||||
else:
|
|
||||||
st.warning("Please enter your OpenAI API key and either Deepseek/Gemini API key to start the game.")
|
|
||||||
|
|
@ -1,4 +1,238 @@
|
||||||
streamlit==1.41.1
|
# This file was autogenerated by uv via the following command:
|
||||||
agno
|
# ./generate_requirements.sh
|
||||||
openai==1.58.1
|
agno==1.1.6
|
||||||
google-generativeai==0.8.3
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
altair==5.5.0
|
||||||
|
# via streamlit
|
||||||
|
annotated-types==0.7.0
|
||||||
|
# via pydantic
|
||||||
|
anthropic==0.47.1
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
anyio==4.8.0
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# groq
|
||||||
|
# httpx
|
||||||
|
# openai
|
||||||
|
attrs==25.1.0
|
||||||
|
# via
|
||||||
|
# jsonschema
|
||||||
|
# referencing
|
||||||
|
blinker==1.9.0
|
||||||
|
# via streamlit
|
||||||
|
build==1.2.2.post1
|
||||||
|
# via pip-tools
|
||||||
|
cachetools==5.5.2
|
||||||
|
# via
|
||||||
|
# google-auth
|
||||||
|
# streamlit
|
||||||
|
certifi==2025.1.31
|
||||||
|
# via
|
||||||
|
# httpcore
|
||||||
|
# httpx
|
||||||
|
# requests
|
||||||
|
charset-normalizer==3.4.1
|
||||||
|
# via requests
|
||||||
|
click==8.1.8
|
||||||
|
# via
|
||||||
|
# pip-tools
|
||||||
|
# streamlit
|
||||||
|
# typer
|
||||||
|
distro==1.9.0
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# groq
|
||||||
|
# openai
|
||||||
|
docstring-parser==0.16
|
||||||
|
# via agno
|
||||||
|
gitdb==4.0.12
|
||||||
|
# via gitpython
|
||||||
|
gitpython==3.1.44
|
||||||
|
# via
|
||||||
|
# agno
|
||||||
|
# streamlit
|
||||||
|
google-auth==2.38.0
|
||||||
|
# via google-genai
|
||||||
|
google-genai==1.3.0
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
groq==0.18.0
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
h11==0.14.0
|
||||||
|
# via httpcore
|
||||||
|
httpcore==1.0.7
|
||||||
|
# via httpx
|
||||||
|
httpx==0.28.1
|
||||||
|
# via
|
||||||
|
# agno
|
||||||
|
# anthropic
|
||||||
|
# google-genai
|
||||||
|
# groq
|
||||||
|
# ollama
|
||||||
|
# openai
|
||||||
|
idna==3.10
|
||||||
|
# via
|
||||||
|
# anyio
|
||||||
|
# httpx
|
||||||
|
# requests
|
||||||
|
jinja2==3.1.5
|
||||||
|
# via
|
||||||
|
# altair
|
||||||
|
# pydeck
|
||||||
|
jiter==0.8.2
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# openai
|
||||||
|
jsonschema==4.23.0
|
||||||
|
# via altair
|
||||||
|
jsonschema-specifications==2024.10.1
|
||||||
|
# via jsonschema
|
||||||
|
markdown-it-py==3.0.0
|
||||||
|
# via rich
|
||||||
|
markupsafe==3.0.2
|
||||||
|
# via jinja2
|
||||||
|
mdurl==0.1.2
|
||||||
|
# via markdown-it-py
|
||||||
|
narwhals==1.28.0
|
||||||
|
# via altair
|
||||||
|
nest-asyncio==1.6.0
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
numpy==2.2.3
|
||||||
|
# via
|
||||||
|
# pandas
|
||||||
|
# pydeck
|
||||||
|
# streamlit
|
||||||
|
ollama==0.4.7
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
openai==1.64.0
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
packaging==24.2
|
||||||
|
# via
|
||||||
|
# altair
|
||||||
|
# build
|
||||||
|
# streamlit
|
||||||
|
pandas==2.2.3
|
||||||
|
# via streamlit
|
||||||
|
pathlib==1.0.1
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
pillow==11.1.0
|
||||||
|
# via
|
||||||
|
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
# streamlit
|
||||||
|
pip==25.0.1
|
||||||
|
# via pip-tools
|
||||||
|
pip-tools==7.4.1
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
protobuf==5.29.3
|
||||||
|
# via streamlit
|
||||||
|
pyarrow==19.0.1
|
||||||
|
# via streamlit
|
||||||
|
pyasn1==0.6.1
|
||||||
|
# via
|
||||||
|
# pyasn1-modules
|
||||||
|
# rsa
|
||||||
|
pyasn1-modules==0.4.1
|
||||||
|
# via google-auth
|
||||||
|
pydantic==2.10.6
|
||||||
|
# via
|
||||||
|
# agno
|
||||||
|
# anthropic
|
||||||
|
# google-genai
|
||||||
|
# groq
|
||||||
|
# ollama
|
||||||
|
# openai
|
||||||
|
# pydantic-settings
|
||||||
|
pydantic-core==2.27.2
|
||||||
|
# via pydantic
|
||||||
|
pydantic-settings==2.8.0
|
||||||
|
# via agno
|
||||||
|
pydeck==0.9.1
|
||||||
|
# via streamlit
|
||||||
|
pygments==2.19.1
|
||||||
|
# via rich
|
||||||
|
pyproject-hooks==1.2.0
|
||||||
|
# via
|
||||||
|
# build
|
||||||
|
# pip-tools
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
# via pandas
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
# via
|
||||||
|
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
# agno
|
||||||
|
# pydantic-settings
|
||||||
|
python-multipart==0.0.20
|
||||||
|
# via agno
|
||||||
|
pytz==2025.1
|
||||||
|
# via pandas
|
||||||
|
pyyaml==6.0.2
|
||||||
|
# via agno
|
||||||
|
referencing==0.36.2
|
||||||
|
# via
|
||||||
|
# jsonschema
|
||||||
|
# jsonschema-specifications
|
||||||
|
requests==2.32.3
|
||||||
|
# via
|
||||||
|
# google-genai
|
||||||
|
# streamlit
|
||||||
|
rich==13.9.4
|
||||||
|
# via
|
||||||
|
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
# agno
|
||||||
|
# streamlit
|
||||||
|
# typer
|
||||||
|
rpds-py==0.23.1
|
||||||
|
# via
|
||||||
|
# jsonschema
|
||||||
|
# referencing
|
||||||
|
rsa==4.9
|
||||||
|
# via google-auth
|
||||||
|
setuptools==75.8.0
|
||||||
|
# via pip-tools
|
||||||
|
shellingham==1.5.4
|
||||||
|
# via typer
|
||||||
|
six==1.17.0
|
||||||
|
# via python-dateutil
|
||||||
|
smmap==5.0.2
|
||||||
|
# via gitdb
|
||||||
|
sniffio==1.3.1
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# anyio
|
||||||
|
# groq
|
||||||
|
# openai
|
||||||
|
streamlit==1.42.2
|
||||||
|
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
||||||
|
tenacity==9.0.0
|
||||||
|
# via streamlit
|
||||||
|
toml==0.10.2
|
||||||
|
# via streamlit
|
||||||
|
tomli==2.2.1
|
||||||
|
# via agno
|
||||||
|
tornado==6.4.2
|
||||||
|
# via streamlit
|
||||||
|
tqdm==4.67.1
|
||||||
|
# via openai
|
||||||
|
typer==0.15.1
|
||||||
|
# via agno
|
||||||
|
typing-extensions==4.12.2
|
||||||
|
# via
|
||||||
|
# agno
|
||||||
|
# altair
|
||||||
|
# anthropic
|
||||||
|
# anyio
|
||||||
|
# google-genai
|
||||||
|
# groq
|
||||||
|
# openai
|
||||||
|
# pydantic
|
||||||
|
# pydantic-core
|
||||||
|
# referencing
|
||||||
|
# streamlit
|
||||||
|
# typer
|
||||||
|
tzdata==2025.1
|
||||||
|
# via pandas
|
||||||
|
urllib3==2.3.0
|
||||||
|
# via requests
|
||||||
|
websockets==14.2
|
||||||
|
# via google-genai
|
||||||
|
wheel==0.45.1
|
||||||
|
# via pip-tools
|
||||||
|
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
# Agent Tic Tac Toe
|
|
||||||
|
|
||||||
This example shows how to build an interactive Tic Tac Toe game where AI agents compete against each other. The application showcases how to:
|
|
||||||
- Coordinate multiple AI agents in a turn-based game
|
|
||||||
- Use different language models for different players
|
|
||||||
- Create an interactive web interface with Streamlit
|
|
||||||
- Handle game state and move validation
|
|
||||||
- Display real-time game progress and move history
|
|
||||||
|
|
||||||
## Features
|
|
||||||
- Multiple AI models support (GPT-4, Claude, Gemini, etc.)
|
|
||||||
- Real-time game visualization
|
|
||||||
- Move history tracking with board states
|
|
||||||
- Interactive player selection
|
|
||||||
- Game state management
|
|
||||||
- Move validation and coordination
|
|
||||||
|
|
||||||
### 1. Create a virtual environment
|
|
||||||
|
|
||||||
```shell
|
|
||||||
python3 -m venv .venv
|
|
||||||
source .venv/bin/activate
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Install dependencies
|
|
||||||
|
|
||||||
```shell
|
|
||||||
pip install -r ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Export API Keys
|
|
||||||
|
|
||||||
The game supports multiple AI models. Export the API keys for the models you want to use:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Required for OpenAI models
|
|
||||||
export OPENAI_API_KEY=***
|
|
||||||
|
|
||||||
# Optional - for additional models
|
|
||||||
export ANTHROPIC_API_KEY=*** # For Claude models
|
|
||||||
export GOOGLE_API_KEY=*** # For Gemini models
|
|
||||||
export GROQ_API_KEY=*** # For Groq models
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Run the Game
|
|
||||||
|
|
||||||
```shell
|
|
||||||
streamlit run ai_agent_tutorials/ai_tic_tac_toe_game/app.py
|
|
||||||
```
|
|
||||||
|
|
||||||
- Open [localhost:8501](http://localhost:8501) to view the game interface
|
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
The game consists of three agents:
|
|
||||||
|
|
||||||
1. **Master Agent (Referee)**
|
|
||||||
- Coordinates the game
|
|
||||||
- Validates moves
|
|
||||||
- Maintains game state
|
|
||||||
- Determines game outcome
|
|
||||||
|
|
||||||
2. **Two Player Agents**
|
|
||||||
- Make strategic moves
|
|
||||||
- Analyze board state
|
|
||||||
- Follow game rules
|
|
||||||
- Respond to opponent moves
|
|
||||||
|
|
||||||
## Available Models
|
|
||||||
|
|
||||||
The game supports various AI models:
|
|
||||||
- GPT-4o (OpenAI)
|
|
||||||
- GPT-o3-mini (OpenAI)
|
|
||||||
- Gemini (Google)
|
|
||||||
- Llama 3 (Groq)
|
|
||||||
- Claude (Anthropic)
|
|
||||||
|
|
||||||
## Game Features
|
|
||||||
|
|
||||||
1. **Interactive Board**
|
|
||||||
- Real-time updates
|
|
||||||
- Visual move tracking
|
|
||||||
- Clear game status display
|
|
||||||
|
|
||||||
2. **Move History**
|
|
||||||
- Detailed move tracking
|
|
||||||
- Board state visualization
|
|
||||||
- Player action timeline
|
|
||||||
|
|
||||||
3. **Game Controls**
|
|
||||||
- Start/Pause game
|
|
||||||
- Reset board
|
|
||||||
- Select AI models
|
|
||||||
- View game history
|
|
||||||
|
|
||||||
4. **Performance Analysis**
|
|
||||||
- Move timing
|
|
||||||
- Strategy tracking
|
|
||||||
- Game statistics
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Join our [Discord community](https://agno.link/discord) for help and discussions.
|
|
||||||
|
|
@ -1,238 +0,0 @@
|
||||||
# This file was autogenerated by uv via the following command:
|
|
||||||
# ./generate_requirements.sh
|
|
||||||
agno==1.1.6
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
altair==5.5.0
|
|
||||||
# via streamlit
|
|
||||||
annotated-types==0.7.0
|
|
||||||
# via pydantic
|
|
||||||
anthropic==0.47.1
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
anyio==4.8.0
|
|
||||||
# via
|
|
||||||
# anthropic
|
|
||||||
# groq
|
|
||||||
# httpx
|
|
||||||
# openai
|
|
||||||
attrs==25.1.0
|
|
||||||
# via
|
|
||||||
# jsonschema
|
|
||||||
# referencing
|
|
||||||
blinker==1.9.0
|
|
||||||
# via streamlit
|
|
||||||
build==1.2.2.post1
|
|
||||||
# via pip-tools
|
|
||||||
cachetools==5.5.2
|
|
||||||
# via
|
|
||||||
# google-auth
|
|
||||||
# streamlit
|
|
||||||
certifi==2025.1.31
|
|
||||||
# via
|
|
||||||
# httpcore
|
|
||||||
# httpx
|
|
||||||
# requests
|
|
||||||
charset-normalizer==3.4.1
|
|
||||||
# via requests
|
|
||||||
click==8.1.8
|
|
||||||
# via
|
|
||||||
# pip-tools
|
|
||||||
# streamlit
|
|
||||||
# typer
|
|
||||||
distro==1.9.0
|
|
||||||
# via
|
|
||||||
# anthropic
|
|
||||||
# groq
|
|
||||||
# openai
|
|
||||||
docstring-parser==0.16
|
|
||||||
# via agno
|
|
||||||
gitdb==4.0.12
|
|
||||||
# via gitpython
|
|
||||||
gitpython==3.1.44
|
|
||||||
# via
|
|
||||||
# agno
|
|
||||||
# streamlit
|
|
||||||
google-auth==2.38.0
|
|
||||||
# via google-genai
|
|
||||||
google-genai==1.3.0
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
groq==0.18.0
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
h11==0.14.0
|
|
||||||
# via httpcore
|
|
||||||
httpcore==1.0.7
|
|
||||||
# via httpx
|
|
||||||
httpx==0.28.1
|
|
||||||
# via
|
|
||||||
# agno
|
|
||||||
# anthropic
|
|
||||||
# google-genai
|
|
||||||
# groq
|
|
||||||
# ollama
|
|
||||||
# openai
|
|
||||||
idna==3.10
|
|
||||||
# via
|
|
||||||
# anyio
|
|
||||||
# httpx
|
|
||||||
# requests
|
|
||||||
jinja2==3.1.5
|
|
||||||
# via
|
|
||||||
# altair
|
|
||||||
# pydeck
|
|
||||||
jiter==0.8.2
|
|
||||||
# via
|
|
||||||
# anthropic
|
|
||||||
# openai
|
|
||||||
jsonschema==4.23.0
|
|
||||||
# via altair
|
|
||||||
jsonschema-specifications==2024.10.1
|
|
||||||
# via jsonschema
|
|
||||||
markdown-it-py==3.0.0
|
|
||||||
# via rich
|
|
||||||
markupsafe==3.0.2
|
|
||||||
# via jinja2
|
|
||||||
mdurl==0.1.2
|
|
||||||
# via markdown-it-py
|
|
||||||
narwhals==1.28.0
|
|
||||||
# via altair
|
|
||||||
nest-asyncio==1.6.0
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
numpy==2.2.3
|
|
||||||
# via
|
|
||||||
# pandas
|
|
||||||
# pydeck
|
|
||||||
# streamlit
|
|
||||||
ollama==0.4.7
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
openai==1.64.0
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
packaging==24.2
|
|
||||||
# via
|
|
||||||
# altair
|
|
||||||
# build
|
|
||||||
# streamlit
|
|
||||||
pandas==2.2.3
|
|
||||||
# via streamlit
|
|
||||||
pathlib==1.0.1
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
pillow==11.1.0
|
|
||||||
# via
|
|
||||||
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
# streamlit
|
|
||||||
pip==25.0.1
|
|
||||||
# via pip-tools
|
|
||||||
pip-tools==7.4.1
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
protobuf==5.29.3
|
|
||||||
# via streamlit
|
|
||||||
pyarrow==19.0.1
|
|
||||||
# via streamlit
|
|
||||||
pyasn1==0.6.1
|
|
||||||
# via
|
|
||||||
# pyasn1-modules
|
|
||||||
# rsa
|
|
||||||
pyasn1-modules==0.4.1
|
|
||||||
# via google-auth
|
|
||||||
pydantic==2.10.6
|
|
||||||
# via
|
|
||||||
# agno
|
|
||||||
# anthropic
|
|
||||||
# google-genai
|
|
||||||
# groq
|
|
||||||
# ollama
|
|
||||||
# openai
|
|
||||||
# pydantic-settings
|
|
||||||
pydantic-core==2.27.2
|
|
||||||
# via pydantic
|
|
||||||
pydantic-settings==2.8.0
|
|
||||||
# via agno
|
|
||||||
pydeck==0.9.1
|
|
||||||
# via streamlit
|
|
||||||
pygments==2.19.1
|
|
||||||
# via rich
|
|
||||||
pyproject-hooks==1.2.0
|
|
||||||
# via
|
|
||||||
# build
|
|
||||||
# pip-tools
|
|
||||||
python-dateutil==2.9.0.post0
|
|
||||||
# via pandas
|
|
||||||
python-dotenv==1.0.1
|
|
||||||
# via
|
|
||||||
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
# agno
|
|
||||||
# pydantic-settings
|
|
||||||
python-multipart==0.0.20
|
|
||||||
# via agno
|
|
||||||
pytz==2025.1
|
|
||||||
# via pandas
|
|
||||||
pyyaml==6.0.2
|
|
||||||
# via agno
|
|
||||||
referencing==0.36.2
|
|
||||||
# via
|
|
||||||
# jsonschema
|
|
||||||
# jsonschema-specifications
|
|
||||||
requests==2.32.3
|
|
||||||
# via
|
|
||||||
# google-genai
|
|
||||||
# streamlit
|
|
||||||
rich==13.9.4
|
|
||||||
# via
|
|
||||||
# -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
# agno
|
|
||||||
# streamlit
|
|
||||||
# typer
|
|
||||||
rpds-py==0.23.1
|
|
||||||
# via
|
|
||||||
# jsonschema
|
|
||||||
# referencing
|
|
||||||
rsa==4.9
|
|
||||||
# via google-auth
|
|
||||||
setuptools==75.8.0
|
|
||||||
# via pip-tools
|
|
||||||
shellingham==1.5.4
|
|
||||||
# via typer
|
|
||||||
six==1.17.0
|
|
||||||
# via python-dateutil
|
|
||||||
smmap==5.0.2
|
|
||||||
# via gitdb
|
|
||||||
sniffio==1.3.1
|
|
||||||
# via
|
|
||||||
# anthropic
|
|
||||||
# anyio
|
|
||||||
# groq
|
|
||||||
# openai
|
|
||||||
streamlit==1.42.2
|
|
||||||
# via -r cookbook/examples/apps/tic_tac_toe/requirements.in
|
|
||||||
tenacity==9.0.0
|
|
||||||
# via streamlit
|
|
||||||
toml==0.10.2
|
|
||||||
# via streamlit
|
|
||||||
tomli==2.2.1
|
|
||||||
# via agno
|
|
||||||
tornado==6.4.2
|
|
||||||
# via streamlit
|
|
||||||
tqdm==4.67.1
|
|
||||||
# via openai
|
|
||||||
typer==0.15.1
|
|
||||||
# via agno
|
|
||||||
typing-extensions==4.12.2
|
|
||||||
# via
|
|
||||||
# agno
|
|
||||||
# altair
|
|
||||||
# anthropic
|
|
||||||
# anyio
|
|
||||||
# google-genai
|
|
||||||
# groq
|
|
||||||
# openai
|
|
||||||
# pydantic
|
|
||||||
# pydantic-core
|
|
||||||
# referencing
|
|
||||||
# streamlit
|
|
||||||
# typer
|
|
||||||
tzdata==2025.1
|
|
||||||
# via pandas
|
|
||||||
urllib3==2.3.0
|
|
||||||
# via requests
|
|
||||||
websockets==14.2
|
|
||||||
# via google-genai
|
|
||||||
wheel==0.45.1
|
|
||||||
# via pip-tools
|
|
||||||
Loading…
Reference in a new issue