kaggle-environments 1.23.5__py3-none-any.whl → 1.23.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/components/getRepeatedPokerStateForStep.js +312 -143
- kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/main.ts +27 -27
- kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/repeated_poker_renderer.js +5 -6
- {kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/METADATA +1 -1
- {kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/RECORD +8 -8
- {kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/WHEEL +0 -0
- {kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/entry_points.txt +0 -0
- {kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,63 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
const moves = [];
|
|
1
|
+
const PLACEHOLDER_CARD = '2c';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
function _getActionStringsFromACPC(bettingString, nextPlayerIndex, numPlayers = 2) {
|
|
4
|
+
const moves = [];
|
|
5
5
|
const streets = bettingString.split('/');
|
|
6
|
-
|
|
7
|
-
// Process each street's actions
|
|
8
6
|
for (let streetIndex = 0; streetIndex < streets.length; streetIndex++) {
|
|
9
7
|
const streetAction = streets[streetIndex];
|
|
10
8
|
let i = 0;
|
|
11
|
-
|
|
12
|
-
// 4. Parse the moves within the street
|
|
13
9
|
while (i < streetAction.length) {
|
|
14
10
|
const char = streetAction[i];
|
|
15
|
-
|
|
16
11
|
if (char === 'r') {
|
|
17
12
|
let amount = '';
|
|
18
13
|
i++;
|
|
19
|
-
// parse all digits of the raise amount
|
|
20
14
|
while (i < streetAction.length && streetAction[i] >= '0' && streetAction[i] <= '9') {
|
|
21
15
|
amount += streetAction[i];
|
|
22
16
|
i++;
|
|
23
17
|
}
|
|
24
|
-
moves.push(`r${amount}`)
|
|
18
|
+
moves.push(`r${amount}`);
|
|
25
19
|
} else {
|
|
26
20
|
moves.push(char);
|
|
27
21
|
i++;
|
|
28
|
-
continue;
|
|
29
22
|
}
|
|
30
23
|
}
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
// 6. Get the last two moves from our complete list
|
|
34
26
|
const lastMove = moves.length > 0 ? moves[moves.length - 1] : null;
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
const actionStrings = Array(numPlayers).fill('');
|
|
28
|
+
|
|
29
|
+
if (lastMove) {
|
|
30
|
+
if (typeof nextPlayerIndex === 'number' && nextPlayerIndex >= 0) {
|
|
31
|
+
const lastActor = (nextPlayerIndex + numPlayers - 1) % numPlayers;
|
|
32
|
+
actionStrings[lastActor] = lastMove;
|
|
33
|
+
} else {
|
|
34
|
+
const inferredActor = (moves.length - 1) % numPlayers;
|
|
35
|
+
actionStrings[inferredActor] = lastMove;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
37
38
|
|
|
38
39
|
return actionStrings;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
function _parseStepHistoryData(universalPokerJSON) {
|
|
42
|
+
function _parseStepHistoryData(universalPokerJSON, nextPlayerIndex, numPlayers = 2) {
|
|
42
43
|
const result = {
|
|
43
44
|
cards: [],
|
|
44
45
|
communityCards: '',
|
|
45
46
|
bets: [],
|
|
46
|
-
playerActionStrings:
|
|
47
|
+
playerActionStrings: Array(numPlayers).fill(''),
|
|
47
48
|
winOdds: [0, 0],
|
|
48
49
|
};
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
if (!universalPokerJSON) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
51
55
|
const lines = universalPokerJSON.acpc_state.trim().split('\n');
|
|
52
56
|
if (lines.length < 2) {
|
|
53
|
-
console.error("Invalid state string format.");
|
|
54
57
|
return result;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
const stateLine = lines[0];
|
|
58
|
-
const spentLine = lines[1];
|
|
60
|
+
const stateLine = lines[0];
|
|
61
|
+
const spentLine = lines[1];
|
|
59
62
|
|
|
60
|
-
// --- Parse the Spent Line ---
|
|
61
63
|
if (spentLine) {
|
|
62
64
|
const p0BetMatch = spentLine.match(/P0:\s*(\d+)/);
|
|
63
65
|
const p1BetMatch = spentLine.match(/P1:\s*(\d+)/);
|
|
@@ -75,167 +77,334 @@ function _parseStepHistoryData(universalPokerJSON) {
|
|
|
75
77
|
result.bets = bets;
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
// --- Parse the State Line ---
|
|
79
80
|
if (stateLine) {
|
|
80
81
|
const stateParts = stateLine.split(':');
|
|
82
|
+
const cardString = stateParts[stateParts.length - 1];
|
|
83
|
+
const cardSegments = cardString.split('/');
|
|
81
84
|
|
|
82
|
-
// --- Parse Cards ---
|
|
83
|
-
// The card string is always the last part
|
|
84
|
-
const cardString = stateParts[stateParts.length - 1]; // example: "6cKd|AsJc/7hQh6d/2c"
|
|
85
|
-
|
|
86
|
-
// Split card string by '/' to separate hand block from board blocks
|
|
87
|
-
const cardSegments = cardString.split('/'); // example: ["6cKd|AsJc", "7hQh6d", "2c"]
|
|
88
|
-
|
|
89
|
-
// Parse the first segment (player hands)
|
|
90
85
|
if (cardSegments[0]) {
|
|
91
86
|
const playerHands = cardSegments[0].split('|');
|
|
92
87
|
if (playerHands.length >= 2) {
|
|
93
|
-
// example: "6cKd"
|
|
94
88
|
result.cards = [playerHands[0], playerHands[1]];
|
|
95
89
|
}
|
|
96
90
|
}
|
|
97
91
|
|
|
98
|
-
// The rest of the segments are community cards, one per street
|
|
99
92
|
result.communityCards = cardSegments
|
|
100
|
-
.slice(1)
|
|
101
|
-
.filter(Boolean)
|
|
102
|
-
.join('');
|
|
93
|
+
.slice(1)
|
|
94
|
+
.filter(Boolean)
|
|
95
|
+
.join('');
|
|
103
96
|
|
|
104
|
-
// --- Parse Betting String --
|
|
105
|
-
// The betting string is everything between the 2nd colon and the last colon.
|
|
106
|
-
// This handles edge cases like "STATE:0:r5c/cr11c/:cards"
|
|
107
97
|
const bettingString = stateParts.slice(2, stateParts.length - 1).join(':');
|
|
108
|
-
|
|
109
98
|
if (bettingString) {
|
|
110
|
-
result.playerActionStrings = _getActionStringsFromACPC(
|
|
99
|
+
result.playerActionStrings = _getActionStringsFromACPC(
|
|
100
|
+
bettingString,
|
|
101
|
+
nextPlayerIndex,
|
|
102
|
+
numPlayers
|
|
103
|
+
);
|
|
111
104
|
}
|
|
112
105
|
}
|
|
113
106
|
|
|
114
|
-
|
|
115
|
-
const p0WinOdds = Number(
|
|
116
|
-
|
|
107
|
+
const odds = universalPokerJSON.odds || [];
|
|
108
|
+
const p0WinOdds = Number(odds[0] ?? 0).toLocaleString(undefined, {
|
|
109
|
+
style: 'percent',
|
|
110
|
+
minimumFractionDigits: 2
|
|
111
|
+
});
|
|
112
|
+
const p1WinOdds = Number(odds[1] ?? 0).toLocaleString(undefined, {
|
|
113
|
+
style: 'percent',
|
|
114
|
+
minimumFractionDigits: 2
|
|
115
|
+
});
|
|
117
116
|
result.winOdds = [p0WinOdds, p1WinOdds];
|
|
118
117
|
|
|
119
118
|
return result;
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (!environment || !environment.steps || !environment.steps[step] || !environment.info) {
|
|
126
|
-
// return default state
|
|
127
|
-
return null;
|
|
121
|
+
function splitCards(cardString) {
|
|
122
|
+
if (!cardString) {
|
|
123
|
+
return [];
|
|
128
124
|
}
|
|
125
|
+
return cardString.match(/.{1,2}/g) || [];
|
|
126
|
+
}
|
|
129
127
|
|
|
130
|
-
|
|
128
|
+
function isPlaceholderString(cardString) {
|
|
129
|
+
return typeof cardString === 'string' && /^((2c)+)$/i.test(cardString);
|
|
130
|
+
}
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const agentName = environment?.info?.TeamNames?.[i] ||
|
|
136
|
-
`Player ${i}`;
|
|
137
|
-
const thumbnail = environment?.info?.Agents?.[i].ThumbnailUrl;
|
|
138
|
-
return {
|
|
139
|
-
id: `player${i}`,
|
|
140
|
-
name: agentName,
|
|
141
|
-
thumbnail: thumbnail,
|
|
142
|
-
stack: 0,
|
|
143
|
-
cards: [], // Will be filled with nulls or cards
|
|
144
|
-
currentBet: 0,
|
|
145
|
-
isDealer: i === 0,
|
|
146
|
-
isTurn: false,
|
|
147
|
-
reward: null,
|
|
148
|
-
actionDisplayText: ""
|
|
149
|
-
};
|
|
150
|
-
}),
|
|
151
|
-
communityCards: [],
|
|
152
|
-
pot: 0,
|
|
153
|
-
isTerminal: false,
|
|
154
|
-
rawObservation: null, // For debugging
|
|
155
|
-
step: step,
|
|
156
|
-
winOdds: [],
|
|
157
|
-
fiveCardBestHands: [],
|
|
158
|
-
currentPlayer: -1,
|
|
159
|
-
winner: -1,
|
|
160
|
-
};
|
|
132
|
+
function sanitizeCardList(cards) {
|
|
133
|
+
return (cards || []).filter((card) => card);
|
|
134
|
+
}
|
|
161
135
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
136
|
+
function formatActionDisplay(actionString) {
|
|
137
|
+
if (!actionString) {
|
|
138
|
+
return '';
|
|
139
|
+
}
|
|
140
|
+
const playerMatch = actionString.match(/move=([^\s]+)/);
|
|
141
|
+
if (!playerMatch) {
|
|
142
|
+
return '';
|
|
143
|
+
}
|
|
144
|
+
const moveRaw = playerMatch[1];
|
|
145
|
+
const moveLower = moveRaw.toLowerCase();
|
|
146
|
+
if (moveLower.startsWith('bet') || moveLower.startsWith('raise')) {
|
|
147
|
+
const amountMatch = moveRaw.match(/\d+/);
|
|
148
|
+
return amountMatch ? `r${amountMatch[0]}` : 'r';
|
|
149
|
+
}
|
|
150
|
+
if (moveLower === 'call') {
|
|
151
|
+
return 'c';
|
|
152
|
+
}
|
|
153
|
+
if (moveLower === 'check') {
|
|
154
|
+
return 'k';
|
|
155
|
+
}
|
|
156
|
+
if (moveLower === 'fold') {
|
|
157
|
+
return 'f';
|
|
158
|
+
}
|
|
159
|
+
return moveRaw;
|
|
160
|
+
}
|
|
165
161
|
|
|
166
|
-
|
|
162
|
+
function getBlinds(configuration) {
|
|
163
|
+
const blindConfig = configuration?.openSpielGameParameters?.universal_poker_game_string?.blind;
|
|
164
|
+
if (typeof blindConfig !== 'string') {
|
|
165
|
+
return { bigBlind: null, smallBlind: null };
|
|
166
|
+
}
|
|
167
|
+
const parts = blindConfig
|
|
168
|
+
.trim()
|
|
169
|
+
.split(/\s+/)
|
|
170
|
+
.map((entry) => Number(entry))
|
|
171
|
+
.filter((n) => !Number.isNaN(n));
|
|
172
|
+
if (parts.length >= 2) {
|
|
173
|
+
return { bigBlind: parts[0], smallBlind: parts[1] };
|
|
174
|
+
}
|
|
175
|
+
return { bigBlind: null, smallBlind: null };
|
|
176
|
+
}
|
|
167
177
|
|
|
168
|
-
|
|
169
|
-
const
|
|
178
|
+
function getCommunityCardsFromUniversal(universal, numPlayers) {
|
|
179
|
+
const parsed = _parseStepHistoryData(universal, null, numPlayers);
|
|
180
|
+
const cards = splitCards(parsed.communityCards);
|
|
181
|
+
const actual = cards.filter((card) => card && card.toLowerCase() !== PLACEHOLDER_CARD);
|
|
182
|
+
if (actual.length < 3) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
return actual;
|
|
186
|
+
}
|
|
170
187
|
|
|
171
|
-
|
|
188
|
+
function getHandCardsFromUniversal(universal, numPlayers) {
|
|
189
|
+
const parsed = _parseStepHistoryData(universal, null, numPlayers);
|
|
190
|
+
return (parsed.cards || []).map((cardString) => {
|
|
191
|
+
if (isPlaceholderString(cardString)) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
return sanitizeCardList(splitCards(cardString));
|
|
195
|
+
});
|
|
196
|
+
}
|
|
172
197
|
|
|
173
|
-
|
|
198
|
+
function buildTimeline(environment, numPlayers) {
|
|
199
|
+
const stateHistory = environment?.info?.stateHistory || [];
|
|
200
|
+
if (!stateHistory.length) {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
174
203
|
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
return
|
|
204
|
+
const parsedStates = stateHistory.map((entry, idx) => {
|
|
205
|
+
const outer = JSON.parse(entry);
|
|
206
|
+
return {
|
|
207
|
+
idx,
|
|
208
|
+
outer,
|
|
209
|
+
universal: JSON.parse(outer.current_universal_poker_json)
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const hands = [];
|
|
214
|
+
let currentHandNumber = parsedStates[0]?.outer?.hand_number ?? 0;
|
|
215
|
+
let currentStates = [];
|
|
216
|
+
parsedStates.forEach((stateInfo) => {
|
|
217
|
+
const handNumber = stateInfo.outer?.hand_number ?? currentHandNumber;
|
|
218
|
+
if (handNumber !== currentHandNumber) {
|
|
219
|
+
if (currentStates.length) {
|
|
220
|
+
hands.push({ handNumber: currentHandNumber, states: currentStates });
|
|
221
|
+
}
|
|
222
|
+
currentStates = [];
|
|
223
|
+
currentHandNumber = handNumber;
|
|
224
|
+
}
|
|
225
|
+
currentStates.push(stateInfo);
|
|
226
|
+
});
|
|
227
|
+
if (currentStates.length) {
|
|
228
|
+
hands.push({ handNumber: currentHandNumber, states: currentStates });
|
|
178
229
|
}
|
|
179
230
|
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
231
|
+
const processedSteps = environment.__processedSteps || environment.steps || [];
|
|
232
|
+
const actionsByHand = new Map();
|
|
233
|
+
processedSteps.forEach((step) => {
|
|
234
|
+
const handNumber = step?.hand ?? 0;
|
|
235
|
+
if (!actionsByHand.has(handNumber)) {
|
|
236
|
+
actionsByHand.set(handNumber, []);
|
|
237
|
+
}
|
|
238
|
+
if (!step?.isEndState && step?.step?.action && step.step.action.submission !== -1) {
|
|
239
|
+
const actionString = step.step.action.actionString || '';
|
|
240
|
+
const playerMatch = actionString.match(/player=(\d+)/);
|
|
241
|
+
const playerIndex = playerMatch ? parseInt(playerMatch[1], 10) : null;
|
|
242
|
+
actionsByHand.get(handNumber).push({
|
|
243
|
+
playerIndex,
|
|
244
|
+
actionText: formatActionDisplay(actionString),
|
|
245
|
+
stateHistoryIndex: step.stateHistoryIndex
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const events = [];
|
|
251
|
+
let orderCounter = 0;
|
|
252
|
+
const pushEvent = (stateIndex, event) => {
|
|
253
|
+
events.push({
|
|
254
|
+
order: orderCounter++,
|
|
255
|
+
stateIndex,
|
|
256
|
+
highlightPlayer: event.highlightPlayer,
|
|
257
|
+
actionText: event.actionText,
|
|
258
|
+
hideHoleCards: event.hideHoleCards,
|
|
259
|
+
hideCommunity: event.hideCommunity
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
hands.forEach(({ handNumber, states }) => {
|
|
264
|
+
if (!states.length) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
188
267
|
|
|
189
|
-
|
|
268
|
+
const firstState = states[0];
|
|
269
|
+
const dealer = firstState.outer?.dealer ?? 0;
|
|
270
|
+
const { bigBlind, smallBlind } = getBlinds(environment.configuration);
|
|
271
|
+
const smallBlindPlayer = dealer % numPlayers;
|
|
272
|
+
const bigBlindPlayer = (dealer + 1) % numPlayers;
|
|
273
|
+
|
|
274
|
+
pushEvent(firstState.idx, { highlightPlayer: null, actionText: '', hideHoleCards: true, hideCommunity: true });
|
|
275
|
+
pushEvent(firstState.idx, { highlightPlayer: smallBlindPlayer, actionText: smallBlind != null ? `SB ${smallBlind}` : 'SB', hideHoleCards: true, hideCommunity: true });
|
|
276
|
+
pushEvent(firstState.idx, { highlightPlayer: bigBlindPlayer, actionText: bigBlind != null ? `BB ${bigBlind}` : 'BB', hideHoleCards: true, hideCommunity: true });
|
|
277
|
+
|
|
278
|
+
const firstActionState = states.find((stateInfo) => stateInfo.universal.current_player !== -1) || firstState;
|
|
279
|
+
pushEvent(firstActionState.idx, { highlightPlayer: null, actionText: '', hideHoleCards: false, hideCommunity: true });
|
|
280
|
+
|
|
281
|
+
const actions = actionsByHand.get(handNumber) || [];
|
|
282
|
+
actions.forEach((action) => {
|
|
283
|
+
const targetIndex = typeof action.stateHistoryIndex === 'number' ? action.stateHistoryIndex : states[0].idx;
|
|
284
|
+
const postState = states.find((stateInfo) => stateInfo.idx > targetIndex) || states[states.length - 1];
|
|
285
|
+
pushEvent(postState.idx, {
|
|
286
|
+
highlightPlayer: action.playerIndex,
|
|
287
|
+
actionText: action.actionText,
|
|
288
|
+
hideHoleCards: false,
|
|
289
|
+
hideCommunity: false
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
let currentStageCommunityLength = 0;
|
|
294
|
+
states.forEach((stateInfo) => {
|
|
295
|
+
const communityCards = getCommunityCardsFromUniversal(stateInfo.universal, numPlayers);
|
|
296
|
+
const communityLength = communityCards.length;
|
|
297
|
+
if (communityLength > currentStageCommunityLength) {
|
|
298
|
+
currentStageCommunityLength = communityLength;
|
|
299
|
+
if (communityLength === 3 || communityLength === 4 || communityLength === 5) {
|
|
300
|
+
pushEvent(stateInfo.idx, {
|
|
301
|
+
highlightPlayer: null,
|
|
302
|
+
actionText: '',
|
|
303
|
+
hideHoleCards: false,
|
|
304
|
+
hideCommunity: false
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
events.sort((a, b) => a.order - b.order);
|
|
312
|
+
return events.map(({ stateIndex, highlightPlayer, actionText, hideHoleCards, hideCommunity }) => ({
|
|
313
|
+
stateIndex,
|
|
314
|
+
highlightPlayer,
|
|
315
|
+
actionText,
|
|
316
|
+
hideHoleCards: !!hideHoleCards,
|
|
317
|
+
hideCommunity: !!hideCommunity
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
190
320
|
|
|
191
|
-
|
|
321
|
+
function getTimeline(environment, numPlayers) {
|
|
322
|
+
if (!environment.__timeline) {
|
|
323
|
+
environment.__timeline = buildTimeline(environment, numPlayers);
|
|
324
|
+
}
|
|
325
|
+
return environment.__timeline;
|
|
326
|
+
}
|
|
192
327
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
328
|
+
function getUniversalState(environment, index) {
|
|
329
|
+
const entry = environment?.info?.stateHistory?.[index];
|
|
330
|
+
if (!entry) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
const outer = JSON.parse(entry);
|
|
334
|
+
return {
|
|
335
|
+
outer,
|
|
336
|
+
universal: JSON.parse(outer.current_universal_poker_json)
|
|
337
|
+
};
|
|
338
|
+
}
|
|
197
339
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
340
|
+
export const getPokerStateForStep = (environment, step) => {
|
|
341
|
+
const numPlayers = 2;
|
|
342
|
+
if (!environment || !environment.info?.stateHistory) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
203
345
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
346
|
+
const timeline = getTimeline(environment, numPlayers);
|
|
347
|
+
const event = timeline[step];
|
|
348
|
+
if (!event) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
const stateInfo = getUniversalState(environment, event.stateIndex);
|
|
352
|
+
if (!stateInfo) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
210
355
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
356
|
+
const parsedStateHistory = _parseStepHistoryData(
|
|
357
|
+
stateInfo.universal,
|
|
358
|
+
stateInfo.universal?.current_player,
|
|
359
|
+
numPlayers
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const startingStacks = stateInfo.universal?.starting_stacks || Array(numPlayers).fill(0);
|
|
363
|
+
const contributions = stateInfo.universal?.player_contributions || parsedStateHistory.bets || Array(numPlayers).fill(0);
|
|
364
|
+
const rewards = stateInfo.outer?.hand_returns || [];
|
|
365
|
+
const communityCards = getCommunityCardsFromUniversal(stateInfo.universal, numPlayers);
|
|
366
|
+
|
|
367
|
+
const players = Array(numPlayers)
|
|
368
|
+
.fill(null)
|
|
369
|
+
.map((_, i) => {
|
|
370
|
+
const agentName = environment?.info?.TeamNames?.[i] || `Player ${i}`;
|
|
371
|
+
const thumbnail = environment?.info?.Agents?.[i]?.ThumbnailUrl;
|
|
372
|
+
return {
|
|
373
|
+
id: `player${i}`,
|
|
374
|
+
name: agentName,
|
|
375
|
+
thumbnail,
|
|
376
|
+
stack: startingStacks[i] - (contributions[i] || 0),
|
|
377
|
+
cards: [],
|
|
378
|
+
currentBet: contributions[i] || 0,
|
|
379
|
+
isDealer: stateInfo.outer?.dealer === i,
|
|
380
|
+
isTurn: stateInfo.universal?.current_player === i,
|
|
381
|
+
isLastActor: event.highlightPlayer === i,
|
|
382
|
+
reward: rewards[0]?.[i] ?? null,
|
|
383
|
+
actionDisplayText: event.highlightPlayer === i ? event.actionText : ''
|
|
384
|
+
};
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const handCards = getHandCardsFromUniversal(stateInfo.universal, numPlayers);
|
|
388
|
+
players.forEach((player, index) => {
|
|
389
|
+
if (event.hideHoleCards) {
|
|
390
|
+
player.cards = [];
|
|
391
|
+
} else {
|
|
392
|
+
player.cards = handCards[index] || [];
|
|
223
393
|
}
|
|
394
|
+
});
|
|
224
395
|
|
|
225
|
-
|
|
226
|
-
const reward = environment.rewards ? environment.rewards[i] : null;
|
|
227
|
-
pData.reward = reward;
|
|
228
|
-
if (reward > 0) {
|
|
229
|
-
pData.name = `${pData.name} wins 🎉`;
|
|
230
|
-
pData.isWinner = true;
|
|
231
|
-
pData.status = null;
|
|
232
|
-
} else {
|
|
233
|
-
pData.status = null;
|
|
234
|
-
}
|
|
235
|
-
} else if (pData.stack === 0 && pData.currentBet > 0) {
|
|
236
|
-
pData.status = "All-in";
|
|
237
|
-
}
|
|
238
|
-
}
|
|
396
|
+
const displayCommunity = event.hideCommunity ? [] : communityCards;
|
|
239
397
|
|
|
240
|
-
return
|
|
241
|
-
|
|
398
|
+
return {
|
|
399
|
+
players,
|
|
400
|
+
communityCards: displayCommunity,
|
|
401
|
+
pot: contributions.reduce((sum, value) => sum + (value || 0), 0),
|
|
402
|
+
isTerminal: false,
|
|
403
|
+
rawObservation: stateInfo.universal,
|
|
404
|
+
step,
|
|
405
|
+
winOdds: parsedStateHistory.winOdds,
|
|
406
|
+
fiveCardBestHands: [],
|
|
407
|
+
currentPlayer: stateInfo.universal?.current_player ?? -1,
|
|
408
|
+
winner: -1
|
|
409
|
+
};
|
|
410
|
+
};
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { Player, GameAdapter, ReplayData } from
|
|
2
|
-
import { renderer } from
|
|
3
|
-
import { render } from
|
|
1
|
+
import { Player, GameAdapter, ReplayData } from "@kaggle-environments/core";
|
|
2
|
+
import { renderer } from "./repeated_poker_renderer.js";
|
|
3
|
+
import { render } from "preact";
|
|
4
4
|
|
|
5
5
|
class LegacyAdapter implements GameAdapter {
|
|
6
|
-
|
|
6
|
+
private container: HTMLElement | null = null;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
mount(container: HTMLElement): void {
|
|
9
|
+
this.container = container;
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
render(step: number, replay: ReplayData, agents: any[]): void {
|
|
13
|
+
if (!this.container) return;
|
|
14
|
+
this.container.innerHTML = ""; // Clear container before rendering
|
|
15
|
+
renderer({
|
|
16
|
+
parent: this.container,
|
|
17
|
+
environment: replay,
|
|
18
|
+
step: step,
|
|
19
|
+
agents: agents,
|
|
20
|
+
// These are probably not used by poker but good to have
|
|
21
|
+
width: this.container.clientWidth,
|
|
22
|
+
height: this.container.clientHeight,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
this.container = null;
|
|
26
|
+
unmount(): void {
|
|
27
|
+
if (this.container) {
|
|
28
|
+
render(null, this.container);
|
|
31
29
|
}
|
|
30
|
+
this.container = null;
|
|
31
|
+
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const app = document.getElementById(
|
|
34
|
+
const app = document.getElementById("app");
|
|
35
35
|
if (app) {
|
|
36
|
-
|
|
36
|
+
new Player(app, new LegacyAdapter());
|
|
37
37
|
}
|
|
@@ -525,7 +525,6 @@ export function renderer(options) {
|
|
|
525
525
|
// --- State Parsing ---
|
|
526
526
|
function _parseKagglePokerState(options) {
|
|
527
527
|
const { environment, step } = options;
|
|
528
|
-
const numPlayers = 2;
|
|
529
528
|
|
|
530
529
|
// --- Default State ---
|
|
531
530
|
const defaultStateUiData = {
|
|
@@ -536,7 +535,7 @@ export function renderer(options) {
|
|
|
536
535
|
};
|
|
537
536
|
|
|
538
537
|
// --- Step Validation ---
|
|
539
|
-
if (!environment || !
|
|
538
|
+
if (!environment || !step) {
|
|
540
539
|
return defaultStateUiData;
|
|
541
540
|
}
|
|
542
541
|
|
|
@@ -559,7 +558,7 @@ export function renderer(options) {
|
|
|
559
558
|
elements.gameLayout.style.transform = `scale(${scale})`;
|
|
560
559
|
}
|
|
561
560
|
|
|
562
|
-
function _renderPokerTableUI(data
|
|
561
|
+
function _renderPokerTableUI(data) {
|
|
563
562
|
if (!elements.pokerTable || !data) return;
|
|
564
563
|
const { players, communityCards, pot, isTerminal, step } = data;
|
|
565
564
|
|
|
@@ -603,8 +602,8 @@ export function renderer(options) {
|
|
|
603
602
|
if (playerNameElement) {
|
|
604
603
|
playerNameElement.textContent = playerData.name;
|
|
605
604
|
|
|
606
|
-
// Highlight
|
|
607
|
-
if (playerData.
|
|
605
|
+
// Highlight the player who took the most recent action
|
|
606
|
+
if (playerData.isLastActor) {
|
|
608
607
|
playerNameElement.classList.add('current-turn');
|
|
609
608
|
} else {
|
|
610
609
|
playerNameElement.classList.remove('current-turn');
|
|
@@ -650,7 +649,7 @@ export function renderer(options) {
|
|
|
650
649
|
const playerInfoArea = elements.playerInfoAreas[index];
|
|
651
650
|
if (playerInfoArea) {
|
|
652
651
|
// Highlight active player's pod
|
|
653
|
-
if (playerData.
|
|
652
|
+
if (playerData.isLastActor) {
|
|
654
653
|
playerInfoArea.classList.add('active-player');
|
|
655
654
|
} else {
|
|
656
655
|
playerInfoArea.classList.remove('active-player');
|
|
@@ -194,9 +194,9 @@ kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/
|
|
|
194
194
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/tsconfig.json,sha256=3X9dsQOgFw_cZ_uXByZIsGrQ5jhFfAZZL7QC6ApJWak,133
|
|
195
195
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/vite.config.ts,sha256=KhIjUn0WWhaoQzQ5YKuWjNndimRF0kFlYDgEnZ0cg7U,208
|
|
196
196
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/replays/test-replay.json,sha256=jf4ilR6SmOYPNohkIGJvmKP5Gju5FY6sfSStX1qtFZg,28919900
|
|
197
|
-
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/main.ts,sha256=
|
|
198
|
-
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/repeated_poker_renderer.js,sha256=
|
|
199
|
-
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/components/getRepeatedPokerStateForStep.js,sha256=
|
|
197
|
+
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/main.ts,sha256=Its2m61qv7RHlHUzIW6JkmySaHWq1h2bJ5sWY9woots,1000
|
|
198
|
+
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/repeated_poker_renderer.js,sha256=rEAJf5I7GKyot9H8BqyatneWvzKJFUfl7G9_hNPHA5Y,26482
|
|
199
|
+
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/components/getRepeatedPokerStateForStep.js,sha256=6nTmNT2iD2wpc0li2RU-URHM8jlKd4MRJDsVMLRcMI8,12490
|
|
200
200
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/components/utils.js,sha256=pXDAu4V2OppRCvMdJKQ56q1uFTJReMPIvBL6gwxIJoI,5734
|
|
201
201
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/images/poker_chip_1.svg,sha256=v9yCvpnaQAg8OSUJdJ5PhuTHm9_zXnww-9_7oR_DJpc,22160
|
|
202
202
|
kaggle_environments/envs/open_spiel_env/games/repeated_poker/visualizer/default/src/images/poker_chip_10.svg,sha256=z3CP2h5eUGlgBdqNoWGcioekAyPgiuzhyRNr-nbutOE,22160
|
|
@@ -279,8 +279,8 @@ kaggle_environments/envs/werewolf/scripts/configs/run/rule_experiment/standard_p
|
|
|
279
279
|
kaggle_environments/envs/werewolf/scripts/configs/run/rule_experiment/standard_parallel_voting_no_tie_exile.yaml,sha256=sfSFlFU4F7doZ-wXUWBl-JgJtmpjrLR-SpCAqKnUYeQ,3662
|
|
280
280
|
kaggle_environments/envs/werewolf/scripts/configs/run/rule_experiment/standard_parallel_voting_roundbiddiscussion.yaml,sha256=UGSLfOhmC-4pRqWsJvOtZRU0YLUuOMAGeEHtxTf3wf8,3710
|
|
281
281
|
kaggle_environments/static/player.html,sha256=Icl5yYscPe4BRoWt0HLOSRJWnznQq2MdTHHCaC2OrQQ,27753
|
|
282
|
-
kaggle_environments-1.23.
|
|
283
|
-
kaggle_environments-1.23.
|
|
284
|
-
kaggle_environments-1.23.
|
|
285
|
-
kaggle_environments-1.23.
|
|
286
|
-
kaggle_environments-1.23.
|
|
282
|
+
kaggle_environments-1.23.6.dist-info/entry_points.txt,sha256=h03sq76TdcHvXKcsre1Qm3lIni9dkWehu61xJqI-p8k,69
|
|
283
|
+
kaggle_environments-1.23.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
284
|
+
kaggle_environments-1.23.6.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
285
|
+
kaggle_environments-1.23.6.dist-info/METADATA,sha256=EQ9xVZR7e9fuaBqASk1B3rEJwOTii36QXXSU198jlLA,916
|
|
286
|
+
kaggle_environments-1.23.6.dist-info/RECORD,,
|
|
File without changes
|
{kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{kaggle_environments-1.23.5.dist-info → kaggle_environments-1.23.6.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|