sidnvy commited on
Commit
4a67ae9
·
verified ·
1 Parent(s): 434b789

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. squid_game.py +17 -4
  2. squid_game_core.py +10 -23
  3. test_squid_game.py +60 -4
squid_game.py CHANGED
@@ -70,12 +70,25 @@ def solve_game(distribution: str, total_squids: int, tier_map_str: str) -> str:
70
  for i, ev in enumerate(expected_values):
71
  result += f"Player {i+1}: {ev:.3f}\n"
72
 
73
- # Add next squid gains information
74
- gains = next_squid_gain_for_nonzero(dist, tier_map)
 
 
 
 
 
 
 
 
 
 
75
  if gains:
76
  result += "\nPotential Gains from Next Squid:\n"
77
- for player_idx, gain in gains.items():
78
- result += f"Player {player_idx+1}: +{gain:.1f} \n"
 
 
 
79
 
80
  # Add tier map interpretation
81
  result += "\nTier Map Interpretation:\n"
 
70
  for i, ev in enumerate(expected_values):
71
  result += f"Player {i+1}: {ev:.3f}\n"
72
 
73
+ # Calculate penalty from expected values of zero-squid players
74
+ zero_player_evs = [ev for i, ev in enumerate(expected_values) if dist[i] == 0]
75
+ if zero_player_evs:
76
+ # Verify all zero-squid players have same expected value
77
+ if not all(abs(ev - zero_player_evs[0]) < 1e-6 for ev in zero_player_evs):
78
+ return "Error: Zero-squid players have different expected values"
79
+ penalty = abs(zero_player_evs[0])
80
+ else:
81
+ penalty = 0
82
+
83
+ # Calculate potential gains using hypothetical_next_round_gain with actual penalty
84
+ gains = hypothetical_next_round_gain(dist, tier_map, penalty=penalty)
85
  if gains:
86
  result += "\nPotential Gains from Next Squid:\n"
87
+ for player_idx, gain in enumerate(gains):
88
+ result += f"Player {player_idx+1}: +{gain:.1f}"
89
+ if dist[player_idx] == 0:
90
+ result += " (includes avoiding payment share)"
91
+ result += "\n"
92
 
93
  # Add tier map interpretation
94
  result += "\nTier Map Interpretation:\n"
squid_game_core.py CHANGED
@@ -55,7 +55,7 @@ def compute_final_payout(distribution, tier_map):
55
  """
56
  distribution: e.g. (0,0,4)
57
 
58
- NEW RULES:
59
  - If exactly 1 zero-squid => that one pays sum_of_winners_tier
60
  - If multiple zeros => each zero-squid pays sum_of_winners_tier individually
61
  => each winner gets (number_of_zero_squids * winner_tier_value).
@@ -73,22 +73,14 @@ def compute_final_payout(distribution, tier_map):
73
  if m == 0:
74
  # No zeros => no payment => everyone gets 0
75
  return payoffs
76
- elif m == 1:
77
- # Exactly one zero-squid => that player pays the entire sum
78
- z = zero_indices[0]
79
- payoffs[z] = -sum_winner_values
80
- # each winner receives exactly their own tierValue
81
- # so we set payoffs[winner] = winner_values[i]
82
- for i, w in enumerate(winner_indices):
83
- payoffs[w] = winner_values[i]
84
- return payoffs
85
  else:
86
- # multiple zeros => each zero pays sum_winner_values
87
- # => each winner receives m * (their own tierValue)
88
  for z in zero_indices:
89
  payoffs[z] = -sum_winner_values
 
 
90
  for i, w in enumerate(winner_indices):
91
- payoffs[w] = m * winner_values[i]
92
  return payoffs
93
 
94
  def format_state(distribution, remaining):
@@ -124,21 +116,16 @@ def next_squid_gain_for_nonzero(distribution, tier_map):
124
  """
125
  Returns a dict: {player_index: gain in tierValue if that player goes from s_i to s_i+1}.
126
  Only for players who currently hold > 0 squids.
127
-
128
- Example:
129
- if distribution=(4,0,2) with "1-4:1,5-6:3":
130
- - Player0 has 4 => tierValue(4)=4 => tierValue(5)=15 => gain=11
131
- - Player1 has 0 => skip
132
- - Player2 has 2 => tierValue(2)=2*1=2 => tierValue(3)=3 => gain=1
133
  """
134
  results = {}
135
  for i, s in enumerate(distribution):
136
- curr_val = tierValue(s, tier_map)
137
- next_val = tierValue(s+1, tier_map)
138
- results[i] = next_val - curr_val
 
139
  return results
140
 
141
- def hypothetical_next_round_gain(distribution, tier_map, penalty=24):
142
  """
143
  Returns a list (or dict) of length N, indicating how much "extra" reward
144
  each player would get if they, individually, are the *sole* winner next round.
 
55
  """
56
  distribution: e.g. (0,0,4)
57
 
58
+ RULES:
59
  - If exactly 1 zero-squid => that one pays sum_of_winners_tier
60
  - If multiple zeros => each zero-squid pays sum_of_winners_tier individually
61
  => each winner gets (number_of_zero_squids * winner_tier_value).
 
73
  if m == 0:
74
  # No zeros => no payment => everyone gets 0
75
  return payoffs
 
 
 
 
 
 
 
 
 
76
  else:
77
+ # Each zero pays sum_winner_values
 
78
  for z in zero_indices:
79
  payoffs[z] = -sum_winner_values
80
+ # Each winner gets their tierValue (if single loser)
81
+ # or m * their tierValue (if multiple losers)
82
  for i, w in enumerate(winner_indices):
83
+ payoffs[w] = winner_values[i] if m == 1 else m * winner_values[i]
84
  return payoffs
85
 
86
  def format_state(distribution, remaining):
 
116
  """
