diff --git a/examples/werewolf_game/actions/__init__.py b/examples/werewolf_game/actions/__init__.py index 7c5af46df..3c69b3c99 100644 --- a/examples/werewolf_game/actions/__init__.py +++ b/examples/werewolf_game/actions/__init__.py @@ -1,8 +1,10 @@ from examples.werewolf_game.actions.moderator_actions import InstructSpeak from examples.werewolf_game.actions.common_actions import Speak from examples.werewolf_game.actions.werewolf_actions import Hunt +from examples.werewolf_game.actions.guard_actions import Protect ACTIONS = { "Speak": Speak, "Hunt": Hunt, + "Protect": Protect, } \ No newline at end of file diff --git a/examples/werewolf_game/actions/guard_actions.py b/examples/werewolf_game/actions/guard_actions.py new file mode 100644 index 000000000..419bd0330 --- /dev/null +++ b/examples/werewolf_game/actions/guard_actions.py @@ -0,0 +1,24 @@ +from metagpt.actions import Action + +class Protect(Action): + """Action: choose a player to protect""" + + PROMPT_TEMPLATE = """ + It's a werewolf game and you are a guard, + this is game history: + {context}. + Attention: you can not protect the same player in a row. + Now, choose one to portect, you will: + """ + + def __init__(self, name="Speak", context=None, llm=None): + super().__init__(name, context, llm) + + async def run(self, context: str): + + prompt = self.PROMPT_TEMPLATE.format(context=context) + + rsp = await self._aask(prompt) + # rsp = "Protect Player 1" + + return rsp diff --git a/examples/werewolf_game/roles/__init__.py b/examples/werewolf_game/roles/__init__.py index 464563344..52cbec1f9 100644 --- a/examples/werewolf_game/roles/__init__.py +++ b/examples/werewolf_game/roles/__init__.py @@ -2,3 +2,5 @@ from examples.werewolf_game.roles.base_player import BasePlayer from examples.werewolf_game.roles.moderator import Moderator from examples.werewolf_game.roles.villager import Villager from examples.werewolf_game.roles.werewolf import Werewolf +from examples.werewolf_game.roles.guard import Guard + diff --git a/examples/werewolf_game/roles/guard.py b/examples/werewolf_game/roles/guard.py new file mode 100644 index 000000000..5a3bc55ff --- /dev/null +++ b/examples/werewolf_game/roles/guard.py @@ -0,0 +1,44 @@ +from examples.werewolf_game.roles.base_player import BasePlayer +from examples.werewolf_game.actions import Speak, Hunt +from metagpt.schema import Message +from metagpt.logs import logger + +class Werewolf(BasePlayer): + def __init__( + self, + name: str = "", + profile: str = "Werewolf", + team: str = "werewolves", + special_action_names: list[str] = ["Hunt"], + **kwargs, + ): + super().__init__(name, profile, team, special_action_names, **kwargs) + + async def _act(self): + # todo为_think时确定的,有两种情况,Speak或Hunt + todo = self._rc.todo + logger.info(f"{self._setting}: ready to {str(todo)}") + + # 可以用这个函数获取该角色的全部记忆 + memories = self.get_all_memories() + print("*" * 10, f"{self._setting}'s current memories: {memories}", "*" * 10) + + # 根据自己定义的角色Action,对应地去run,run的入参可能不同 + if isinstance(todo, Speak): + rsp = await todo.run(profile=self.profile, context=memories) + msg = Message( + content=rsp, role=self.profile, sent_from=self.name, + cause_by=Speak, send_to="", restricted_to="", + ) + + elif isinstance(todo, Hunt): + rsp = await todo.run(context=memories) + msg = Message( + content=rsp, role=self.profile, sent_from=self.name, + cause_by=Hunt, send_to="", + restricted_to=f"Moderator,{self.profile}", # 给Moderator及狼阵营发送要杀的人的加密消息 + ) + + logger.info(f"{self._setting}: {rsp}") + + return msg diff --git a/examples/werewolf_game/start_game.py b/examples/werewolf_game/start_game.py index 98d76aa9d..0b10a0a86 100644 --- a/examples/werewolf_game/start_game.py +++ b/examples/werewolf_game/start_game.py @@ -3,7 +3,7 @@ import platform import fire from examples.werewolf_game.werewolf_game import WerewolfGame -from examples.werewolf_game.roles import Moderator, Villager, Werewolf +from examples.werewolf_game.roles import Moderator, Villager, Werewolf, Guard DEFAULT_PLAYER_SETUP = """ Game setup: @@ -11,6 +11,8 @@ Player1: Villager, Player2: Villager, Player3: Werewolf, Player4: Werewolf. +Player5: Guard. + """ async def start_game(idea: str = DEFAULT_PLAYER_SETUP, investment: float = 3.0, n_round: int = 5): @@ -21,6 +23,7 @@ async def start_game(idea: str = DEFAULT_PLAYER_SETUP, investment: float = 3.0, Villager(name="Player2"), Werewolf(name="Player3"), Werewolf(name="Player4"), + Guard(name="Player5"), ]) game.invest(investment) game.start_project(idea)