From f579d005809259ab9e6451a22d40b636802a4f48 Mon Sep 17 00:00:00 2001 From: Madhu Date: Mon, 6 Jan 2025 02:03:03 +0530 Subject: [PATCH] NEW CODE: CHESS AGENTS WITH AUTOGEN --- ai_agent_tutorials/ai_chess_game/README.md | 34 ++++ .../ai_chess_game/ai_chess_agents.py | 170 ++++++++++++++++++ .../ai_chess_game/requirements.txt | 5 + 3 files changed, 209 insertions(+) create mode 100644 ai_agent_tutorials/ai_chess_game/README.md create mode 100644 ai_agent_tutorials/ai_chess_game/ai_chess_agents.py create mode 100644 ai_agent_tutorials/ai_chess_game/requirements.txt diff --git a/ai_agent_tutorials/ai_chess_game/README.md b/ai_agent_tutorials/ai_chess_game/README.md new file mode 100644 index 0000000..f7261b6 --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/README.md @@ -0,0 +1,34 @@ +# AI Blackjack Game + +This is a simple Chess game that uses an AI agents - Player black and player white to play the game. There's also a board proxy agent to execute the tools and manage the game. It is important to use a board proxy as a non-LLM "guard rail" to ensure the game is played correctly and to prevent agents from making illegal moves. + + +### How to get Started? + +1. Clone the GitHub repository + +```bash +git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git +cd ai_agent_tutorials/ai_chess_game +``` +2. Install the required dependencies: + +```bash +pip install -r requirements.txt +``` +3. Get your OpenAI API Key + +- Sign up for an [OpenAI account](https://platform.openai.com/) (or the LLM provider of your choice) and obtain your API key. + +4. Run the Streamlit App +```bash +streamlit run ai_chess_agents.py +``` + +## Requirements + +- autogen +- numpy +- openai +- streamlit +- chess \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py new file mode 100644 index 0000000..99f3d7a --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -0,0 +1,170 @@ +import os +from typing import List +import chess +import chess.svg +from IPython.display import display +from typing_extensions import Annotated +player_white_config_list = [ + { + "model": "gpt-4-turbo-preview", + "api_key": os.environ.get("OPENAI_API_KEY"), + }, +] + +player_black_config_list = [ + { + "model": "gpt-4-turbo-preview", + "api_key": os.environ.get("OPENAI_API_KEY"), + }, +] + + +# Initialize the board. +board = chess.Board() + +# Keep track of whether a move has been made. +made_move = False + +def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]: + return "Possible moves are: " + ",".join([str(move) for move in board.legal_moves]) + +def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]: + move = chess.Move.from_uci(move) + board.push_uci(str(move)) + global made_move + made_move = True + # Display the board. + display( + chess.svg.board(board, arrows=[(move.from_square, move.to_square)], fill={move.from_square: "gray"}, size=200) + ) + # Get the piece name. + piece = board.piece_at(move.to_square) + piece_symbol = piece.unicode_symbol() + piece_name = ( + chess.piece_name(piece.piece_type).capitalize() + if piece_symbol.isupper() + else chess.piece_name(piece.piece_type) + ) + + result_msg = f"Moved {piece_name} ({piece_symbol}) from {chess.SQUARE_NAMES[move.from_square]} to {chess.SQUARE_NAMES[move.to_square]}." + + # Add game state information + if board.is_checkmate(): + result_msg += f"\nCheckmate! {'White' if board.turn == chess.BLACK else 'Black'} wins!" + elif board.is_stalemate(): + result_msg += "\nGame ended in stalemate!" + elif board.is_insufficient_material(): + result_msg += "\nGame ended - insufficient material to checkmate!" + elif board.is_check(): + result_msg += "\nCheck!" + + return result_msg + +from autogen import ConversableAgent, register_function + +player_white = ConversableAgent( + name="Player_White", # Updated name + system_message="You are a chess player and you play as white. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_white_config_list, "cache_seed": None}, +) + +player_black = ConversableAgent( + name="Player_Black", # Updated name + system_message="You are a chess player and you play as black. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_black_config_list, "cache_seed": None}, +) + +# Check if the player has made a move, and reset the flag if move is made. +def check_made_move(msg): + global made_move + if made_move: + made_move = False + return True + else: + return False + +board_proxy = ConversableAgent( + name="Board_Proxy", # Updated name + llm_config=False, + # The board proxy will only terminate the conversation if the player has made a move. + is_termination_msg=check_made_move, + # The auto reply message is set to keep the player agent retrying until a move is made. + default_auto_reply="Please make a move.", + human_input_mode="NEVER", +) + +register_function( + make_move, + caller=player_white, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", +) + +register_function( + get_legal_moves, + caller=player_white, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", +) + +register_function( + make_move, + caller=player_black, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", +) + +register_function( + get_legal_moves, + caller=player_black, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", +) + +player_black.llm_config["tools"] + +player_white.register_nested_chats( + trigger=player_black, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_white, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], +) + +player_black.register_nested_chats( + trigger=player_white, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_black, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], +) + +# Clear the board. +board = chess.Board() + +# Remove max_turns to let the game continue until completion +chat_result = player_black.initiate_chat( + player_white, + message="Let's play chess! Your move.", + max_turns=10, +) \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/requirements.txt b/ai_agent_tutorials/ai_chess_game/requirements.txt new file mode 100644 index 0000000..e8130a5 --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/requirements.txt @@ -0,0 +1,5 @@ +autogen +numpy +openai +streamlit +chess \ No newline at end of file