sidnvy commited on
Commit
2f2fdc8
·
verified ·
1 Parent(s): bafeea9

Upload folder using huggingface_hub

Browse files
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
.gradio/flagged/dataset1.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ Number of Players (N),Total Squids (X),Current Distribution (comma-separated),"Tier Mapping (one range per line, e.g. '1:1\n2-4:2\n5-6:4')",Expected Value (Per Player),timestamp
2
+ 5,8,"1,0,0,3,0","1:1
3
+ 2-4:2
4
+ 5-6:4","Player 1: 0.0000
5
+ Player 2: -1.8976
6
+ Player 3: -1.8976
7
+ Player 4: 0.0000
8
+ Player 5: -1.8976",2025-02-07 19:10:39.723545
.pytest_cache/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # Created by pytest automatically.
2
+ *
.pytest_cache/CACHEDIR.TAG ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Signature: 8a477f597d28d172789f06886806bc55
2
+ # This file is a cache directory tag created by pytest.
3
+ # For information about cache directory tags, see:
4
+ # https://bford.info/cachedir/spec.html
.pytest_cache/README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # pytest cache directory #
2
+
3
+ This directory contains data from the pytest's cache plugin,
4
+ which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
5
+
6
+ **Do not** commit this to version control.
7
+
8
+ See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.
.pytest_cache/v/cache/nodeids ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "test_squid_game.py::test_case1",
3
+ "test_squid_game.py::test_case2",
4
+ "test_squid_game.py::test_case3",
5
+ "test_squid_game.py::test_case4",
6
+ "test_squid_game.py::test_case5",
7
+ "test_squid_game.py::test_case6",
8
+ "test_squid_game.py::test_case7"
9
+ ]
.pytest_cache/v/cache/stepwise ADDED
@@ -0,0 +1 @@
 
 
1
+ []
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Squidgame
3
- emoji: 💻
4
- colorFrom: yellow
5
- colorTo: gray
6
  sdk: gradio
7
  sdk_version: 5.15.0
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: squidgame
3
+ app_file: squid_game.py
 
 
4
  sdk: gradio
5
  sdk_version: 5.15.0
 
 
6
  ---
 
 
__pycache__/squid_game.cpython-310.pyc ADDED
Binary file (5.73 kB). View file
 
__pycache__/test_squid_game.cpython-310-pytest-8.3.4.pyc ADDED
Binary file (6.7 kB). View file
 
