diff --git a/examples/werewolf_game/actions/__init__.py b/examples/werewolf_game/actions/__init__.py index 5568f50f8..3dec45d09 100644 --- a/examples/werewolf_game/actions/__init__.py +++ b/examples/werewolf_game/actions/__init__.py @@ -1,10 +1,12 @@ 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 from examples.werewolf_game.actions.seer_actions import Verify ACTIONS = { "Speak": Speak, "Hunt": Hunt, + "Protect": Protect, "Verify": Verify, } \ 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..10e550a49 --- /dev/null +++ b/examples/werewolf_game/actions/guard_actions.py @@ -0,0 +1,25 @@ +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, + you can choose to protect a player, including yourself, then the protected player will not be killed by the Werewolves this night. + this is game history: + {context}. + Attention: you can not protect the same player two nights in a row. + Now, choose one to protect, you will: + """ + + def __init__(self, name="Protect", 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 \ No newline at end of file diff --git a/examples/werewolf_game/roles/__init__.py b/examples/werewolf_game/roles/__init__.py index ac79f07d7..bd8128fa9 100644 --- a/examples/werewolf_game/roles/__init__.py +++ b/examples/werewolf_game/roles/__init__.py @@ -2,4 +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 from examples.werewolf_game.roles.seer import Seer diff --git a/examples/werewolf_game/roles/guard.py b/examples/werewolf_game/roles/guard.py new file mode 100644 index 000000000..94b5b46dc --- /dev/null +++ b/examples/werewolf_game/roles/guard.py @@ -0,0 +1,46 @@ +from examples.werewolf_game.roles.base_player import BasePlayer +from examples.werewolf_game.actions import Speak, Protect +from metagpt.schema import Message +from metagpt.logs import logger + +class Guard(BasePlayer): + def __init__( + self, + name: str = "", + profile: str = "Guard", + team: str = "good guys", + special_action_names: list[str] = ["Protect"], + **kwargs, + ): + super().__init__(name, profile, team, special_action_names, **kwargs) + + async def _act(self): + # todo为_think时确定的,有两种情况,Speak或Protect + 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, Protect): + rsp = await todo.run(context=memories) + msg = Message( + content=rsp, role=self.profile, sent_from=self.name, + cause_by=Protect, 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 b272dc13b..0b38521c4 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, Seer +from examples.werewolf_game.roles import Moderator, Villager, Werewolf, Guard, Seer DEFAULT_PLAYER_SETUP = """ Game setup: @@ -11,7 +11,8 @@ Player1: Villager, Player2: Villager, Player3: Werewolf, Player4: Werewolf, -Player5: Seer. +Player5: Guard, +Player6: Seer. """ async def start_game(idea: str = DEFAULT_PLAYER_SETUP, investment: float = 3.0, n_round: int = 5): @@ -22,7 +23,8 @@ async def start_game(idea: str = DEFAULT_PLAYER_SETUP, investment: float = 3.0, Villager(name="Player2"), Werewolf(name="Player3"), Werewolf(name="Player4"), - Seer(name="Player5"), + Guard(name="Player5"), + Seer(name="Player6"), ]) game.invest(investment) game.start_project(idea) diff --git a/metagpt/prompts/arbiter.py b/metagpt/prompts/arbiter.py new file mode 100644 index 000000000..d8e0d0781 --- /dev/null +++ b/metagpt/prompts/arbiter.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/9/26 1:12 +@Author : kevin-meng +@File : arbiter.py +""" + + +ARBITER = """ +As an experienced Arbiter, you possess the necessary competence, sound judgment, and absolute objectivity. you promise that you will officiate in games with complete impartiality, respecting and adhering to the rules that govern them, in the true spirit of sportsmanship. + +Please always remember the general duties of the Arbiters in a competition: +a. Ensure fair play and adhere to the Anti-cheating regulations. +b. Supervise the progress of the competition. +c. Observe the game and enforce decisions made, imposing penalties on players where appropriate. +d. Ensure that the Laws of the game are observed. + +The rules governing this competition are as follows: +=== +{rules} +=== + +The scoring dimensions for judging in this game are as follows: +=== +{dimensions} +=== + +After the end of the competition, the Arbiter should submit a report, which includes: +a. A summary report for the game. +b. The final standings. +c. Each player and their final score for each assessment category, along with the reasons for the ratings. +d. Any other important information +for example: + +## Summary + ...... + +## Results and Standings (Top3) + Top 1: player 1 + Top 2: player 2 + Top 2: player 3 + +## Scoring and Assessment Dimensions + - player 1 : socre + - dimension 1 + score: xx + reason: xx + - dimension 2 + score: xx + reason: xx + ...... + - player 2 + ...... + +## Conclusion + ...... + +""" + +