添加了ivan写的parse speak

This commit is contained in:
mannaandpoem 2023-09-26 23:05:45 +08:00
parent 4584435bc6
commit e5140fd6a5
3 changed files with 100 additions and 22 deletions

View file

@ -1,4 +1,5 @@
import asyncio
import collections
from random import random
from metagpt.actions import Action
@ -77,6 +78,42 @@ STEP_INSTRUCTIONS = {
"restricted_to": ""},
}
ROLE_STATES = {
# 存活状态
0: "Alive", # 开场
1: "Dead", # 结束
2: "Protected", # 被保护
3: "Poisoned", # 被毒
4: "Saved", # 被救
5: "Killed" # 被刀
}
VOTE_PROMPT = """
Welcome to the daytime discussion phase in the Werewolf game.
During the day, players discuss and share information about who they suspect might be a werewolf.
Players can also cast their votes to eliminate a player they believe is a werewolf.
Here are the conversations from the daytime:
{vote_message}
Now it's time to cast your votes.
You can vote for a player by typing their name.
Example: "Vote for Player2"
Here are the voting options:
"""
PARSE_INSTRUCTIONS = {
0: "Now it's time to vote",
1: "The {winner} have won! They successfully eliminated all the {loser}}."
"The game has ended. Thank you for playing Werewolf!",
2: "The night has ended, and it's time to reveal the casualties."
"During the night, the Werewolves made their move. Unfortunately, they targeted {PlayerName}, who is now dead."
}
class InstructSpeak(Action):
def __init__(self, name="InstructSpeak", context=None, llm=None):
@ -105,8 +142,46 @@ class InstructSpeak(Action):
class ParseSpeak(Action):
async def run(self):
return ""
def __init__(self, name="ParseSpeak", context=None, llm=None):
super().__init__(name, context, llm)
self.daytime_info = collections.defaultdict(list)
self.night_info = collections.defaultdict(list)
self.vote_message = []
async def run(self, dead_history, context, env):
for m in env.memory.get():
role = m.sent_from if hasattr(m, 'sent_from') else ""
content = m.content if hasattr(m, 'content') else ""
target = m.sent_to if hasattr(m, 'sent_to') else ""
restricted = m.restricted_to if hasattr(m, 'restricted_to') else ""
if target == 'all':
self.daytime_info[role] = [content, target, restricted]
else:
self.night_info[role] = [content, target, restricted]
# collect info from the night and identify the dead player
for role in self.night_info:
if "kill" in self.night_info[role][0] and self.night_info[role][1]:
target = self.night_info[role][1]
print("env.get_roles[target]", env, env.env.roles)
env.env.roles[target].set_status(ROLE_STATES[5])
for role in self.night_info:
if ("save" or "guard") in self.night_info[role][0]:
save_target = self.night_info[role][1]
if save_target == target:
env.env.roles[target].set_status(ROLE_STATES[0])
else:
dead_history.append(target)
# collect message from the daytime and identify the vote player
for role in self.daytime_info:
self.vote_message += f"\n{self.daytime_info[role][0]}"
vote_player = await self.llm.aask(VOTE_PROMPT.format(vote_message=self.vote_message))
dead_history.append(vote_player)
return dead_history, vote_player, PARSE_INSTRUCTIONS
class SummarizeNight(Action):

View file

@ -3,14 +3,6 @@ from metagpt.schema import Message
from metagpt.logs import logger
from examples.werewolf_game.actions import ACTIONS, Speak, InstructSpeak
ROLE_STATES = {
# 存活状态
0: "Alive", # 开场
1: "Dead", # 结束
2: "Protected", # 被保护
3: "Poisoned", # 被毒
4: "Saved", # 被救
}
class BasePlayer(Role):
def __init__(
@ -24,7 +16,7 @@ class BasePlayer(Role):
super().__init__(name, profile, **kwargs)
self._init_actions([Speak])
self._watch([InstructSpeak])
self.team = team
self.team = team
# 调用 get_status() 来检查存活状态,并通过 set_status() 更新状态。
self.status = 0 # 初始状态为活着

View file

@ -26,8 +26,8 @@ class Moderator(Role):
self.step_idx = 0
self.living_players = ["Player1", "Player2", "Player3", "Player4", "Player5"]
self.werewolf_players = ["Player1", "Player2"]
self.killed_player = "Player4" # 夜晚阶段,死掉的玩家
self.voted_out_player = "Player3" # 白天阶段,被投票出局的玩家
self.good_guys = ["Player3", "Player4", "Player5"]
self.dead_players = [] # 夜晚阶段,死掉的玩家
# 假设votes代表白天投票的结果key是被投票的玩家value是得票数
self.votes = {"Player1": 1, "Player2": 2, "Player3": 1, "Player4": 0, "Player5": 0}
@ -37,16 +37,26 @@ class Moderator(Role):
return await InstructSpeak().run(step_idx,
living_players=self.living_players,
werewolf_players=self.werewolf_players,
killed_player=self.killed_player,
voted_out_player=self.voted_out_player)
killed_player=self.dead_players,
voted_out_player="Player3")
async def _parse_speak(self):
# 解析玩家消息并返回结果
parse_result = await ParseSpeak().run()
async def _parse_speak(self, memories, env):
# 理解结果,更新各角色状态、游戏状态
self.dead_players, vote_player, parse_info = await ParseSpeak().run(dead_history=self.dead_players,
context=memories, env=env)
return "Player message processed"
# decide to move the game into the next phase
if not vote_player:
msg_content, send_to = parse_info[0], self.profile
# game's termination condition
elif all(item in self.dead_players for item in self.werewolf_players) or all(
item in self.dead_players for item in self.good_guys):
self.is_game_over = True
msg_content, send_to = parse_info[1], "all"
else:
# game's termination condition
msg_content, send_to = parse_info[2], ""
return msg_content, send_to
async def _think(self):
@ -80,8 +90,9 @@ class Moderator(Role):
cause_by=InstructSpeak, send_to=msg_to_send_to, restricted_to=msg_restriced_to)
elif isinstance(todo, ParseSpeak):
msg_content = await self._parse_speak()
msg = Message(content=msg_content, role=self.profile, sent_from=self.name, cause_by=ParseSpeak)
msg_content, send_to = await self._parse_speak(memories, self._rc)
msg = Message(content=msg_content, role=self.profile, sent_from=self.name, cause_by=ParseSpeak,
send_to=send_to)
elif isinstance(todo, AnnounceGameResult):
msg_content = await AnnounceGameResult().run(winner=self.winner)