squid_game.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from functools import lru_cache
3
+
4
+ # 1) Define a function to parse user input for the tier multipliers.
5
+ # For simplicity, we'll ask them to enter threshold -> multiplier lines, e.g.:
6
+ # 1:1
7
+ # 2-4:2
8
+ # 5-6:4
9
+ def parse_tier_map(tier_str):
10
+ """
11
+ tier_str is something like:
12
+ "1:1\n2-4:2\n5-6:4\n7-10:8"
13
+ We'll return a list of tuples [(min_k, max_k, multiplier), ...]
14
+ in ascending order. Or any structure you prefer.
15
+ """
16
+ lines = tier_str.strip().splitlines()
17
+ tier_map = []
18
+ for line in lines:
19
+ # e.g. "2-4:2"
20
+ # split by ':'
21
+ range_part, mult_part = line.split(":")
22
+ multiplier = float(mult_part.strip())
23
+
24
+ # check if range_part has '-'
25
+ if '-' in range_part:
26
+ min_k_str, max_k_str = range_part.split('-')
27
+ min_k, max_k = int(min_k_str), int(max_k_str)
28
+ else:
29
+ # single value
30
+ min_k = max_k = int(range_part.strip())
31
+ tier_map.append((min_k, max_k, multiplier))
32
+
33
+ # Optionally sort by min_k
34
+ tier_map.sort(key=lambda x: x[0])
35
+ return tier_map
36
+
37
+ def tierMultiplier(k, tier_map):
38
+ """
39
+ Given k squids and a tier_map [(min_k, max_k, multiplier), ...],
40
+ return the appropriate multiplier.
41
+ If k=0, we can return 0 or skip.
42
+ """
43
+ if k == 0: # Explicitly handle k=0 case
44
+ return 0
45
+
46
+ for (low, high, mult) in tier_map:
47
+ if low <= k <= high:
48
+ return mult
49
+ # If k is bigger than any specified range, use the highest multiplier
50
+ return max(mult for _, _, mult in tier_map) if tier_map else 0
51
+
52
+ def is_terminal(distribution, r):
53
+ """
54
+ Check if distribution is a terminal state.
55
+ Condition 1: Exactly one player has 0
56
+ Condition 2: r == 0 (no more squids).
57
+ """
58
+ zero_count = sum(1 for x in distribution if x == 0)
59
+ if zero_count == 1:
60
+ return True
61
+ if r == 0:
62
+ return True
63
+ return False
64
+
65
+ def compute_final_payout(distribution, tier_map):
66
+ """
67
+ Compute final payoffs in a terminal state.
68
+ If exactly one 0-squid player -> that player pays sum of all others' multipliers.
69
+ If multiple 0-squid players when r=0, they share cost proportionally (here equally).
70
+ """
71
+ n = len(distribution)
72
+ zero_indices = [i for i,x in enumerate(distribution) if x == 0]
73
+ m = len(zero_indices) # number of zero-squid players
74
+
75
+ # sum of multipliers for all non-zero players
76
+ total_cost = sum(tierMultiplier(x, tier_map) for x in distribution if x > 0)
77
+
78
+ payouts = [0.0]*n
79
+
80
+ if m == 0:
81
+ # No zero-squid players => no cost
82
+ return payouts
83
+ elif m == 1:
84
+ # Exactly one zero player
85
+ i_zero = zero_indices[0]
86
+ payouts[i_zero] = -float(total_cost)
87
+ return payouts
88
+ else:
89
+ # Multiple zero players share the cost
90
+ portion = float(total_cost) / m
91
+ for i in zero_indices:
92
+ payouts[i] = -portion
93
+ return payouts
94
+
95
+ @lru_cache(None)
96
+ def get_expected_value(distribution, r, tier_map_tuple):
97
+ """
98
+ Memoized function returning the EV vector (size N) for state=(distribution, r).
99
+ tier_map_tuple is a tuple-ified version of the tier map so it's hashable for caching.
100
+ """
101
+ distribution = tuple(distribution)
102
+
103
+ # Terminal check
104
+ if is_terminal(distribution, r):
105
+ return tuple(compute_final_payout(distribution, tier_map_tuple))
106
+
107
+ n = len(distribution)
108
+ # We'll accumulate the EV in an array and then average
109
+ accumulated_ev = [0.0]*n
110
+
111
+ for winner in range(n):
112
+ new_dist = list(distribution)
113
+ new_dist[winner] += 1 # winner gets a squid
114
+
115
+ sub_ev = get_expected_value(tuple(new_dist), r - 1, tier_map_tuple)
116
+ for i in range(n):
117
+ accumulated_ev[i] += sub_ev[i]
118
+
119
+ # Average (each with probability 1/n)
120
+ for i in range(n):
121
+ accumulated_ev[i] /= n
122
+
123
+ return tuple(accumulated_ev)
124
+
125
+ def compute_ev(num_players, total_squids, current_distribution_str, tier_map_str):
126
+ """
127
+ Main function called by Gradio.
128
+ - num_players (N)
129
+ - total_squids (X)
130
+ - current_distribution_str: user enters e.g. "1,0,1,2,0"
131
+ - tier_map_str: user enters e.g. "1:1\n2-4:2\n5-6:4"
132
+ Returns: string representation of EV for each player.
133
+ """
134
+ try:
135
+ # 1) Parse distribution
136
+ distribution_list = [int(x.strip()) for x in current_distribution_str.split(",")]
137
+ # Basic check
138
+ if len(distribution_list) != num_players:
139
+ return f"Error: distribution length ({len(distribution_list)}) must match number of players ({num_players})!"
140
+
141
+ # 2) Parse tier map
142
+ parsed_tiers = parse_tier_map(tier_map_str)
143
+ # We'll store it in a hashable structure (tuple of tuples) for memoization
144
+ tier_map_tuple = tuple(parsed_tiers)
145
+
146
+ # 3) Remaining squids
147
+ current_sum = sum(distribution_list)
148
+ if current_sum > total_squids:
149
+ return f"Error: distribution sum ({current_sum}) exceeds total squids ({total_squids})."
150
+ r = total_squids - current_sum
151
+
152
+ # 4) Clear the cache each time we do a new computation
153
+ get_expected_value.cache_clear()
154
+
155
+ # 5) Compute EV
156
+ ev_result = get_expected_value(tuple(distribution_list), r, tier_map_tuple)
157
+
158
+ # 6) Format output
159
+ output_lines = []
160
+ for i, val in enumerate(ev_result):
161
+ output_lines.append(f"Player {i+1}: {val:.4f}")
162
+ return "\n".join(output_lines)
163
+ except Exception as e:
164
+ return f"Error: {str(e)}"
165
+
166
+ ### Gradio Interface Definition
167
+
168
+ def build_interface():
169
+ # Define inputs
170
+ num_players_input = gr.Number(label="Number of Players (N)", value=5, precision=0)
171
+ total_squids_input = gr.Number(label="Total Squids (X)", value=8, precision=0)
172
+ distribution_input = gr.Textbox(
173
+ label="Current Distribution (comma-separated)",
174
+ value="1,0,1,2,0" # example
175
+ )
176
+ tiermap_input = gr.Textbox(
177
+ label="Tier Mapping (one range per line, e.g. '1:1\\n2-4:2\\n5-6:4')",
178
+ value="1:1\n2-4:2\n5-6:4"
179
+ )
180
+
181
+ # Define output
182
+ result_output = gr.Textbox(label="Expected Value (Per Player)", lines=6)
183
+
184
+ # Define the interface
185
+ iface = gr.Interface(
186
+ fn=compute_ev,
187
+ inputs=[num_players_input, total_squids_input, distribution_input, tiermap_input],
188
+ outputs=result_output,
189
+ title="Texas Hold'em Squid Game EV Calculator",
190
+ description=(
191
+ "Enter the number of players, total squids, current distribution, and your tier map. "
192
+ "Click Submit to compute each player's Expected Value (EV) from this state."
193
+ )
194
+ )
195
+
196
+ return iface
197
+
198
+ # If running as a script, you can just do:
199
+ if __name__ == "__main__":
200
+ iface = build_interface()
201
+ iface.launch(share=True)
test_squid_game.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # test_squid_game.py
2
+
3
+ import pytest
4
+ from functools import lru_cache
5
+ from math import isclose
6
+
7
+ # Suppose your solver is in 'squid_game.py'
8
+ from squid_game import get_expected_value
9
+
10
+ @pytest.fixture
11
+ def test_tier_map():
12
+ """
13
+ A simple tier map for these tests:
14
+ 0 -> 0
15
+ 1 -> 1
16
+ 2 -> 2
17
+ 3+ -> 2 (for simplicity)
18
+ We'll store it in tuple form: ( (min_k, max_k, multiplier), ... )
19
+ """
20
+ # You can adapt if you prefer 3 -> multiplier=3. Just be consistent.
21
+ return (
22
+ (0,0,0.0),
23
+ (1,1,1.0),
24
+ (2,2,2.0),
25
+ (3,10000,2.0), # anything >=3 => 2
26
+ )
27
+
28
+ def nearly_equal(a, b, tol=1e-9):
29
+ return isclose(a, b, abs_tol=tol)
30
+
31
+ def test_case1(test_tier_map):
32
+ # N=2, X=1, dist=(0,0) => EV = (-0.5, -0.5)
33
+ dist = (0,0)
34
+ X = 1
35
+ r = X - sum(dist)
36
+ get_expected_value.cache_clear()
37
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
38
+ assert len(ev) == 2
39
+ assert nearly_equal(ev[0], -0.5)
40
+ assert nearly_equal(ev[1], -0.5)
41
+
42
+ def test_case2(test_tier_map):
43
+ # N=2, X=2, dist=(0,0) => EV = (-0.5, -0.5)
44
+ dist = (0,0)
45
+ X = 2
46
+ r = X - sum(dist)
47
+ get_expected_value.cache_clear()
48
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
49
+ assert len(ev) == 2
50
+ assert nearly_equal(ev[0], -0.5)
51
+ assert nearly_equal(ev[1], -0.5)
52
+
53
+ def test_case3(test_tier_map):
54
+ # N=2, X=2, dist=(1,0) => terminal => payoff = (0, -1)
55
+ # because there's exactly one zero-squid player at start.
56
+ dist = (1,0)
57
+ X = 2
58
+ r = X - sum(dist)
59
+ get_expected_value.cache_clear()
60
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
61
+ assert len(ev) == 2
62
+ assert nearly_equal(ev[0], 0.0)
63
+ assert nearly_equal(ev[1], -1.0)
64
+
65
+ def test_case4(test_tier_map):
66
+ # N=3, X=3, dist=(0,0,3) => multiple zero => final => cost= tier(3)=2 => each zero pays -1 => (-1, -1, 0)
67
+ dist = (0,0,3)
68
+ X = 3
69
+ r = X - sum(dist)
70
+ get_expected_value.cache_clear()
71
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
72
+ assert len(ev) == 3
73
+ assert nearly_equal(ev[0], -1.0)
74
+ assert nearly_equal(ev[1], -1.0)
75
+ assert nearly_equal(ev[2], 0.0)
76
+
77
+ def test_case5(test_tier_map):
78
+ # N=3, X=2, dist=(0,1,1) => one zero => final => cost= tier(1)+tier(1)=1+1=2 => p1=-2, p2=0, p3=0
79
+ dist = (0,1,1)
80
+ X = 2
81
+ r = X - sum(dist)
82
+ get_expected_value.cache_clear()
83
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
84
+ assert len(ev) == 3
85
+ assert nearly_equal(ev[0], -2.0)
86
+ assert nearly_equal(ev[1], 0.0)
87
+ assert nearly_equal(ev[2], 0.0)
88
+
89
+ def test_case6(test_tier_map):
90
+ # N=3, X=2, dist=(1,0,1) => one zero => cost=2 => payoff= (0, -2, 0)
91
+ dist = (1,0,1)
92
+ X = 2
93
+ r = X - sum(dist)
94
+ get_expected_value.cache_clear()
95
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
96
+ assert len(ev) == 3
97
+ assert nearly_equal(ev[0], 0.0)
98
+ assert nearly_equal(ev[1], -2.0)
99
+ assert nearly_equal(ev[2], 0.0)
100
+
101
+ def test_case7(test_tier_map):
102
+ # N=2, X=3, dist=(1,1) => not terminal => 1 leftover => final => either (2,1) or (1,2) => no zero => payoff=(0,0).
103
+ dist = (1,1)
104
+ X = 3
105
+ r = X - sum(dist)
106
+ get_expected_value.cache_clear()
107
+ ev = get_expected_value(dist, r, tier_map_tuple=test_tier_map)
108
+ assert len(ev) == 2
109
+ # Both outcomes => no zero => payoff= (0,0) with probability 1 => EV=(0,0)
110
+ assert nearly_equal(ev[0], 0.0)
111
+ assert nearly_equal(ev[1], 0.0)