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
|
||||
|
||||
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
|
||||
- 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
|
||||
- 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
|
||||
## How to Run?
|
||||
|
||||
1. **Setup Environment**
|
||||
```bash
|
||||
|
|
@ -38,40 +29,78 @@ An interactive Tic-Tac-Toe game where two AI agents powered by different languag
|
|||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **Configure API Keys**
|
||||
- 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)
|
||||
### 2. Install dependencies
|
||||
|
||||
4. **Run the Application**
|
||||
```bash
|
||||
streamlit run ai_tic_tac_toe_agent.py
|
||||
```
|
||||
```shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
5. **Using the Interface**
|
||||
- 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
|
||||
### 3. Export API Keys
|
||||
|
||||
## Game Components
|
||||
The game supports multiple AI models. Export the API keys for the models you want to use:
|
||||
|
||||
- **Game Board**
|
||||
- 3x3 interactive grid
|
||||
- Real-time move visualization
|
||||
- Clear symbol placement (X/O)
|
||||
```shell
|
||||
# Required for OpenAI models
|
||||
export OPENAI_API_KEY=***
|
||||
|
||||
- **AI Agent Players**
|
||||
- Player X: Strategic offensive moves
|
||||
- Player O: Defensive countermoves since this agent started later
|
||||
- AI Judge: Game outcome validation
|
||||
# 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
|
||||
```
|
||||
|
||||
- **Game Flow**
|
||||
- Alternating turns between AIs
|
||||
- Move validation and error handling
|
||||
- Winner determination
|
||||
- Draw detection
|
||||
### 4. Run the Game
|
||||
|
||||
## 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
|
||||
agno
|
||||
openai==1.58.1
|
||||
google-generativeai==0.8.3
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -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