Eric Botti commited on
Commit
172af0f
·
1 Parent(s): 1a8a579

added game and player level logging

Browse files
Files changed (4) hide show
  1. src/game.py +28 -13
  2. src/game_utils.py +7 -0
  3. src/main.py +2 -0
  4. src/player.py +13 -1
src/game.py CHANGED
@@ -11,13 +11,15 @@ NUMBER_OF_PLAYERS = 5
11
 
12
  class Game:
13
  log_dir = os.path.join(os.pardir, "experiments")
14
- player_log_file = "{game_id}-{role}-{player_num}.jsonl"
15
  parser_log_file = "{game_id}-parser.jsonl"
 
16
 
17
- def __init__(self,
18
- human_name: str = None,
19
- number_of_players: int = NUMBER_OF_PLAYERS
20
- ):
 
21
 
22
  # Game ID
23
  self.game_id = game_id()
@@ -28,6 +30,7 @@ class Game:
28
  self.human_index = random_index(number_of_players)
29
  else:
30
  ai_names = random_names(number_of_players)
 
31
 
32
  # Choose Chameleon
33
  self.chameleon_index = random_index(number_of_players)
@@ -47,10 +50,14 @@ class Game:
47
  else:
48
  role = "herd"
49
 
50
- log_path = os.path.join(self.log_dir,
51
- self.player_log_file.format(game_id=self.game_id, role=role, player_num=i))
52
 
53
- self.players.append(Player(name, controller, role, log_filepath=log_path))
 
 
 
 
 
54
 
55
  # Game State
56
  self.player_responses = []
@@ -74,9 +81,9 @@ class Game:
74
  self.player_responses = []
75
  herd_animal = random_animal()
76
 
77
- game_over = False
78
 
79
- while not game_over:
80
  # Phase I: Collect Player Animal Descriptions
81
  for player in self.players:
82
  if player.role == "chameleon":
@@ -113,10 +120,8 @@ class Game:
113
  output = await self.parser.parse(prompt, response, ChameleonGuessAnimalModel)
114
 
115
  if output.animal == herd_animal:
116
- game_over = True
117
  winner = "chameleon"
118
  else:
119
- game_over = True
120
  winner = "herd"
121
 
122
  else:
@@ -142,7 +147,6 @@ class Game:
142
  accused_player = count_chameleon_votes(player_votes)
143
 
144
  if accused_player:
145
- game_over = True
146
  if accused_player == self.players[self.chameleon_index].name:
147
  winner = "herd"
148
  else:
@@ -156,3 +160,14 @@ class Game:
156
  # Herd Wins by Correctly Guessing Chameleon - 2 points (each)
157
 
158
  # Log Game Info
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  class Game:
13
  log_dir = os.path.join(os.pardir, "experiments")
14
+ player_log_file = "{player_id}.jsonl"
15
  parser_log_file = "{game_id}-parser.jsonl"
16
+ game_log_file = "{game_id}-game.jsonl"
17
 
18
+ def __init__(
19
+ self,
20
+ human_name: str = None,
21
+ number_of_players: int = NUMBER_OF_PLAYERS
22
+ ):
23
 
24
  # Game ID
25
  self.game_id = game_id()
 
30
  self.human_index = random_index(number_of_players)
31
  else:
32
  ai_names = random_names(number_of_players)
33
+ self.human_index = None
34
 
35
  # Choose Chameleon
36
  self.chameleon_index = random_index(number_of_players)
 
50
  else:
51
  role = "herd"
52
 
53
+ player_id = f"{self.game_id}-{i + 1}-{role}"
 
54
 
55
+ log_path = os.path.join(
56
+ self.log_dir,
57
+ self.player_log_file.format(player_id=player_id)
58
+ )
59
+
60
+ self.players.append(Player(name, controller, role, player_id, log_filepath=log_path))
61
 
62
  # Game State
63
  self.player_responses = []
 
81
  self.player_responses = []
82
  herd_animal = random_animal()
83
 
84
+ winner = None
85
 
86
+ while not winner:
87
  # Phase I: Collect Player Animal Descriptions
88
  for player in self.players:
89
  if player.role == "chameleon":
 
120
  output = await self.parser.parse(prompt, response, ChameleonGuessAnimalModel)
121
 
122
  if output.animal == herd_animal:
 
123
  winner = "chameleon"
124
  else:
 
125
  winner = "herd"
126
 
127
  else:
 
147
  accused_player = count_chameleon_votes(player_votes)
