Skip to content

Commit

Permalink
This works perfectly - Minimal game
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkbrnd committed Dec 15, 2023
1 parent 944bff8 commit b23488b
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 101 deletions.
25 changes: 12 additions & 13 deletions coup.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import sys

from autogen import GroupChat, GroupChatManager, UserProxyAgent, config_list_from_dotenv
from autogen import GroupChat, GroupChatManager, UserProxyAgent, config_list_from_dotenv, AssistantAgent
from autogen.agentchat.contrib.gpt_assistant_agent import GPTAssistantAgent

from src.ai.agents import create_player_agent, create_game_master_agent
from src.ai.agents import create_player_agent, create_game_master_agent, create_user_proxy
from src.handler.game_handler import ResistanceCoupGameHandler

# SEED = 42
config_list = config_list_from_dotenv(
dotenv_file_path='.env',
filter_dict={
"model": {
# "gpt-4",
"gpt-3.5-turbo",
"gpt-4",
# "gpt-3.5-turbo",
}
}
)

base_llm_config = {
"config_list": config_list,
# "seed": SEED,
}


def main():
# Create game handler with 5 players
handler = ResistanceCoupGameHandler(5)
handler = ResistanceCoupGameHandler(3)
print(f"First player is {handler.current_player}")

# Create AI players
Expand All @@ -33,11 +29,14 @@ def main():
agent_players.append(create_player_agent(player.name, [other_player.name for other_player in handler.players if other_player.name != player.name], player.cards, handler, config_list))

# Game master
game_master: UserProxyAgent = create_game_master_agent(handler, config_list)
game_master: AssistantAgent = create_game_master_agent(handler, config_list)

# Game master
user_proxy: UserProxyAgent = create_user_proxy(config_list)

# Define group chat
group_chat = GroupChat(agents=[game_master] + agent_players, messages=[])
manager = GroupChatManager(groupchat=group_chat, llm_config=base_llm_config)
group_chat = GroupChat(agents=[user_proxy, game_master, *agent_players], messages=[], admin_name=game_master.name, max_round=100)
manager = GroupChatManager(groupchat=group_chat, llm_config={"config_list": config_list})

