init
This commit is contained in:
149
AlgoriAgent/examples/game_werewolf/werewolf.py
Normal file
149
AlgoriAgent/examples/game_werewolf/werewolf.py
Normal file
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""A werewolf game implemented by agentscope."""
|
||||
from functools import partial
|
||||
|
||||
from prompt import Prompts
|
||||
from werewolf_utils import (
|
||||
check_winning,
|
||||
update_alive_players,
|
||||
majority_vote,
|
||||
extract_name_and_id,
|
||||
n2s,
|
||||
set_parsers,
|
||||
)
|
||||
from agentscope.message import Msg
|
||||
from agentscope.msghub import msghub
|
||||
from agentscope.pipelines.functional import sequentialpipeline
|
||||
import agentscope
|
||||
|
||||
|
||||
# pylint: disable=too-many-statements
|
||||
def main() -> None:
|
||||
"""werewolf game"""
|
||||
# default settings
|
||||
HostMsg = partial(Msg, name="Moderator", role="assistant", echo=True)
|
||||
healing, poison = True, True
|
||||
MAX_WEREWOLF_DISCUSSION_ROUND = 3
|
||||
MAX_GAME_ROUND = 6
|
||||
# read model and agent configs, and initialize agents automatically
|
||||
survivors = agentscope.init(
|
||||
model_configs="./configs/model_configs.json",
|
||||
agent_configs="./configs/agent_configs.json",
|
||||
project="Werewolf",
|
||||
)
|
||||
|
||||
roles = ["werewolf", "werewolf", "villager", "villager", "seer", "witch"]
|
||||
wolves, witch, seer = survivors[:2], survivors[-1], survivors[-2]
|
||||
|
||||
# start the game
|
||||
for _ in range(1, MAX_GAME_ROUND + 1):
|
||||
# night phase, werewolves discuss
|
||||
hint = HostMsg(content=Prompts.to_wolves.format(n2s(wolves)))
|
||||
with msghub(wolves, announcement=hint) as hub:
|
||||
set_parsers(wolves, Prompts.wolves_discuss_parser)
|
||||
for _ in range(MAX_WEREWOLF_DISCUSSION_ROUND):
|
||||
x = sequentialpipeline(wolves)
|
||||
if x.metadata.get("finish_discussion", False):
|
||||
break
|
||||
|
||||
# werewolves vote
|
||||
set_parsers(wolves, Prompts.wolves_vote_parser)
|
||||
hint = HostMsg(content=Prompts.to_wolves_vote)
|
||||
votes = [
|
||||
extract_name_and_id(wolf(hint).content)[0] for wolf in wolves
|
||||
]
|
||||
# broadcast the result to werewolves
|
||||
dead_player = [majority_vote(votes)]
|
||||
hub.broadcast(
|
||||
HostMsg(content=Prompts.to_wolves_res.format(dead_player[0])),
|
||||
)
|
||||
|
||||
# witch
|
||||
healing_used_tonight = False
|
||||
if witch in survivors:
|
||||
if healing:
|
||||
hint = HostMsg(
|
||||
content=Prompts.to_witch_resurrect.format_map(
|
||||
{
|
||||
"witch_name": witch.name,
|
||||
"dead_name": dead_player[0],
|
||||
},
|
||||
),
|
||||
)
|
||||
set_parsers(witch, Prompts.witch_resurrect_parser)
|
||||
if witch(hint).metadata.get("resurrect", False):
|
||||
healing_used_tonight = True
|
||||
dead_player.pop()
|
||||
healing = False
|
||||
HostMsg(content=Prompts.to_witch_resurrect_yes)
|
||||
else:
|
||||
HostMsg(content=Prompts.to_witch_resurrect_no)
|
||||
|
||||
if poison and not healing_used_tonight:
|
||||
set_parsers(witch, Prompts.witch_poison_parser)
|
||||
x = witch(HostMsg(content=Prompts.to_witch_poison))
|
||||
if x.metadata.get("eliminate", False):
|
||||
dead_player.append(extract_name_and_id(x.content)[0])
|
||||
poison = False
|
||||
|
||||
# seer
|
||||
if seer in survivors:
|
||||
hint = HostMsg(
|
||||
content=Prompts.to_seer.format(seer.name, n2s(survivors)),
|
||||
)
|
||||
set_parsers(seer, Prompts.seer_parser)
|
||||
x = seer(hint)
|
||||
|
||||
player, idx = extract_name_and_id(x.content)
|
||||
role = "werewolf" if roles[idx] == "werewolf" else "villager"
|
||||
hint = HostMsg(content=Prompts.to_seer_result.format(player, role))
|
||||
seer.observe(hint)
|
||||
|
||||
survivors, wolves = update_alive_players(
|
||||
survivors,
|
||||
wolves,
|
||||
dead_player,
|
||||
)
|
||||
if check_winning(survivors, wolves, "Moderator"):
|
||||
break
|
||||
|
||||
# daytime discussion
|
||||
content = (
|
||||
Prompts.to_all_danger.format(n2s(dead_player))
|
||||
if dead_player
|
||||
else Prompts.to_all_peace
|
||||
)
|
||||
hints = [
|
||||
HostMsg(content=content),
|
||||
HostMsg(content=Prompts.to_all_discuss.format(n2s(survivors))),
|
||||
]
|
||||
with msghub(survivors, announcement=hints) as hub:
|
||||
# discuss
|
||||
set_parsers(survivors, Prompts.survivors_discuss_parser)
|
||||
x = sequentialpipeline(survivors)
|
||||
|
||||
# vote
|
||||
set_parsers(survivors, Prompts.survivors_vote_parser)
|
||||
hint = HostMsg(content=Prompts.to_all_vote.format(n2s(survivors)))
|
||||
votes = [
|
||||
extract_name_and_id(_(hint).content)[0] for _ in survivors
|
||||
]
|
||||
vote_res = majority_vote(votes)
|
||||
# broadcast the result to all players
|
||||
result = HostMsg(content=Prompts.to_all_res.format(vote_res))
|
||||
hub.broadcast(result)
|
||||
|
||||
survivors, wolves = update_alive_players(
|
||||
survivors,
|
||||
wolves,
|
||||
vote_res,
|
||||
)
|
||||
|
||||
if check_winning(survivors, wolves, "Moderator"):
|
||||
break
|
||||
|
||||
hub.broadcast(HostMsg(content=Prompts.to_all_continue))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user