148
 
149
  if accused_player:
 
150
  if accused_player == self.players[self.chameleon_index].name:
151
  winner = "herd"
152
  else:
 
160
  # Herd Wins by Correctly Guessing Chameleon - 2 points (each)
161
 
162
  # Log Game Info
163
+ game_log = {
164
+ "game_id": self.game_id,
165
+ "herd_animal": herd_animal,
166
+ "number_of_players": len(self.players),
167
+ "human_player": self.players[self.human_index].id if self.human_index else "None",
168
+ "chameleon": self.players[self.chameleon_index].id,
169
+ "winner": winner
170
+ }
171
+ game_log_path = os.path.join(self.log_dir, self.game_log_file.format(game_id=self.game_id))
172
+
173
+ log(game_log, game_log_path)
src/game_utils.py CHANGED
@@ -3,6 +3,7 @@ Utilities for the game including random selections and prompts.
3
  """
4
  import random
5
  import string
 
6
  from collections import Counter
7
 
8
  ALPHABET = string.ascii_lowercase + string.digits
@@ -46,6 +47,12 @@ def count_chameleon_votes(player_votes: list[str]) -> str | None:
46
  return None
47
 
48
 
 
 
 
 
 
 
49
  def fetch_prompt(prompt_name):
50
  return prompts[prompt_name]
51
 
 
3
  """
4
  import random
5
  import string
6
+ import json
7
  from collections import Counter
8
 
9
  ALPHABET = string.ascii_lowercase + string.digits
 
47
  return None
48
 
49
 
50
+ def log(log_object, log_file):
51
+ with open(log_file, "a+") as f:
52
+ f.write(json.dumps(log_object) + "\n")
53
+
54
+
55
+ # Prompt Stuff
56
  def fetch_prompt(prompt_name):
57
  return prompts[prompt_name]
58
 
src/main.py CHANGED
@@ -8,6 +8,8 @@ def main():
8
 
9
  game = Game(human_name=name)
10
 
 
 
11
  asyncio.run(game.start())
12
 
13
 
 
8
 
9
  game = Game(human_name=name)
10
 
11
+ # game = Game()
12
+
13
  asyncio.run(game.start())
14
 
15
 
src/player.py CHANGED
@@ -1,10 +1,12 @@
1
  import os
 
2
  import asyncio
3
 
4
  import openai
5
  from agents import LogMessagesKani
6
  from kani.engines.openai import OpenAIEngine
7
 
 
8
 
9
  # Using TGI Inference Endpoints from Hugging Face
10
  # api_type = "tgi"
@@ -24,8 +26,9 @@ openai_engine = OpenAIEngine(model="gpt-3.5-turbo")
24
 
25
 
26
  class Player:
27
- def __init__(self, name: str, controller_type: str, role: str, log_filepath: str = None):
28
  self.name = name
 
29
  self.controller = controller_type
30
  if controller_type == "ai":
31
  self.kani = LogMessagesKani(openai_engine, log_filepath=log_filepath)
@@ -33,6 +36,15 @@ class Player:
33
  self.role = role
34
  self.messages = []
35
 
 
 
 
 
 
 
 
 
 
36
  async def respond_to(self, prompt: str) -> str:
37
  """Makes the player respond to a prompt. Returns the response."""
38
  # Generate a response from the controller
 
1
  import os
2
+ import json
3
  import asyncio
4
 
5
  import openai
6
  from agents import LogMessagesKani
7
  from kani.engines.openai import OpenAIEngine
8
 
9
+ from game_utils import log
10
 
11
  # Using TGI Inference Endpoints from Hugging Face
12
  # api_type = "tgi"
 
26
 
27
 
28
  class Player:
29
+ def __init__(self, name: str, controller_type: str, role: str, id: str = None, log_filepath: str = None):
30
  self.name = name
31
+ self.id = id
32
  self.controller = controller_type
33
  if controller_type == "ai":
34
  self.kani = LogMessagesKani(openai_engine, log_filepath=log_filepath)
 
36
  self.role = role
37
  self.messages = []
38
 
39
+ if log_filepath:
40
+ player_info = {
41
+ "id": self.id,
42
+ "name": self.name,
43
+ "role": self.role,
44
+ "controller": controller_type,
45
+ }
46
+ log(player_info, log_filepath)
47
+
48
  async def respond_to(self, prompt: str) -> str:
49
  """Makes the player respond to a prompt. Returns the response."""
50
  # Generate a response from the controller