mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-05-24 14:15:17 +02:00
添加了ivan写的parse speak
This commit is contained in:
parent
4584435bc6
commit
e5140fd6a5
3 changed files with 100 additions and 22 deletions
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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 # 初始状态为活着
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue