add human player

This commit is contained in:
yzlin 2023-10-01 23:10:59 +08:00
parent 81e8ee83fb
commit 91faec6bb1
3 changed files with 59 additions and 7 deletions

View file

@ -0,0 +1,40 @@
from examples.werewolf_game.actions import Speak
from examples.werewolf_game.roles import BasePlayer
from metagpt.schema import Message
from metagpt.logs import logger
async def _act(self):
todo = self._rc.todo
memories = self.get_all_memories()
input_instruction = f"""
## As a reminder, you have access to the following game history:
{memories}
## You are {self.name}({self.profile})
## Guidance:
1. If you are performing a special action or exercising a vote,
end your response with "PlayerX" where X is the player index, e.g., "..., kill/protect/poison/.../vote Player1".
2. If it is a daytime free speech, you can speak in whatever format.
Now, please speak:
"""
rsp = input(input_instruction) # wait for human input
msg_cause_by = type(todo)
msg_restricted_to = "" if isinstance(todo, Speak) \
else f"Moderator,{self.profile}"
msg = Message(
content=rsp, role=self.profile, sent_from=self.name,
cause_by=msg_cause_by, send_to="",
restricted_to=msg_restricted_to, # 给Moderator及自身阵营发送加密消息
)
logger.info(f"{self._setting}: {rsp}")
return msg
def prepare_human_player(player_class: BasePlayer):
# Dynamically define a human player class that inherits from a certain role class
HumanPlayer = type('HumanPlayer', (player_class,), {'_act': _act})
return HumanPlayer

View file

@ -35,7 +35,7 @@ class Seer(BasePlayer):
msg = Message(
content=rsp, role=self.profile, sent_from=self.name,
cause_by=Verify, send_to="",
restricted_to="Moderator",
restricted_to=f"Moderator,{self.profile}",
)
logger.info(f"{self._setting}: {rsp}")

View file

@ -3,10 +3,12 @@ import platform
import fire
import random
from metagpt.logs import logger
from examples.werewolf_game.werewolf_game import WerewolfGame
from examples.werewolf_game.roles import Moderator, Villager, Werewolf, Guard, Seer, Witch
from examples.werewolf_game.roles.human_player import prepare_human_player
def init_game_setup(shuffle=False):
def init_game_setup(shuffle=True, add_human=False):
roles = [
Villager,
Villager,
@ -17,29 +19,39 @@ def init_game_setup(shuffle=False):
Witch
]
if shuffle:
random.seed(2023)
# random.seed(2023)
random.shuffle(roles)
if add_human:
assigned_role_idx = random.randint(0, len(roles) - 1)
assigned_role = roles[assigned_role_idx]
roles[assigned_role_idx] = prepare_human_player(assigned_role)
players = [role(name=f"Player{i+1}") for i, role in enumerate(roles)]
if add_human:
logger.info(f"You are assigned {players[assigned_role_idx].name}({players[assigned_role_idx].profile})")
game_setup = ["Game setup:"] + [f"{player.name}: {player.profile}," for player in players]
game_setup = "\n".join(game_setup)
return game_setup, players
async def start_game(investment: float = 3.0, n_round: int = 5):
async def start_game(investment: float = 3.0, n_round: int = 5, shuffle : bool = True, add_human: bool = False):
game = WerewolfGame()
game_setup, players = init_game_setup(shuffle=True)
game_setup, players = init_game_setup(shuffle=shuffle, add_human=add_human)
players = [Moderator()] + players
game.hire(players)
game.invest(investment)
game.start_project(game_setup)
await game.run(n_round=n_round)
def main(investment: float = 3.0, n_round: int = 100):
def main(investment: float = 3.0, n_round: int = 100, shuffle : bool = True, add_human: bool = False):
"""
:param investment: contribute a certain dollar amount to watch the debate
:param n_round: maximum rounds of the debate
:return:
"""
asyncio.run(start_game(investment, n_round))
asyncio.run(start_game(investment, n_round, shuffle, add_human))
if __name__ == '__main__':