mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-05-04 05:12:37 +02:00
update win mechanism
This commit is contained in:
parent
4ffbee525c
commit
0c238d2b0d
2 changed files with 28 additions and 15 deletions
|
|
@ -65,13 +65,13 @@ STEP_INSTRUCTIONS = {
|
|||
15: {"content": "{player_current_dead} was killed last night!",
|
||||
"send_to": "Moderator",
|
||||
"restricted_to": ""},
|
||||
16: {"content": """Now freely talk about roles of other players with each other based on your observation and
|
||||
reflection with few sentences. Decide whether to reveal your identity based on your reflection.""",
|
||||
16: {"content": """Living players: {living_players}, now freely talk about the current situation based on your observation and
|
||||
reflection with a few sentences. Decide whether to reveal your identity based on your reflection.""",
|
||||
"send_to": "", # send to all to speak in daytime
|
||||
"restricted_to": ""},
|
||||
17: {"content": """Now vote and tell me who you think is the werewolf. Don’t mention your role.
|
||||
You only choose one from the following living options please:
|
||||
{living_players}. Or you can pass. For example: I vote to kill ...""",
|
||||
{living_players}. Say ONLY: I vote to eliminate ...""",
|
||||
"send_to": "",
|
||||
"restricted_to": ""},
|
||||
18: {"content": """{player_current_dead} was eliminated.""",
|
||||
|
|
@ -91,12 +91,12 @@ class InstructSpeak(Action):
|
|||
})
|
||||
content = instruction_info["content"]
|
||||
if "{living_players}" in content and "{werewolf_players}" in content:
|
||||
content = content.format(living_players=",".join(living_players),
|
||||
werewolf_players=",".join(werewolf_players))
|
||||
content = content.format(living_players=living_players,
|
||||
werewolf_players=werewolf_players)
|
||||
if "{living_players}" in content:
|
||||
content = content.format(living_players=",".join(living_players))
|
||||
content = content.format(living_players=living_players)
|
||||
if "{werewolf_players}" in content:
|
||||
content = content.format(werewolf_players=",".join(werewolf_players))
|
||||
content = content.format(werewolf_players=werewolf_players)
|
||||
if "{player_hunted}" in content:
|
||||
content = content.format(player_hunted=player_hunted)
|
||||
if "{player_current_dead}" in content:
|
||||
|
|
@ -140,8 +140,8 @@ class SummarizeDay(Action):
|
|||
|
||||
class AnnounceGameResult(Action):
|
||||
|
||||
async def run(self, winner: str):
|
||||
return f"Game over! The winner is the {winner}"
|
||||
async def run(self, winner: str, win_reason: str):
|
||||
return f"Game over! {win_reason}. The winner is the {winner}"
|
||||
|
||||
async def main():
|
||||
rst1 = await SummarizeDay().run({"Player1": 0, "Player2": 0, "Player3": 0, "Player4": 0})
|
||||
|
|
|
|||
|
|
@ -24,12 +24,15 @@ class Moderator(Role):
|
|||
self._watch([UserRequirement, InstructSpeak, ParseSpeak])
|
||||
self._init_actions([InstructSpeak, ParseSpeak, AnnounceGameResult])
|
||||
self.step_idx = 0
|
||||
self.eval_step_idx = []
|
||||
|
||||
# game states
|
||||
self.living_players = []
|
||||
self.werewolf_players = []
|
||||
self.good_guys = []
|
||||
self.villager_players = []
|
||||
self.special_role_players = []
|
||||
self.winner = None
|
||||
self.win_reason = None
|
||||
self.witch_poison_left = 1
|
||||
self.witch_antidote_left = 1
|
||||
|
||||
|
|
@ -44,7 +47,10 @@ class Moderator(Role):
|
|||
self.living_players = re.findall(r"Player[0-9]+", game_setup)
|
||||
self.werewolf_players = re.findall(r"Player[0-9]+: Werewolf", game_setup)
|
||||
self.werewolf_players = [p.replace(": Werewolf", "") for p in self.werewolf_players]
|
||||
self.good_guys = [p for p in self.living_players if p not in self.werewolf_players]
|
||||
self.villager_players = re.findall(r"Player[0-9]+: Villager", game_setup)
|
||||
self.villager_players = [p.replace(": Villager", "") for p in self.villager_players]
|
||||
self.special_role_players = [p for p in self.living_players \
|
||||
if p not in self.werewolf_players + self.villager_players]
|
||||
|
||||
def update_player_status(self, player_names: list[str]):
|
||||
if not player_names:
|
||||
|
|
@ -114,8 +120,10 @@ class Moderator(Role):
|
|||
def _update_game_states(self, memories):
|
||||
|
||||
step_idx = self.step_idx % len(STEP_INSTRUCTIONS)
|
||||
if step_idx not in [15, 18]: # FIXME: hard code
|
||||
if step_idx not in [15, 18] or self.step_idx in self.eval_step_idx: # FIXME: hard code
|
||||
return
|
||||
else:
|
||||
self.eval_step_idx.append(self.step_idx) # record evaluation, avoid repetitive evaluation at the same step
|
||||
|
||||
if step_idx == 15: # FIXME: hard code
|
||||
# night ends: after all special roles acted, process the whole night
|
||||
|
|
@ -135,6 +143,7 @@ class Moderator(Role):
|
|||
self.player_poisoned = None
|
||||
|
||||
elif step_idx == 18: # FIXME: hard code
|
||||
print("*" * 10, step_idx)
|
||||
# day ends: after all roles voted, process all votings
|
||||
voting_msgs = memories[-len(self.living_players):]
|
||||
voted_all = []
|
||||
|
|
@ -144,16 +153,20 @@ class Moderator(Role):
|
|||
continue
|
||||
voted_all.append(voted.group(0))
|
||||
self.player_current_dead = [Counter(voted_all).most_common()[0][0]] # 平票时,杀序号小的
|
||||
# print("*" * 10, "dead", self.player_current_dead)
|
||||
self.living_players = [p for p in self.living_players if p not in self.player_current_dead]
|
||||
self.update_player_status(self.player_current_dead)
|
||||
|
||||
# game's termination condition
|
||||
living_werewolf = [p for p in self.werewolf_players if p in self.living_players]
|
||||
living_good_guys = [p for p in self.good_guys if p in self.living_players]
|
||||
living_villagers = [p for p in self.villager_players if p in self.living_players]
|
||||
living_special_roles = [p for p in self.special_role_players if p in self.living_players]
|
||||
if not living_werewolf:
|
||||
self.winner = "good guys"
|
||||
elif not living_good_guys:
|
||||
self.win_reason = "werewolves all dead"
|
||||
elif not living_villagers or not living_special_roles:
|
||||
self.winner = "werewolf"
|
||||
self.win_reason = "villagers all dead" if not living_villagers else "special roles all dead"
|
||||
|
||||
def _record_game_history(self):
|
||||
if self.step_idx % len(STEP_INSTRUCTIONS) == 0 or self.winner is not None:
|
||||
|
|
@ -210,7 +223,7 @@ class Moderator(Role):
|
|||
cause_by=ParseSpeak, send_to="", restricted_to=msg_restriced_to)
|
||||
|
||||
elif isinstance(todo, AnnounceGameResult):
|
||||
msg_content = await AnnounceGameResult().run(winner=self.winner)
|
||||
msg_content = await AnnounceGameResult().run(winner=self.winner, win_reason=self.win_reason)
|
||||
msg = Message(content=msg_content, role=self.profile, sent_from=self.name, cause_by=AnnounceGameResult)
|
||||
|
||||
logger.info(f"{self._setting}: {msg_content}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue