bstraehle's picture
Update multi_agent.py
963a71f verified
import chess, chess.svg, math
from autogen import ConversableAgent, register_function
from typing_extensions import Annotated
board = None
board_svgs = None
made_move = None
def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]:
return "Legal 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
board_svgs.append(chess.svg.board(
board,
arrows=[(move.from_square, move.to_square)],
fill={move.from_square: "gray"},
size=250
))
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)
)
return f"Moved {piece_name} ({piece_symbol}) from "\
f"{chess.SQUARE_NAMES[move.from_square]} to "\
f"{chess.SQUARE_NAMES[move.to_square]}."
def check_made_move(msg):
global made_move
if made_move:
made_move = False
return True
else:
return False
def get_num_turns(num_moves):
# Each turn includes two moves (one by each player)
# The first move by player black kicks off the chat
# The first move by player white starts the game
num_turns = math.ceil(num_moves / 2)
if num_moves % 2 == 0:
num_turns += 1
return num_turns
def initialize():
global board, board_svgs, made_move
board = chess.Board()
board_svgs = []
made_move = False
def run_multi_agent(llm_white, llm_black, num_moves):
initialize()
llm_config_white = {"model": llm_white}
llm_config_black = {"model": llm_black}
board_proxy = ConversableAgent(
name="Board Proxy",
llm_config=False,
is_termination_msg=check_made_move,
default_auto_reply="Please make a move.",
human_input_mode="NEVER",
)
player_white = ConversableAgent(
name="Player White",
system_message="You are a chess Grandmaster and you play as white. "
"First call get_legal_moves() to get a list of legal moves. "
"Then study the returned moves and call make_move(move) to make the best move. "
"Finally analyze the move: **Analysis:** move in UCI format, emoji of piece, unordered list of 3 items.",
llm_config=llm_config_white,
)
player_black = ConversableAgent(
name="Player Black",
system_message="You are a chess Grandmaster and you play as black. "
"First call get_legal_moves() to get a list of legal moves. "
"Then study the returned moves and call make_move(move) to make the best move. "
"Finally analyze the move: **Analysis:** move in UCI format, emoji of piece, unordered list of 3 items.",
llm_config=llm_config_black,
)
for caller in [player_white, player_black]:
register_function(
get_legal_moves,
caller=caller,
executor=board_proxy,
name="get_legal_moves",
description="Call this tool to get legal moves.",
)
register_function(
make_move,
caller=caller,
executor=board_proxy,
name="make_move",
description="Call this tool to make a move.",
)
player_white.register_nested_chats(
trigger=player_black,
chat_queue=[
{
"sender": board_proxy,
"recipient": player_white,
"summary_method": "last_msg",
"silent": False,
}
],
)
player_black.register_nested_chats(
trigger=player_white,
chat_queue=[
{
"sender": board_proxy,
"recipient": player_black,
"summary_method": "last_msg",
"silent": False,
}
],
)
chat_result = None
chat_history = []
try:
chat_result = player_black.initiate_chat(
player_white,
message="Let's play chess!",
max_turns=get_num_turns(num_moves),
verbose=True
)
except Exception as e:
print(f"Error: {e}")
finally:
if chat_result != None:
chat_history = chat_result.chat_history
result = ""
num_move = 0
for chat in chat_history:
player = ""
if num_move % 2 == 0:
player = "Player Black"
else:
player = "Player White"
if num_move > 0:
result += f"**{player}, Move {num_move}**\n{chat.get('content')}\n{board_svgs[num_move - 1]}\n\n"
num_move += 1
if num_moves % 2 == 0 and num_move == num_moves + 1:
break
#print("===")
#print(result)
#print("===")
return result