task = """
Play a game of The Resistance: Coup until there is a single winner.
Expand Down
155 changes: 94 additions & 61 deletions src/ai/agents.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from autogen import UserProxyAgent, config_list_from_dotenv
from autogen import UserProxyAgent, AssistantAgent
from autogen.agentchat.contrib.gpt_assistant_agent import GPTAssistantAgent

from src.handler.game_handler import ResistanceCoupGameHandler
Expand All @@ -9,79 +9,107 @@

# SEED = 42

def create_game_master_agent(handler: ResistanceCoupGameHandler, config_list: list) -> UserProxyAgent:
game_master_llm_config = {
def create_user_proxy(config_list: list) -> UserProxyAgent:
llm_config = {
"config_list": config_list,
# "seed": SEED,
"temperature": 0,
"tools": [
{
"type": "function",
"function": {
"name": "get_game_state",
"description": "Get the current state of the game",
"parameters": {
"type": "object",
"properties": {
},
}
},
}
]
}

user_proxy = UserProxyAgent(
name="GameMaster",
llm_config=game_master_llm_config,
name="User_Proxy",
llm_config=llm_config,
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
system_message="""
You are facilitating a game of The Resistance: Coup between five players. Respond with TERMINATE once the game has a winner.
At the start of the game, you will inform the starting player that it is their turn.
In between each player's turn you have to retrieve the game state and provide it to the players.
""",
code_execution_config=False,
human_input_mode="TERMINATE",
max_consecutive_auto_reply=10
default_auto_reply="Reply TERMINATE when the initial request has been fulfilled.",
human_input_mode="NEVER",
# max_consecutive_auto_reply=10
)
user_proxy.register_function(
return user_proxy


def create_game_master_agent(handler: ResistanceCoupGameHandler, config_list: list) -> AssistantAgent:
llm_config = {
"config_list": config_list,
# "seed": SEED,
"temperature": 1,
"functions": [
{
"name": "get_game_state",
"description": "Get the current state of the game",
"parameters": {
"type": "object",
"properties": {
},
}
},
]
}

instructions = f"""
You are the game master in a game of The Resistance: Coup between {handler.number_of_players} players.
At the start of the game, you will inform the starting player that it is their turn and announce to everyone the starting game state.
In between each player's turn you have to retrieve the game state and provide it to the current player.
Make sure the correct player is taking their next turn based on the game state.
Once there is only one active player left in the game, you can declare the game is over and we have a winner.
"""

game_master = AssistantAgent(
name="Game_Master",
system_message=instructions,
llm_config=llm_config,
function_map={
"get_game_state": handler.get_game_state,
}
},
# max_consecutive_auto_reply=100,
description="The game master in a game of The Resistance Coup"
)
return user_proxy
return game_master


def create_player_agent(name: str, other_player_names: list[str], cards: list[Card],
handler: ResistanceCoupGameHandler, config_list: list) -> GPTAssistantAgent:
player_llm_config = {
handler: ResistanceCoupGameHandler, config_list: list) -> AssistantAgent:
llm_config = {
"config_list": config_list,
# "seed": SEED,
"temperature": 0,
"tools": [
"temperature": 0.3,
"functions": [
{
"type": "function",
"function": {
"name": "perform_action",
"description": "Perform a valid action for Resistance: Coup",
"parameters": {
"type": "object",
"properties": {
"action_name": {
"type": "string",
"description": "The name of the action to perform.",
"enum": [ActionType.income, ActionType.foreign_aid, ActionType.tax, ActionType.coup,
ActionType.steal, ActionType.assassinate, ActionType.exchange]
},
"target_player_name": {
"type": "string",
"description": "The name player to target.",
},
"name": "perform_action",
"description": "Perform a valid action for Resistance: Coup",
"parameters": {
"type": "object",
"properties": {
"player_name": {
"type": "string",
"description": "Send your own name.",
"enum": [name]
},
"action_name": {
"type": "string",
"description": "The name of the action to perform.",
"enum": [ActionType.income, ActionType.foreign_aid, ActionType.tax, ActionType.coup,
ActionType.steal, ActionType.assassinate, ActionType.exchange]
},
"target_player_name": {
"type": "string",
"description": "The player name to target.",
},
"required": [
"action_name"
]
}
},
},
"required": [
"player_name",
"action_name"
]
}
}
]
}
Expand All @@ -92,26 +120,31 @@ def create_player_agent(name: str, other_player_names: list[str], cards: list[Ca
You start with a {str(cards[0])} card and a {str(cards[1])} card, as well as 2 coins.
On your turn you have to pick a valid action based on your current available cards and coins.
On your turn you have to pick a valid action based on your current available cards and coins. Also provide your own name to the function.
If your action was invalid, you have to pick another action.
Never announce what cards you have, they are secret.
If your action was invalid, you have to pick another action. However feel free to bluff and perform an action even if you don't have the card.
The possible actions are {[ActionType.income, ActionType.foreign_aid, ActionType.tax, ActionType.coup, ActionType.steal, ActionType.assassinate, ActionType.exchange]}
You also chit-chat with your opponent when you communicate an action to light up the mood.
You should ensure both you and your opponents are making valid actions. Also that everyone is only taking actions when it is their turn.
Do not apologize for making invalid actions."""
Do not apologize for making invalid actions.
If the game is over, stop playing."""

player = GPTAssistantAgent(
player = AssistantAgent(
name=name,
instructions=instructions,
llm_config=player_llm_config,
function_map={}
)

player.register_function(
system_message=instructions,
llm_config=llm_config,
function_map={
"perform_action": handler.perform_action,
}
},
max_consecutive_auto_reply=100,
description=f"The player named {name} the game of The Resistance Coup"
)

return player
Loading

0 comments on commit b23488b

Please sign in to comment.