117
  Returns a dict: {player_index: gain in tierValue if that player goes from s_i to s_i+1}.
118
  Only for players who currently hold > 0 squids.
 
 
 
 
 
 
119
  """
120
  results = {}
121
  for i, s in enumerate(distribution):
122
+ if s > 0: # Only include non-zero players
123
+ curr_val = tierValue(s, tier_map)
124
+ next_val = tierValue(s+1, tier_map)
125
+ results[i] = next_val - curr_val
126
  return results
127
 
128
+ def hypothetical_next_round_gain(distribution, tier_map, penalty):
129
  """
130
  Returns a list (or dict) of length N, indicating how much "extra" reward
131
  each player would get if they, individually, are the *sole* winner next round.
test_squid_game.py CHANGED
@@ -11,7 +11,8 @@ from squid_game_core import (
11
  is_terminal,
12
  compute_final_payout,
13
  get_expected_value,
14
- next_squid_gain_for_nonzero
 
15
  )
16
 
17
  def nearly_equal(a, b, tol=1e-9):
@@ -50,12 +51,15 @@ def test_multiple_losers_pay_individually(tier_map_example):
50
  def test_single_loser(tier_map_example):
51
  """
52
  Scenario: 2 players => final distribution=(1,0).
53
- => 1 zero => that zero pays sum_of_winners= tierValue(1)=1 => payoff=(0, -1).
 
 
 
54
  """
55
  dist = (1,0)
56
  payoffs = compute_final_payout(dist, tier_map_example)
57
- assert nearly_equal(payoffs[0], 0)
58
- assert nearly_equal(payoffs[1], -1)
59
 
60
  def test_no_losers(tier_map_example):
61
  """
@@ -142,3 +146,55 @@ def test_ev_multiple_losers_specific(tier_map_example):
142
  assert nearly_equal(ev[2], 4)
143
  # sum = 0
144
  assert nearly_equal(sum(ev), 0.0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  is_terminal,
12
  compute_final_payout,
13
  get_expected_value,
14
+ next_squid_gain_for_nonzero,
15
+ hypothetical_next_round_gain
16
  )
17
 
18
  def nearly_equal(a, b, tol=1e-9):
 
51
  def test_single_loser(tier_map_example):
52
  """
53
  Scenario: 2 players => final distribution=(1,0).
54
+ => 1 zero => that zero pays sum_of_winners= tierValue(1)=1
55
+ => payoff=(1, -1) because:
56
+ - Winner keeps their tierValue (1)
57
+ - Loser pays that amount (-1)
58
  """
59
  dist = (1,0)
60
  payoffs = compute_final_payout(dist, tier_map_example)
61
+ assert nearly_equal(payoffs[0], 1) # Winner gets tierValue(1)=1
62
+ assert nearly_equal(payoffs[1], -1) # Loser pays -1
63
 
64
  def test_no_losers(tier_map_example):
65
  """
 
146
  assert nearly_equal(ev[2], 4)
147
  # sum = 0
148
  assert nearly_equal(sum(ev), 0.0)
149
+
150
+ def test_hypothetical_next_round_gain_with_penalty():
151
+ """
152
+ Test scenario: 3 players with distribution=(0,0,2)
153
+ Expected values would be (-2,-2,4) as shown in test_ev_multiple_losers_specific
154
+ So penalty should be 2 (abs of -2)
155
+
156
+ For zero-squid players (0,1):
157
+ - Getting 1 squid = tierValue(1) = 1
158
+ - Avoiding penalty share = 2/2 = 1 (penalty/zero_count)
159
+ - Total gain = 2
160
+
161
+ For player with 2 squids:
162
+ - Going from 2 to 3 = tierValue(3) - tierValue(2) = 3 - 2 = 1
163
+ """
164
+ tier_map = (
165
+ (0,0,0.0),
166
+ (1,4,1.0),
167
+ (5,6,3.0)
168
+ )
169
+ dist = (0,0,2)
170
+ penalty = 2 # abs of -2 from expected values
171
+
172
+ gains = hypothetical_next_round_gain(dist, tier_map, penalty)
173
+
174
+ # Check zero-squid players
175
+ assert nearly_equal(gains[0], 2.0), f"Expected gain 2.0 for player 1, got {gains[0]}"
176
+ assert nearly_equal(gains[1], 2.0), f"Expected gain 2.0 for player 2, got {gains[1]}"
177
+
178
+ # Check non-zero player
179
+ assert nearly_equal(gains[2], 1.0), f"Expected gain 1.0 for player 3, got {gains[2]}"
180
+
181
+ def test_hypothetical_next_round_gain_no_zeros():
182
+ """
183
+ Test scenario: 2 players with distribution=(1,2)
184
+ No zero-squid players, so penalty doesn't matter
185
+
186
+ Player 1: going from 1 to 2 = tierValue(2) - tierValue(1) = 2 - 1 = 1
187
+ Player 2: going from 2 to 3 = tierValue(3) - tierValue(2) = 3 - 2 = 1
188
+ """
189
+ tier_map = (
190
+ (0,0,0.0),
191
+ (1,4,1.0),
192
+ (5,6,3.0)
193
+ )
194
+ dist = (1,2)
195
+ penalty = 0 # doesn't matter since no zero-squid players
196
+
197
+ gains = hypothetical_next_round_gain(dist, tier_map, penalty)
198
+
199
+ assert nearly_equal(gains[0], 1.0), f"Expected gain 1.0 for player 1, got {gains[0]}"
200
+ assert nearly_equal(gains[1], 1.0), f"Expected gain 1.0 for player 2, got {gains[1]}"