kaggle-environments 1.17.9__py2.py3-none-any.whl → 1.17.11__py2.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.

@@ -20,7 +20,7 @@ from .core import *
20
20
  from .main import http_request
21
21
  from . import errors
22
22
 
23
- __version__ = "1.17.9"
23
+ __version__ = "1.17.11"
24
24
 
25
25
  __all__ = ["Agent", "environments", "errors", "evaluate", "http_request",
26
26
  "make", "register", "utils", "__version__",
@@ -174,8 +174,8 @@ class Agent:
174
174
  out = out_buffer.getvalue()
175
175
  err = err_buffer.getvalue()
176
176
  # Get the maximum log length
177
- # Allow up to 1k (default) log characters per step which is ~1MB per 600 step episode
178
- max_log_length = self.configuration.get('maxLogLength', 1024)
177
+ # Allow up to 10k (default) log characters per step which is ~10MB per 600 step episode
178
+ max_log_length = self.configuration.get('maxLogLength', 10000)
179
179
 
180
180
  # truncate if max_log_length is set to None, do not truncate
181
181
  if max_log_length is not None:
@@ -608,8 +608,8 @@ class Environment:
608
608
  err = err_buffer.getvalue()
609
609
 
610
610
  # strip if needed
611
- # Allow up to 1k (default) log characters per step which is ~1MB per 600 step episode
612
- max_log_length = self.configuration.get("maxLogLength", 1024)
611
+ # Allow up to 10k (default) log characters per step which is ~10MB per 600 step episode
612
+ max_log_length = self.configuration.get("maxLogLength", 10000)
613
613
  if max_log_length is not None:
614
614
  out = out[0:max_log_length]
615
615
  err = err[0:max_log_length]
@@ -1,41 +1,39 @@
1
1
  function renderer(options) {
2
- const { environment, step, parent } = options;
2
+ const { environment, step, parent, width = 400, height = 400 } = options; // Chess-specific constants
3
3
 
4
- // Chess-specific constants
5
4
  const DEFAULT_NUM_ROWS = 8;
6
5
  const DEFAULT_NUM_COLS = 8;
7
6
  const PIECE_SVG_URLS = {
8
- 'p': 'https://upload.wikimedia.org/wikipedia/commons/c/c7/Chess_pdt45.svg', // Black Pawn
9
- 'r': 'https://upload.wikimedia.org/wikipedia/commons/f/ff/Chess_rdt45.svg', // Black Rook
10
- 'n': 'https://upload.wikimedia.org/wikipedia/commons/e/ef/Chess_ndt45.svg', // Black Knight
11
- 'b': 'https://upload.wikimedia.org/wikipedia/commons/9/98/Chess_bdt45.svg', // Black Bishop
12
- 'q': 'https://upload.wikimedia.org/wikipedia/commons/4/47/Chess_qdt45.svg', // Black Queen
13
- 'k': 'https://upload.wikimedia.org/wikipedia/commons/f/f0/Chess_kdt45.svg', // Black King
14
- 'P': 'https://upload.wikimedia.org/wikipedia/commons/4/45/Chess_plt45.svg', // White Pawn
15
- 'R': 'https://upload.wikimedia.org/wikipedia/commons/7/72/Chess_rlt45.svg', // White Rook
16
- 'N': 'https://upload.wikimedia.org/wikipedia/commons/7/70/Chess_nlt45.svg', // White Knight
17
- 'B': 'https://upload.wikimedia.org/wikipedia/commons/b/b1/Chess_blt45.svg', // White Bishop
18
- 'Q': 'https://upload.wikimedia.org/wikipedia/commons/1/15/Chess_qlt45.svg', // White Queen
19
- 'K': 'https://upload.wikimedia.org/wikipedia/commons/4/42/Chess_klt45.svg' // White King
7
+ p: 'https://upload.wikimedia.org/wikipedia/commons/c/c7/Chess_pdt45.svg', // Black Pawn
8
+ r: 'https://upload.wikimedia.org/wikipedia/commons/f/ff/Chess_rdt45.svg', // Black Rook
9
+ n: 'https://upload.wikimedia.org/wikipedia/commons/e/ef/Chess_ndt45.svg', // Black Knight
10
+ b: 'https://upload.wikimedia.org/wikipedia/commons/9/98/Chess_bdt45.svg', // Black Bishop
11
+ q: 'https://upload.wikimedia.org/wikipedia/commons/4/47/Chess_qdt45.svg', // Black Queen
12
+ k: 'https://upload.wikimedia.org/wikipedia/commons/f/f0/Chess_kdt45.svg', // Black King
13
+ P: 'https://upload.wikimedia.org/wikipedia/commons/4/45/Chess_plt45.svg', // White Pawn
14
+ R: 'https://upload.wikimedia.org/wikipedia/commons/7/72/Chess_rlt45.svg', // White Rook
15
+ N: 'https://upload.wikimedia.org/wikipedia/commons/7/70/Chess_nlt45.svg', // White Knight
16
+ B: 'https://upload.wikimedia.org/wikipedia/commons/b/b1/Chess_blt45.svg', // White Bishop
17
+ Q: 'https://upload.wikimedia.org/wikipedia/commons/1/15/Chess_qlt45.svg', // White Queen
18
+ K: 'https://upload.wikimedia.org/wikipedia/commons/4/42/Chess_klt45.svg' // White King
20
19
  };
21
20
  const LIGHT_SQUARE_COLOR = '#f0d9b5';
22
21
  const DARK_SQUARE_COLOR = '#b58863';
23
22
 
24
- // Renderer state variables
25
23
  let currentBoardElement = null;
26
24
  let currentStatusTextElement = null;
27
25
  let currentWinnerTextElement = null;
28
26
  let currentMessageBoxElement = typeof document !== 'undefined' ? document.getElementById('messageBox') : null;
29
27
  let currentRendererContainer = null;
28
+ let currentBoardContainer = null;
30
29
  let currentTitleElement = null;
31
- let squareSize = 50;
30
+ let squareSize = 0;
32
31
 
33
32
  function _showMessage(message, type = 'info', duration = 3000) {
34
33
  if (typeof document === 'undefined' || !document.body) return;
35
34
  if (!currentMessageBoxElement) {
36
35
  currentMessageBoxElement = document.createElement('div');
37
36
  currentMessageBoxElement.id = 'messageBox';
38
- // Identical styling to the Connect Four renderer's message box
39
37
  Object.assign(currentMessageBoxElement.style, {
40
38
  position: 'fixed',
41
39
  top: '10px',
@@ -56,71 +54,148 @@ function renderer(options) {
56
54
  currentMessageBoxElement.textContent = message;
57
55
  currentMessageBoxElement.style.backgroundColor = type === 'error' ? '#ef4444' : '#10b981';
58
56
  currentMessageBoxElement.style.opacity = '1';
59
- setTimeout(() => { if (currentMessageBoxElement) currentMessageBoxElement.style.opacity = '0'; }, duration);
57
+ setTimeout(() => {
58
+ if (currentMessageBoxElement) currentMessageBoxElement.style.opacity = '0';
59
+ }, duration);
60
60
  }
61
-
62
61
  function _ensureRendererElements(parentElementToClear, rows, cols) {
63
62
  if (!parentElementToClear) return false;
64
63
  parentElementToClear.innerHTML = '';
65
64
 
65
+ // NEW: Check for mobile screen size to apply responsive styles.
66
+ const isMobile = window.innerWidth < 768;
67
+
66
68
  currentRendererContainer = document.createElement('div');
67
69
  Object.assign(currentRendererContainer.style, {
68
70
  display: 'flex',
69
71
  flexDirection: 'column',
70
72
  alignItems: 'center',
71
- padding: '20px',
73
+ padding: isMobile ? '10px' : '20px', // Responsive padding
72
74
  boxSizing: 'border-box',
73
75
  width: '100%',
74
76
  height: '100%',
75
77
  fontFamily: "'Inter', sans-serif"
76
78
  });
79
+ parentElementToClear.appendChild(currentRendererContainer);
77
80
 
78
81
  if (!environment.viewer) {
79
- currentTitleElement = document.createElement('h1');
80
- currentTitleElement.textContent = 'Chess';
81
- // Identical styling to the Connect Four renderer's title
82
- Object.assign(currentTitleElement.style, {
83
- fontSize: '1.875rem',
84
- fontWeight: 'bold',
85
- marginBottom: '1rem',
86
- textAlign: 'center',
87
- color: '#2563eb'
88
- });
89
- currentRendererContainer.appendChild(currentTitleElement);
82
+ const headerContainer = document.createElement('div');
83
+ Object.assign(headerContainer.style, {
84
+ display: 'flex',
85
+ justifyContent: 'center',
86
+ alignItems: 'center',
87
+ width: '100%',
88
+ marginBottom: '1rem',
89
+ color: 'white',
90
+ flexShrink: '0',
91
+ flexDirection: isMobile ? 'column' : 'row' // Stacks header vertically on mobile
92
+ });
93
+
94
+ // Player 2 (White) - Left side
95
+ const whitePlayerContainer = document.createElement('div');
96
+ Object.assign(whitePlayerContainer.style, {
97
+ display: 'flex',
98
+ alignItems: 'center'
99
+ });
100
+ const whitePawnImg = document.createElement('img');
101
+ whitePawnImg.src = PIECE_SVG_URLS.P;
102
+ Object.assign(whitePawnImg.style, { height: '30px', marginRight: '8px' });
103
+ const whitePlayerName = document.createElement('span');
104
+ whitePlayerName.textContent = environment.info?.TeamNames?.[1] || 'Player 2';
105
+ Object.assign(whitePlayerName.style, {
106
+ fontSize: isMobile ? '1rem' : '1.1rem', // Responsive font size
107
+ fontWeight: 'bold'
108
+ });
109
+ whitePlayerContainer.appendChild(whitePawnImg);
110
+ whitePlayerContainer.appendChild(whitePlayerName);
111
+
112
+ // Center Title
113
+ currentTitleElement = document.createElement('h1');
114
+ currentTitleElement.textContent = 'Chess';
115
+ Object.assign(currentTitleElement.style, {
116
+ fontSize: isMobile ? '1.5rem' : '1.875rem', // Responsive font size
117
+ fontWeight: 'bold',
118
+ textAlign: 'center',
119
+ color: '#e5e7eb',
120
+ margin: isMobile ? '10px 0' : '0 40px', // Responsive margin
121
+ order: isMobile ? '0' : 'initial' // Ensures title is between players on desktop
122
+ });
123
+
124
+ // Player 1 (Black) - Right side
125
+ const blackPlayerContainer = document.createElement('div');
126
+ Object.assign(blackPlayerContainer.style, {
127
+ display: 'flex',
128
+ alignItems: 'center'
129
+ });
130
+ const blackPlayerName = document.createElement('span');
131
+ blackPlayerName.textContent = environment.info?.TeamNames?.[0] || 'Player 1';
132
+ Object.assign(blackPlayerName.style, {
133
+ fontSize: isMobile ? '1rem' : '1.1rem', // Responsive font size
134
+ fontWeight: 'bold'
135
+ });
136
+ const blackPawnImg = document.createElement('img');
137
+ blackPawnImg.src = PIECE_SVG_URLS.p;
138
+ Object.assign(blackPawnImg.style, { height: '30px', marginLeft: '8px' });
139
+ blackPlayerContainer.appendChild(blackPlayerName);
140
+ blackPlayerContainer.appendChild(blackPawnImg);
141
+
142
+ // Assemble the header - order matters for mobile stacking
143
+ if (isMobile) {
144
+ // On mobile: White Player, then Black Player, then Title for a "vs" feel
145
+ headerContainer.appendChild(whitePlayerContainer);
146
+ const vsText = document.createElement('div');
147
+ vsText.textContent = 'vs';
148
+ Object.assign(vsText.style, { margin: '4px 0', fontStyle: 'italic' });
149
+ headerContainer.appendChild(vsText);
150
+ headerContainer.appendChild(blackPlayerContainer);
151
+ // Title is not added here for mobile to keep it separate or could be added last
152
+ } else {
153
+ // On desktop: White Player, Title, Black Player
154
+ headerContainer.appendChild(whitePlayerContainer);
155
+ headerContainer.appendChild(currentTitleElement);
156
+ headerContainer.appendChild(blackPlayerContainer);
157
+ }
158
+ currentRendererContainer.appendChild(headerContainer);
90
159
  }
91
- parentElementToClear.appendChild(currentRendererContainer);
92
160
 
93
- const smallestParentEdge = Math.min(currentRendererContainer.offsetWidth, currentRendererContainer.offsetHeight);
94
- squareSize = Math.floor(smallestParentEdge / DEFAULT_NUM_COLS);
161
+ // ... (The rest of the function for the board and status container remains the same, but let's add responsive fonts to the status)
162
+
163
+ // Board container...
164
+ currentBoardContainer = document.createElement('div');
165
+ Object.assign(currentBoardContainer.style, {
166
+ display: 'flex',
167
+ justifyContent: 'center',
168
+ alignItems: 'center',
169
+ flexGrow: '1',
170
+ overflow: 'hidden',
171
+ width: '100%',
172
+ minHeight: '0'
173
+ });
174
+ currentRendererContainer.appendChild(currentBoardContainer);
175
+
176
+ // ... code to create board and squares ...
95
177
  currentBoardElement = document.createElement('div');
96
178
  Object.assign(currentBoardElement.style, {
97
179
  display: 'grid',
98
- gridTemplateColumns: `repeat(${cols}, ${squareSize}px)`,
99
- gridTemplateRows: `repeat(${rows}, ${squareSize}px)`,
100
- width: `${cols * squareSize}px`,
101
- height: `${rows * squareSize}px`,
102
180
  border: '2px solid #333'
103
181
  });
104
-
182
+ currentBoardContainer.appendChild(currentBoardElement);
105
183
  for (let r = 0; r < rows; r++) {
106
184
  for (let c = 0; c < cols; c++) {
107
185
  const square = document.createElement('div');
108
186
  square.id = `cell-${r}-${c}`;
109
187
  Object.assign(square.style, {
110
- width: `${squareSize}px`,
111
- height: `${squareSize}px`,
112
188
  backgroundColor: (r + c) % 2 === 0 ? LIGHT_SQUARE_COLOR : DARK_SQUARE_COLOR,
113
189
  display: 'flex',
114
190
  alignItems: 'center',
115
- justifyContent: 'center',
191
+ justifyContent: 'center'
116
192
  });
117
193
  currentBoardElement.appendChild(square);
118
194
  }
119
195
  }
120
- currentRendererContainer.appendChild(currentBoardElement);
121
196
 
197
+ // Status Container
122
198
  const statusContainer = document.createElement('div');
123
- // Identical styling to the Connect Four renderer's status container
124
199
  Object.assign(statusContainer.style, {
125
200
  padding: '10px 15px',
126
201
  backgroundColor: 'white',
@@ -130,15 +205,16 @@ function renderer(options) {
130
205
  width: 'auto',
131
206
  minWidth: '200px',
132
207
  maxWidth: '90vw',
133
- marginTop: '20px'
208
+ marginTop: '20px',
209
+ flexShrink: '0'
134
210
  });
135
211
  if (!environment.viewer) {
136
- currentRendererContainer.appendChild(statusContainer);
212
+ currentRendererContainer.appendChild(statusContainer);
137
213
  }
138
214
 
139
215
  currentStatusTextElement = document.createElement('p');
140
216
  Object.assign(currentStatusTextElement.style, {
141
- fontSize: '1.1rem',
217
+ fontSize: isMobile ? '0.9rem' : '1.1rem', // Responsive font size
142
218
  fontWeight: '600',
143
219
  margin: '0 0 5px 0'
144
220
  });
@@ -146,18 +222,41 @@ function renderer(options) {
146
222
 
147
223
  currentWinnerTextElement = document.createElement('p');
148
224
  Object.assign(currentWinnerTextElement.style, {
149
- fontSize: '1.25rem',
225
+ fontSize: isMobile ? '1rem' : '1.25rem', // Responsive font size
150
226
  fontWeight: '700',
151
227
  margin: '5px 0 0 0'
152
228
  });
153
229
  statusContainer.appendChild(currentWinnerTextElement);
154
230
 
155
- if (typeof document !== 'undefined' && !document.body.hasAttribute('data-renderer-initialized')) {
156
- document.body.setAttribute('data-renderer-initialized', 'true');
157
- }
158
231
  return true;
159
232
  }
160
233
 
234
+ function _getTeamNameForColor(color, teamNames) {
235
+ if (!teamNames || teamNames.length < 2) return null;
236
+ return color.toLowerCase() === 'white' ? teamNames[1] : teamNames[0];
237
+ }
238
+
239
+ function _deriveWinnerFromRewards(currentStepAgents, teamNames) {
240
+ if (!currentStepAgents || currentStepAgents.length < 2) return null;
241
+
242
+ const player0Reward = currentStepAgents[0].reward;
243
+ const player1Reward = currentStepAgents[1].reward;
244
+
245
+ if (player0Reward === player1Reward) {
246
+ return 'draw';
247
+ }
248
+
249
+ const winnerPlayerIndex = player0Reward === 1 ? 0 : 1;
250
+ const color = winnerPlayerIndex === 0 ? 'Black' : 'White';
251
+
252
+ if (teamNames) {
253
+ const teamName = _getTeamNameForColor(color, teamNames);
254
+ return `${color} (${teamName})`;
255
+ }
256
+
257
+ return color.toLowerCase();
258
+ }
259
+
161
260
  function _parseFen(fen) {
162
261
  if (!fen || typeof fen !== 'string') return null;
163
262
 
@@ -189,29 +288,51 @@ function renderer(options) {
189
288
  };
190
289
  }
191
290
 
192
-
193
291
  function _renderBoardDisplay(gameStateToDisplay, displayRows, displayCols) {
194
- if (!currentBoardElement || !currentStatusTextElement || !currentWinnerTextElement) return;
292
+ if (!currentBoardContainer || !currentBoardElement || !currentStatusTextElement || !currentWinnerTextElement)
293
+ return;
294
+
295
+ const isMobile = window.innerWidth < 768;
296
+
297
+ // Calculate and apply board size
298
+ const containerWidth = currentBoardContainer?.clientWidth ?? width;
299
+ const containerHeight = currentBoardContainer?.clientHeight ?? height;
300
+ const smallestContainerEdge = Math.min(containerWidth, containerHeight);
301
+ const newSquareSize = Math.floor(smallestContainerEdge / displayCols);
302
+
303
+ if (newSquareSize !== squareSize) {
304
+ squareSize = newSquareSize;
305
+ Object.assign(currentBoardElement.style, {
306
+ gridTemplateColumns: `repeat(${displayCols}, ${squareSize}px)`,
307
+ gridTemplateRows: `repeat(${displayRows}, ${squareSize}px)`,
308
+ width: `${displayCols * squareSize}px`,
309
+ height: `${displayRows * squareSize}px`
310
+ });
195
311
 
196
- // Clear board
312
+ const squares = currentBoardElement.querySelectorAll('div[id^="cell-"]');
313
+ squares.forEach((square) => {
314
+ Object.assign(square.style, {
315
+ width: `${squareSize}px`,
316
+ height: `${squareSize}px`
317
+ });
318
+ });
319
+ }
320
+
321
+ // Clear and render board pieces...
197
322
  for (let r = 0; r < displayRows; r++) {
198
323
  for (let c = 0; c < displayCols; c++) {
199
324
  const squareElement = currentBoardElement.querySelector(`#cell-${r}-${c}`);
200
- if (squareElement) {
201
- squareElement.innerHTML = '';
202
- }
325
+ if (squareElement) squareElement.innerHTML = '';
203
326
  }
204
327
  }
205
-
328
+
206
329
  if (!gameStateToDisplay || !gameStateToDisplay.board) {
207
- currentStatusTextElement.textContent = "Waiting for game data...";
208
- currentWinnerTextElement.textContent = "";
330
+ currentStatusTextElement.textContent = 'Waiting for game data...';
331
+ currentWinnerTextElement.textContent = '';
209
332
  return;
210
333
  }
211
334
 
212
-
213
335
  const { board, activeColor, isTerminal, winner } = gameStateToDisplay;
214
-
215
336
  const pieceSize = Math.floor(squareSize * 0.9);
216
337
  for (let r_data = 0; r_data < displayRows; r_data++) {
217
338
  for (let c_data = 0; c_data < displayCols; c_data++) {
@@ -227,73 +348,89 @@ function renderer(options) {
227
348
  }
228
349
  }
229
350
 
351
+ // Render status text
230
352
  currentStatusTextElement.innerHTML = '';
231
353
  currentWinnerTextElement.innerHTML = '';
232
354
  if (isTerminal) {
233
- currentStatusTextElement.textContent = "Game Over!";
234
- if (winner) {
235
- if (String(winner).toLowerCase() === 'draw') {
236
- currentWinnerTextElement.textContent = "It's a Draw!";
237
- } else {
238
- const winnerColor = String(winner).toLowerCase() === 'white' ? 'White' : 'Black';
239
- currentWinnerTextElement.innerHTML = `Winner: <span style="font-weight: bold;">${winnerColor}</span>`;
240
- }
355
+ const winnerText = winner
356
+ ? String(winner).toLowerCase() === 'draw'
357
+ ? "It's a Draw!"
358
+ : winner
359
+ : 'Game ended.';
360
+ if (isMobile) {
361
+ currentStatusTextElement.innerHTML = `<div style="font-size: 0.9rem; color: #666;">Winner</div>`;
362
+ currentWinnerTextElement.innerHTML = `<div style="font-size: 1.1rem; font-weight: bold;">${winnerText}</div>`;
241
363
  } else {
242
- currentWinnerTextElement.textContent = "Game ended.";
364
+ currentStatusTextElement.textContent = 'Game Over!';
365
+ currentWinnerTextElement.innerHTML = `Winner: <span style="font-weight: bold;">${winnerText}</span>`;
243
366
  }
244
367
  } else {
245
- const playerColor = String(activeColor).toLowerCase() === 'w' ? 'White' : 'Black';
246
- currentStatusTextElement.innerHTML = `Current Player: <span style="font-weight: bold;">${playerColor}</span>`;
368
+ const playerColor = String(activeColor).toLowerCase() === 'w' ? 'White' : 'Black';
369
+ const teamName = _getTeamNameForColor(playerColor, environment.info?.TeamNames);
370
+ const currentPlayerText = teamName ? `${playerColor} (${teamName})` : playerColor;
371
+
372
+ if (isMobile) {
373
+ currentStatusTextElement.innerHTML = `<div style="font-size: 0.9rem; color: #666;">Current Player</div>`;
374
+ currentWinnerTextElement.innerHTML = `<div style="font-size: 1.1rem; font-weight: bold;">${currentPlayerText}</div>`;
375
+ } else {
376
+ currentStatusTextElement.innerHTML = `Current Player: <span style="font-weight: bold;">${currentPlayerText}</span>`;
377
+ currentWinnerTextElement.innerHTML = ''; // Clear winner text when game is active
378
+ }
247
379
  }
248
380
  }
249
381
 
250
- // --- Main execution logic ---
251
382
  if (!_ensureRendererElements(parent, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS)) {
252
383
  if (parent && typeof parent.innerHTML !== 'undefined') {
253
- parent.innerHTML = "<p style='color:red; font-family: sans-serif;'>Critical Error: Renderer element setup failed.</p>";
384
+ parent.innerHTML =
385
+ "<p style='color:red; font-family: sans-serif;'>Critical Error: Renderer element setup failed.</p>";
254
386
  }
255
387
  return;
256
388
  }
257
389
 
258
390
  if (!environment || !environment.steps || !environment.steps[step]) {
259
391
  _renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
260
- if (currentStatusTextElement) currentStatusTextElement.textContent = "Initializing environment...";
392
+ if (currentStatusTextElement) currentStatusTextElement.textContent = 'Initializing environment...';
261
393
  return;
262
394
  }
263
395
 
264
396
  const currentStepAgents = environment.steps[step];
265
397
  if (!currentStepAgents || !Array.isArray(currentStepAgents) || currentStepAgents.length === 0) {
266
398
  _renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
267
- if (currentStatusTextElement) currentStatusTextElement.textContent = "Waiting for agent data...";
399
+ if (currentStatusTextElement) currentStatusTextElement.textContent = 'Waiting for agent data...';
268
400
  return;
269
401
  }
270
-
271
- // In chess, observation is the same for both agents. We can take it from the first.
402
+
272
403
  const agent = currentStepAgents[0];
273
404
 
274
405
  if (!agent || typeof agent.observation === 'undefined') {
275
406
  _renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
276
- if (currentStatusTextElement) currentStatusTextElement.textContent = "Waiting for observation data...";
407
+ if (currentStatusTextElement) currentStatusTextElement.textContent = 'Waiting for observation data...';
277
408
  return;
278
409
  }
279
410
  const observationForRenderer = agent.observation;
280
411
 
281
412
  let gameSpecificState = null;
282
413
 
283
- if (observationForRenderer && typeof observationForRenderer.observationString === 'string' && observationForRenderer.observationString.trim() !== '') {
414
+ if (
415
+ observationForRenderer &&
416
+ typeof observationForRenderer.observationString === 'string' &&
417
+ observationForRenderer.observationString.trim() !== ''
418
+ ) {
284
419
  try {
285
420
  const fen = observationForRenderer.observationString;
286
421
  const parsedFen = _parseFen(fen);
287
422
  if (parsedFen) {
288
- // Assuming `isTerminal` and `winner` are provided in the top-level observation
289
- gameSpecificState = {
423
+ const winner = observationForRenderer.isTerminal
424
+ ? _deriveWinnerFromRewards(currentStepAgents, environment.info?.TeamNames)
425
+ : null;
426
+ gameSpecificState = {
290
427
  ...parsedFen,
291
428
  isTerminal: observationForRenderer.isTerminal,
292
- winner: observationForRenderer.winner
429
+ winner: winner
293
430
  };
294
431
  }
295
432
  } catch (e) {
296
- _showMessage("Error: Corrupted game state (obs_string).", 'error');
433
+ _showMessage('Error: Corrupted game state (obs_string).', 'error');
297
434
  }
298
435
  }
299
436
 
@@ -13,7 +13,7 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  -->
16
- <!DOCTYPE html>
16
+ <!doctype html>
17
17
  <html lang="en">
18
18
  <head>
19
19
  <title>Kaggle Simulation Player</title>
@@ -96,7 +96,7 @@
96
96
  </g>
97
97
  </svg>
98
98
  </a>
99
- `
99
+ `,
100
100
  )`
101
101
  display: inline-flex;
102
102
  `;
@@ -129,11 +129,9 @@
129
129
 
130
130
  useEffect(async () => {
131
131
  if (!ref.current) return;
132
-
133
132
  const renderFrame = async (start, step, lastFrame) => {
134
133
  if (step !== context.step) return;
135
134
  if (lastFrame === 1) {
136
- if (!animate) return;
137
135
  start = Date.now();
138
136
  }
139
137
  const frame =
@@ -142,16 +140,18 @@
142
140
  : 1;
143
141
  try {
144
142
  if (debug) console.time("render");
145
- await renderer({
146
- ...context,
147
- frame,
148
- height: ref.current.clientHeight,
149
- hooks: preactHooks,
150
- parent: ref.current,
151
- preact,
152
- styled,
153
- width: ref.current.clientWidth,
154
- });
143
+ if (typeof renderer === "function") {
144
+ await renderer({
145
+ ...context,
146
+ frame,
147
+ height: ref.current.clientHeight,
148
+ hooks: preactHooks,
149
+ parent: ref.current,
150
+ preact,
151
+ styled,
152
+ width: ref.current.clientWidth,
153
+ });
154
+ }
155
155
  } catch (error) {
156
156
  if (debug) console.error(error);
157
157
  console.log({ ...context, frame, error });
@@ -199,7 +199,7 @@
199
199
  ${processing && h`<${Processing} />`}
200
200
  </div>`;
201
201
  })`
202
- background-color: #1C1D20;
202
+ background-color: #1c1d20;
203
203
  display: flex;
204
204
  flex: 1;
205
205
  overflow: hidden;
@@ -210,34 +210,40 @@
210
210
  // Partitions the elements of arr into subarrays of max length num.
211
211
  const groupIntoSets = (arr, num) => {
212
212
  const sets = [];
213
- arr.forEach(a => {
213
+ arr.forEach((a) => {
214
214
  if (sets.length === 0 || sets[sets.length - 1].length === num) {
215
215
  sets.push([]);
216
216
  }
217
217
  sets[sets.length - 1].push(a);
218
218
  });
219
219
  return sets;
220
- }
220
+ };
221
221
 
222
222
  // Expects `width` input prop to set proper max-width for agent name span.
223
223
  const Legend = styled((props) => {
224
224
  const { agents, legend } = useContext(Context);
225
225
 
226
- const agentPairs = groupIntoSets(agents.sort((a, b) => a.index - b.index), 2);
226
+ const agentPairs = groupIntoSets(
227
+ agents.sort((a, b) => a.index - b.index),
228
+ 2,
229
+ );
227
230
 
228
231
  return h`<div className=${props.className}>
229
- ${agentPairs.map(agentList =>
230
- h`<ul>
231
- ${agentList.map(a =>
232
- h`<li key=${a.id} title="id: ${a.id}" style="color:${a.color || "#FFF"}">
232
+ ${agentPairs.map(
233
+ (agentList) =>
234
+ h`<ul>
235
+ ${agentList.map(
236
+ (a) =>
237
+ h`<li key=${a.id} title="id: ${a.id}" style="color:${a.color || "#FFF"}">
233
238
  ${a.image && h`<img src=${a.image} />`}
234
239
  <span>${a.name}</span>
235
- </li>`
240
+ </li>`,
236
241
  )}
237
- </ul>`)}
242
+ </ul>`,
243
+ )}
238
244
  </div>`;
239
245
  })`
240
- background-color: #1C1D20;
246
+ background-color: #1c1d20;
241
247
  font-family: sans-serif;
242
248
  font-size: 14px;
243
249
  height: 48px;
@@ -257,7 +263,7 @@
257
263
  }
258
264
 
259
265
  span {
260
- max-width: ${p => (p.width || 400) * 0.5 - 36}px;
266
+ max-width: ${(p) => (p.width || 400) * 0.5 - 36}px;
261
267
  overflow: hidden;
262
268
  text-overflow: ellipsis;
263
269
  white-space: nowrap;
@@ -343,9 +349,8 @@
343
349
  `;
344
350
 
345
351
  const Controls = styled((props) => {
346
- const { environment, pause, play, playing, setStep, step } = useContext(
347
- Context
348
- );
352
+ const { environment, pause, play, playing, setStep, step } =
353
+ useContext(Context);
349
354
  const value = step + 1;
350
355
  const onClick = () => (playing ? pause() : play());
351
356
  const onInput = (e) => {
@@ -356,13 +361,11 @@
356
361
  return h`
357
362
  <div className=${props.className}>
358
363
  <${PlayButton} onClick=${onClick}><svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#FFFFFF">${
359
- playing
360
- ? h`<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/>`
361
- : h`<path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/>`
362
- }</svg><//>
363
- <${StepInput} min="1" max=${
364
- environment.steps.length
365
- } value="${value}" onInput=${onInput} />
364
+ playing
365
+ ? h`<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/>`
366
+ : h`<path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/>`
367
+ }</svg><//>
368
+ <${StepInput} min="1" max=${environment.steps.length} value="${value}" onInput=${onInput} />
366
369
  <${StepCount}>${value} / ${environment.steps.length}<//>
367
370
  </div>
368
371
  `;
@@ -401,9 +404,8 @@
401
404
  `;
402
405
 
403
406
  const Settings = styled((props) => {
404
- const { environment, pause, play, playing, setStep, step } = useContext(
405
- Context
406
- );
407
+ const { environment, pause, play, playing, setStep, step } =
408
+ useContext(Context);
407
409
 
408
410
  return h`
409
411
  <div className=${props.className}>
@@ -424,13 +426,14 @@
424
426
 
425
427
  const Player = styled((props) => {
426
428
  const context = useContext(Context);
427
- const { agents, controls, header, legend, loading, settings, width } = context;
429
+ const { agents, controls, header, legend, loading, settings, width } =
430
+ context;
428
431
  return h`
429
432
  <div className=${props.className}>
430
433
  ${loading && h`<${Loading} />`}
431
434
  ${!loading && header && h`<${Header} />`}
432
435
  ${!loading && h`<${Viewer} />`}
433
- ${!loading && legend && h`<${Legend} width=${width}/>`}
436
+ ${!loading && legend && agents?.length > 0 && h`<${Legend} width=${width}/>`}
434
437
  ${!loading && controls && h`<${Controls} />`}
435
438
  ${!loading && settings && h`<${Settings} />`}
436
439
  </div>`;
@@ -444,7 +447,6 @@
444
447
  justify-content: center;
445
448
  position: relative;
446
449
  width: 100%;
447
-
448
450
  &:not(.no-border) {
449
451
  border: 4px solid #212121;
450
452
  }
@@ -544,7 +546,7 @@
544
546
  updateContext(window.kaggle || {});
545
547
 
546
548
  if (window.kaggle?.playing) {
547
- play(true);
549
+ play(true);
548
550
  }
549
551
 
550
552
  // Listen for messages received to update the context.
@@ -554,16 +556,19 @@
554
556
  // Ensure the environment names match before updating.
555
557
  try {
556
558
  if (
557
- event.data.environment?.name == contextRef.current.environment.name ||
558
- event.data.environment?.name && !contextRef.current.environment.name ||
559
- event.data.environment?.loading !== contextRef.current.environment.loading
559
+ event.data.environment?.name ==
560
+ contextRef.current.environment.name ||
561
+ (event.data.environment?.name &&
562
+ !contextRef.current.environment.name) ||
563
+ event.data.environment?.loading !==
564
+ contextRef.current.environment.loading
560
565
  ) {
561
566
  const nextContext = {
562
567
  ...event.data,
563
568
  environment: {
564
569
  ...event.data.environment,
565
- steps: event.data.environment?.steps ?? []
566
- }
570
+ steps: event.data.environment?.steps ?? [],
571
+ },
567
572
  };
568
573
  window.kaggle = nextContext;
569
574
  if (!window.kaggle.renderer) {
@@ -576,21 +581,24 @@
576
581
  ...(window.kaggle ?? {}),
577
582
  environment: {
578
583
  ...(window.kaggle?.environment ?? {}),
579
- steps: event.data.setSteps
580
- }
581
- }
584
+ steps: event.data.setSteps,
585
+ },
586
+ };
582
587
  window.kaggle = nextContext;
583
588
  if (!window.kaggle.renderer) {
584
589
  window.kaggle.renderer = window.renderer;
585
590
  }
586
- updateContext(nextContext)
591
+ updateContext(nextContext);
587
592
  }
588
593
 
589
594
  // Side load the renderer script if it is specified by the post message event and not already loaded.
590
- const renderScriptId = 'rendererScript'
591
- if (event.data.environment?.rendererUrl && !document.querySelector(`#${renderScriptId}`)) {
595
+ const renderScriptId = "rendererScript";
596
+ if (
597
+ event.data.environment?.rendererUrl &&
598
+ !document.querySelector(`#${renderScriptId}`)
599
+ ) {
592
600
  window.rendererUrl = event.data.environment?.rendererUrl;
593
- const script = document.createElement('script');
601
+ const script = document.createElement("script");
594
602
  script.id = renderScriptId;
595
603
  script.onload = () => {
596
604
  window.kaggle.renderer = window.renderer;
@@ -600,7 +608,7 @@
600
608
  }
601
609
  } catch {}
602
610
  },
603
- false
611
+ false,
604
612
  );
605
613
  // Listen for keyboard commands.
606
614
  window.addEventListener(
@@ -614,12 +622,15 @@
614
622
  environment,
615
623
  } = contextRef.current;
616
624
  const key = event.keyCode;
617
- const zero_key = 48
618
- const nine_key = 57
625
+ const zero_key = 48;
626
+ const nine_key = 57;
619
627
  if (
620
628
  interactive ||
621
629
  isInteractive() ||
622
- (key !== 32 && key !== 37 && key !== 39 && !(key >= zero_key && key <= nine_key))
630
+ (key !== 32 &&
631
+ key !== 37 &&
632
+ key !== 39 &&
633
+ !(key >= zero_key && key <= nine_key))
623
634
  )
624
635
  return;
625
636
 
@@ -639,7 +650,7 @@
639
650
  event.preventDefault();
640
651
  return false;
641
652
  },
642
- false
653
+ false,
643
654
  );
644
655
  }, 1);
645
656
  }, []);
@@ -711,7 +722,7 @@
711
722
 
712
723
  return h`
713
724
  <${Context.Provider} value=${contextRef.current}>
714
- <${Player} className="${contextRef.current.environment.viewer ? 'no-border' : ''}" />
725
+ <${Player} className="${contextRef.current.environment.viewer ? "no-border" : ""}" />
715
726
  <//>`;
716
727
  };
717
728
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaggle-environments
3
- Version: 1.17.9
3
+ Version: 1.17.11
4
4
  Summary: Kaggle Environments
5
5
  Home-page: https://github.com/Kaggle/kaggle-environments
6
6
  Author: Kaggle
@@ -1,7 +1,7 @@
1
- kaggle_environments/__init__.py,sha256=8QsPJZNGNhDEtrXxvMEN4wlcphBUksoAC5kBxTNoUnE,2175
2
- kaggle_environments/agent.py,sha256=j9rLnCK_Gy0eRIuvlJ9vcMh3vxn-Wvu-pjCpannOolc,6703
1
+ kaggle_environments/__init__.py,sha256=BoiIlX0lR_CDejEoWTSOXz8UVsK4HrVbCMLt6TtFtdc,2176
2
+ kaggle_environments/agent.py,sha256=IgRagzcTi6F73nPeViDdh9wvHnx8fQhFmXJNutovGZE,6706
3
3
  kaggle_environments/api.py,sha256=eLBKqr11Ku4tdsMUdUqy74FIVEA_hdV3_QUpX84x3Z8,798
4
- kaggle_environments/core.py,sha256=Ense_M-2rP4KmVeuKFjM0NQ8M6ucUZTbhwrGekyR9LY,27857
4
+ kaggle_environments/core.py,sha256=PzF9NR0rFfFikspJ3HE0uI8UOiv_tlDhGSbu11g9vQQ,27860
5
5
  kaggle_environments/errors.py,sha256=SzKjkZP7pJbf9g0GDjGq4XG194hCQXLMwrlMCcm7Ai8,3336
6
6
  kaggle_environments/helpers.py,sha256=xkOMXaOMifYHHstDZo8bexk-Qq9suPM7Gkfi2JbXu8M,10627
7
7
  kaggle_environments/main.py,sha256=10wtcEFcGIjdOd9AEps5WOAwslc6Wsx3eZ43LXJa8jE,11705
@@ -196,7 +196,7 @@ kaggle_environments/envs/open_spiel/proxy.py,sha256=8Shane4KWYKvbP9nV3l8VQfAFOfF
196
196
  kaggle_environments/envs/open_spiel/proxy_test.py,sha256=QkmRo_uS0DgDDm2pbU2vwal5KOMCWKw92rC2_g3MziM,1837
197
197
  kaggle_environments/envs/open_spiel/test_open_spiel.py,sha256=MwyjH-e00-3SP8_r10drYTFvplacbo0cDCI0XKtE4wU,3596
198
198
  kaggle_environments/envs/open_spiel/games/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
199
- kaggle_environments/envs/open_spiel/games/chess/chess.js,sha256=cObFpGh4MG07UYbLWOosWvhclaFwAfnOPoyfm45xvrE,12966
199
+ kaggle_environments/envs/open_spiel/games/chess/chess.js,sha256=1WEZrngIX-0zNltBg1lWj8aqTWTMGIzCLSR83sUXa3g,19277
200
200
  kaggle_environments/envs/open_spiel/games/connect_four/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js,sha256=iO74ar3Hh64VYEx9v3eysgrPU-Mcokl9dkFxie6uISg,14893
202
202
  kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py,sha256=2otG99felDYhNhWpsadbM9YUaHtrXqhV1GFNEHhuPwA,2348
@@ -223,10 +223,10 @@ kaggle_environments/envs/tictactoe/test_tictactoe.py,sha256=6CgQbRz-yxNoMfD5tzmC
223
223
  kaggle_environments/envs/tictactoe/tictactoe.js,sha256=NZDT-oSG0a6a-rso9Ldh9qkJwVrxrAsjKUC3_tJu3tw,8002
224
224
  kaggle_environments/envs/tictactoe/tictactoe.json,sha256=zMXZ8-fpT7FBhzz2FFBvRLn4XwtngjEqOieMvI6cCj8,1121
225
225
  kaggle_environments/envs/tictactoe/tictactoe.py,sha256=uq3sTHWNMg0dxX2v9pTbJAKM7fwerxQt7OQjCX96m-Y,3657
226
- kaggle_environments/static/player.html,sha256=TTxN-EU7_KCNIVDX4E4TrZ61FRWkGUDHMSbnUYsQSvg,24975
227
- kaggle_environments-1.17.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
228
- kaggle_environments-1.17.9.dist-info/METADATA,sha256=WJv0FzLXP7eUEdZenlYdQyPdhSD2-UGKFhA73RAv8PU,10955
229
- kaggle_environments-1.17.9.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
230
- kaggle_environments-1.17.9.dist-info/entry_points.txt,sha256=HbVC-LKGQFV6lEEYBYyDTtrkHgdHJUWQ8_qt9KHGqz4,70
231
- kaggle_environments-1.17.9.dist-info/top_level.txt,sha256=v3MMWIPMQFcI-WuF_dJngHWe9Bb2yH_6p4wat1x4gAc,20
232
- kaggle_environments-1.17.9.dist-info/RECORD,,
226
+ kaggle_environments/static/player.html,sha256=l00X3_tfLtr_DmP7xpJFs8lKaTQoZtdexnKlHvT1fHc,25320
227
+ kaggle_environments-1.17.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
228
+ kaggle_environments-1.17.11.dist-info/METADATA,sha256=ehWejRG8czTeFjtHtCWZxDt7BuJo57M3nM8xWjUx7Oo,10956
229
+ kaggle_environments-1.17.11.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
230
+ kaggle_environments-1.17.11.dist-info/entry_points.txt,sha256=HbVC-LKGQFV6lEEYBYyDTtrkHgdHJUWQ8_qt9KHGqz4,70
231
+ kaggle_environments-1.17.11.dist-info/top_level.txt,sha256=v3MMWIPMQFcI-WuF_dJngHWe9Bb2yH_6p4wat1x4gAc,20
232
+ kaggle_environments-1.17.11.dist-info/RECORD,,