研究 · 休闲、经营 · 第 1 赛季 · shoal/overcooked

Overcooked

要打败的Starter (GreedyHumanModel) 97.7778
加入
What shoal-games changes in this game
由 @shoal shoal 从 main 的 28c377d 分出 · 领先 1 个提交,比 main 落后 0 个
接续
贡献回去
69 行 · 3.3 KB 原始文件 永久链接 历史
1"""The project's referee. Overcooked is cooperative: a route's bot is a cook, and the season's field are the partners
2it cooks with. check: with each partner, on each layout, in both seats, one episode of 400 steps; the score is the
3mean reward (20 for each soup served), each partner a subtask. practice: one episode with each partner on the first
4layout, a replay of each in replays/.
5 python3 -I referee/play.py check|practice <route folder>
6"""
7import json, os, sys
8
9ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
10sys.path.insert(0, os.path.join(ROOT, 'kit'))
11import league # noqa: E402
12from host import Child # noqa: E402
13from overcooked_ai_py.mdp.actions import Action # noqa: E402
14from overcooked_ai_py.mdp.overcooked_env import OvercookedEnv # noqa: E402
15from overcooked_ai_py.mdp.overcooked_mdp import OvercookedGridworld # noqa: E402
16
17LAYOUTS = ['cramped_room', 'asymmetric_advantages', 'coordination_ring']
18HORIZON = 400
19
20
21def cook(folder):
22 bot = os.path.join(league.bot_dir(folder), 'bot.py')
23 if not os.path.isfile(bot):
24 sys.exit(f'No bot in {folder}: add bot.py with make_agent(mdp, mlam) or a class Agent')
25 return Child([sys.executable, '-s', os.path.join(ROOT, 'referee', 'child.py'), bot], cwd=os.path.dirname(bot), limit=1.0, start=60)
26
27
28def episode(cooks, layout, seed):
29 mdp = OvercookedGridworld.from_layout_name(layout)
30 env = OvercookedEnv.from_mdp(mdp, horizon=HORIZON, info_level=0)
31 for seat, c in enumerate(cooks):
32 c.ask({'episode': {'layout': layout, 'seat': seat, 'seed': seed + seat, 'horizon': HORIZON}}, limit=120)
33 frames, score, done = [], 0, False
34 while not done:
35 s = env.state.to_dict()
36 frames.append({'state': s, 'score': score})
37 picks = [c.ask({'state': s}) for c in cooks]
38 joint = tuple(Action.INDEX_TO_ACTION[p] if isinstance(p, int) and 0 <= p < len(Action.INDEX_TO_ACTION) else Action.STAY for p in picks)
39 _, r, done, _ = env.step(joint)
40 score += r
41 frames.append({'state': env.state.to_dict(), 'score': score})
42 return score, {'game': 'overcooked', 'layout': layout, 'terrain': mdp.terrain_mtx, 'horizon': HORIZON, 'score': score, 'frames': frames}
43
44
45def main(mode, route):
46 me = cook(route)
47 name = league.route_name()
48 reps = league.Replays() if mode == 'practice' else None
49 subtasks = {}
50 for partner in league.field(os.path.join(ROOT, 'field')):
51 them = cook(os.path.join(ROOT, 'field', partner))
52 got = []
53 for k, layout in enumerate(LAYOUTS if mode == 'check' else LAYOUTS[:1]):
54 for seat in (0, 1) if mode == 'check' else (0,):
55 cooks = [me, them] if seat == 0 else [them, me]
56 score, replay = episode(cooks, layout, 1000 * k + seat)
57 got.append(score)
58 if reps:
59 who = [name, partner] if seat == 0 else [partner, name]
60 replay['players'] = who
61 reps.add(f'{partner}-{layout}.json', replay, f'{who[0]} (blue) and {who[1]} (green) in {layout.replace("_", " ")}', who, f'{int(score // 20)} soups served, {int(score)} points')
62 them.close()
63 subtasks[partner] = sum(got) / len(got)
64 me.close()
65 league.write_metrics(sum(subtasks.values()) / len(subtasks), subtasks)
66
67
68if __name__ == '__main__':
69 main(sys.argv[1], sys.argv[2])