kaggle-environments 0.2.0__py3-none-any.whl → 1.20.0__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.

Files changed (215) hide show
  1. kaggle_environments/__init__.py +49 -13
  2. kaggle_environments/agent.py +177 -124
  3. kaggle_environments/api.py +31 -0
  4. kaggle_environments/core.py +298 -173
  5. kaggle_environments/envs/cabt/cabt.js +164 -0
  6. kaggle_environments/envs/cabt/cabt.json +28 -0
  7. kaggle_environments/envs/cabt/cabt.py +186 -0
  8. kaggle_environments/envs/cabt/cg/__init__.py +0 -0
  9. kaggle_environments/envs/cabt/cg/cg.dll +0 -0
  10. kaggle_environments/envs/cabt/cg/game.py +75 -0
  11. kaggle_environments/envs/cabt/cg/libcg.so +0 -0
  12. kaggle_environments/envs/cabt/cg/sim.py +48 -0
  13. kaggle_environments/envs/cabt/test_cabt.py +120 -0
  14. kaggle_environments/envs/chess/chess.js +4289 -0
  15. kaggle_environments/envs/chess/chess.json +60 -0
  16. kaggle_environments/envs/chess/chess.py +4241 -0
  17. kaggle_environments/envs/chess/test_chess.py +60 -0
  18. kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
  19. kaggle_environments/envs/connectx/connectx.js +1 -1
  20. kaggle_environments/envs/connectx/connectx.json +15 -1
  21. kaggle_environments/envs/connectx/connectx.py +6 -23
  22. kaggle_environments/envs/connectx/test_connectx.py +70 -24
  23. kaggle_environments/envs/football/football.ipynb +75 -0
  24. kaggle_environments/envs/football/football.json +91 -0
  25. kaggle_environments/envs/football/football.py +277 -0
  26. kaggle_environments/envs/football/helpers.py +95 -0
  27. kaggle_environments/envs/football/test_football.py +360 -0
  28. kaggle_environments/envs/halite/__init__.py +0 -0
  29. kaggle_environments/envs/halite/halite.ipynb +44741 -0
  30. kaggle_environments/envs/halite/halite.js +199 -83
  31. kaggle_environments/envs/halite/halite.json +31 -18
  32. kaggle_environments/envs/halite/halite.py +164 -303
  33. kaggle_environments/envs/halite/helpers.py +720 -0
  34. kaggle_environments/envs/halite/test_halite.py +190 -0
  35. kaggle_environments/envs/hungry_geese/__init__.py +0 -0
  36. kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
  37. kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +22 -15
  38. kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
  39. kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
  40. kaggle_environments/envs/identity/identity.json +6 -5
  41. kaggle_environments/envs/identity/identity.py +15 -2
  42. kaggle_environments/envs/kore_fleets/__init__.py +0 -0
  43. kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
  44. kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
  45. kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
  46. kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
  47. kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
  48. kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
  49. kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
  50. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
  51. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
  52. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
  53. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
  54. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
  55. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
  56. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
  57. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
  58. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
  59. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
  60. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
  61. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
  62. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
  63. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
  64. kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
  65. kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
  66. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
  67. kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
  68. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
  69. kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
  70. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
  71. kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
  72. kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
  73. kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
  74. kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
  75. kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
  76. kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
  77. kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
  78. kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
  79. kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
  80. kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
  81. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
  82. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
  83. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
  84. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
  85. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
  86. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
  87. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
  88. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
  89. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
  90. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
  91. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
  92. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
  93. kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
  94. kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
  95. kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
  96. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
  97. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
  98. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
  99. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
  100. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
  101. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
  102. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
  103. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
  104. kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
  105. kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
  106. kaggle_environments/envs/lux_ai_2021/README.md +3 -0
  107. kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
  108. kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
  109. kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
  110. kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
  111. kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
  112. kaggle_environments/envs/lux_ai_2021/index.html +43 -0
  113. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
  114. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
  115. kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
  116. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
  117. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
  118. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
  119. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
  120. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
  121. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
  122. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
  123. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
  124. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
  125. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
  126. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
  127. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
  128. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
  129. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
  130. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
  131. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
  132. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
  133. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
  134. kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
  135. kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
  136. kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
  137. kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
  138. kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
  139. kaggle_environments/envs/lux_ai_s3/README.md +21 -0
  140. kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
  141. kaggle_environments/envs/lux_ai_s3/index.html +42 -0
  142. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
  143. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
  144. kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
  145. kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
  146. kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
  147. kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
  148. kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
  149. kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
  150. kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
  151. kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
  152. kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
  153. kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
  154. kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
  155. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
  156. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
  157. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
  158. kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
  159. kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
  160. kaggle_environments/envs/mab/__init__.py +0 -0
  161. kaggle_environments/envs/mab/agents.py +12 -0
  162. kaggle_environments/envs/mab/mab.js +100 -0
  163. kaggle_environments/envs/mab/mab.json +74 -0
  164. kaggle_environments/envs/mab/mab.py +146 -0
  165. kaggle_environments/envs/open_spiel/__init__.py +0 -0
  166. kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
  167. kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
  168. kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
  169. kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
  170. kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
  171. kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
  172. kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
  173. kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
  174. kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
  175. kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
  176. kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
  177. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
  178. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
  179. kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
  180. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
  181. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
  182. kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
  183. kaggle_environments/envs/open_spiel/observation.py +128 -0
  184. kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
  185. kaggle_environments/envs/open_spiel/proxy.py +138 -0
  186. kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
  187. kaggle_environments/envs/rps/__init__.py +0 -0
  188. kaggle_environments/envs/rps/agents.py +84 -0
  189. kaggle_environments/envs/rps/helpers.py +25 -0
  190. kaggle_environments/envs/rps/rps.js +117 -0
  191. kaggle_environments/envs/rps/rps.json +63 -0
  192. kaggle_environments/envs/rps/rps.py +90 -0
  193. kaggle_environments/envs/rps/test_rps.py +110 -0
  194. kaggle_environments/envs/rps/utils.py +7 -0
  195. kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
  196. kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
  197. kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
  198. kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
  199. kaggle_environments/errors.py +2 -4
  200. kaggle_environments/helpers.py +377 -0
  201. kaggle_environments/main.py +214 -50
  202. kaggle_environments/schemas.json +23 -18
  203. kaggle_environments/static/player.html +206 -74
  204. kaggle_environments/utils.py +46 -73
  205. kaggle_environments-1.20.0.dist-info/METADATA +25 -0
  206. kaggle_environments-1.20.0.dist-info/RECORD +211 -0
  207. {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
  208. kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
  209. kaggle_environments/envs/battlegeese/battlegeese.py +0 -219
  210. kaggle_environments/temp.py +0 -14
  211. kaggle_environments-0.2.0.dist-info/METADATA +0 -393
  212. kaggle_environments-0.2.0.dist-info/RECORD +0 -33
  213. kaggle_environments-0.2.0.dist-info/entry_points.txt +0 -3
  214. kaggle_environments-0.2.0.dist-info/top_level.txt +0 -1
  215. {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,481 @@
1
+ // Go Board Renderer for OpenSpiel
2
+ function renderer(options) {
3
+ const { environment, step, parent, interactive, isInteractive, maxBoardSize = 800 } = options;
4
+
5
+ // --- Constants ---
6
+ const DEFAULT_BOARD_SIZE = 19;
7
+ const STONE_COLORS = {
8
+ 'B': '#2d3748', // Black stone
9
+ 'W': '#f7fafc', // White stone with slight gray tint
10
+ '.': 'transparent' // Empty intersection
11
+ };
12
+ const BOARD_COLOR = '#dcb871'; // Traditional Go board wood color
13
+ const LINE_COLOR = '#8b4513'; // Dark brown for grid lines
14
+ const STAR_POINT_COLOR = '#654321'; // Darker brown for star points
15
+ const LABEL_COLOR = '#2d3748';
16
+
17
+ const SVG_NS = "http://www.w3.org/2000/svg";
18
+
19
+ // Dynamic sizing based on board size
20
+ function getBoardConfig(boardSize) {
21
+ let intersectionSize, margin, fontSize;
22
+
23
+ if (boardSize <= 9) {
24
+ intersectionSize = 35;
25
+ margin = 45;
26
+ fontSize = 14;
27
+ } else if (boardSize <= 13) {
28
+ intersectionSize = 30;
29
+ margin = 40;
30
+ fontSize = 13;
31
+ } else {
32
+ intersectionSize = 25;
33
+ margin = 35;
34
+ fontSize = 12;
35
+ }
36
+
37
+ return { intersectionSize, margin, fontSize };
38
+ }
39
+
40
+ // Go column labels (A-T, omitting I)
41
+ const COLUMN_LABELS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'];
42
+
43
+ let currentBoardSvgElement = null;
44
+ let currentStatusTextElement = null;
45
+ let currentWinnerTextElement = null;
46
+ let currentMessageBoxElement = typeof document !== 'undefined' ? document.getElementById('messageBox') : null;
47
+ let currentRendererContainer = null;
48
+ let currentTitleElement = null;
49
+
50
+ function _showMessage(message, type = 'info', duration = 3000) {
51
+ if (typeof document === 'undefined' || !document.body) return;
52
+ if (!currentMessageBoxElement) {
53
+ currentMessageBoxElement = document.createElement('div');
54
+ currentMessageBoxElement.id = 'messageBox';
55
+ currentMessageBoxElement.style.position = 'fixed';
56
+ currentMessageBoxElement.style.top = '10px';
57
+ currentMessageBoxElement.style.left = '50%';
58
+ currentMessageBoxElement.style.transform = 'translateX(-50%)';
59
+ currentMessageBoxElement.style.padding = '0.75rem 1rem';
60
+ currentMessageBoxElement.style.borderRadius = '0.375rem';
61
+ currentMessageBoxElement.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
62
+ currentMessageBoxElement.style.zIndex = '1000';
63
+ currentMessageBoxElement.style.opacity = '0';
64
+ currentMessageBoxElement.style.transition = 'opacity 0.3s ease-in-out, background-color 0.3s';
65
+ currentMessageBoxElement.style.fontSize = '0.875rem';
66
+ currentMessageBoxElement.style.fontFamily = "'Inter', sans-serif";
67
+ document.body.appendChild(currentMessageBoxElement);
68
+ }
69
+ currentMessageBoxElement.textContent = message;
70
+ currentMessageBoxElement.style.backgroundColor = type === 'error' ? '#ef4444' : '#10b981';
71
+ currentMessageBoxElement.style.color = 'white';
72
+ currentMessageBoxElement.style.opacity = '1';
73
+ setTimeout(() => { if (currentMessageBoxElement) currentMessageBoxElement.style.opacity = '0'; }, duration);
74
+ }
75
+
76
+ function _getStarPoints(boardSize) {
77
+ // Star points for different board sizes
78
+ const starPointsMap = {
79
+ 9: [[2, 2], [2, 6], [4, 4], [6, 2], [6, 6]],
80
+ 13: [[3, 3], [3, 9], [6, 6], [9, 3], [9, 9]],
81
+ 19: [[3, 3], [3, 9], [3, 15], [9, 3], [9, 9], [9, 15], [15, 3], [15, 9], [15, 15]]
82
+ };
83
+ return starPointsMap[boardSize] || [];
84
+ }
85
+
86
+ function _ensureRendererElements(parentElementToClear, boardSize) {
87
+ if (!parentElementToClear) return false;
88
+ parentElementToClear.innerHTML = '';
89
+
90
+ const config = getBoardConfig(boardSize);
91
+ const { intersectionSize, margin, fontSize } = config;
92
+
93
+ currentRendererContainer = document.createElement('div');
94
+ currentRendererContainer.style.display = 'flex';
95
+ currentRendererContainer.style.flexDirection = 'column';
96
+ currentRendererContainer.style.alignItems = 'center';
97
+ currentRendererContainer.style.padding = '20px';
98
+ currentRendererContainer.style.boxSizing = 'border-box';
99
+ currentRendererContainer.style.width = '100%';
100
+ currentRendererContainer.style.height = '100%';
101
+ currentRendererContainer.style.fontFamily = "'Inter', sans-serif";
102
+
103
+ currentTitleElement = document.createElement('h1');
104
+ currentTitleElement.textContent = `Go (${boardSize}×${boardSize})`;
105
+ currentTitleElement.style.fontSize = '1.875rem';
106
+ currentTitleElement.style.fontWeight = 'bold';
107
+ currentTitleElement.style.marginBottom = '1rem';
108
+ currentTitleElement.style.textAlign = 'center';
109
+ currentTitleElement.style.color = '#2563eb';
110
+ currentRendererContainer.appendChild(currentTitleElement);
111
+
112
+ // Calculate SVG dimensions
113
+ const boardPixelSize = (boardSize - 1) * intersectionSize;
114
+ const svgWidth = boardPixelSize + (2 * margin);
115
+ const svgHeight = boardPixelSize + (2 * margin);
116
+
117
+ currentBoardSvgElement = document.createElementNS(SVG_NS, "svg");
118
+ currentBoardSvgElement.setAttribute("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
119
+ currentBoardSvgElement.setAttribute("preserveAspectRatio", "xMidYMid meet");
120
+ currentBoardSvgElement.style.width = "auto";
121
+ currentBoardSvgElement.style.maxWidth = `${maxBoardSize}px`;
122
+ currentBoardSvgElement.style.maxHeight = `${maxBoardSize}px`;
123
+ currentBoardSvgElement.style.aspectRatio = "1 / 1";
124
+ currentBoardSvgElement.style.display = "block";
125
+ currentBoardSvgElement.style.margin = "0 auto 20px auto";
126
+
127
+ // Board background
128
+ const boardBgRect = document.createElementNS(SVG_NS, "rect");
129
+ boardBgRect.setAttribute("x", "0");
130
+ boardBgRect.setAttribute("y", "0");
131
+ boardBgRect.setAttribute("width", svgWidth.toString());
132
+ boardBgRect.setAttribute("height", svgHeight.toString());
133
+ boardBgRect.setAttribute("fill", BOARD_COLOR);
134
+ boardBgRect.setAttribute("rx", "8");
135
+ currentBoardSvgElement.appendChild(boardBgRect);
136
+
137
+ // Grid lines
138
+ for (let i = 0; i < boardSize; i++) {
139
+ const x = margin + i * intersectionSize;
140
+ const y = margin + i * intersectionSize;
141
+
142
+ // Vertical lines
143
+ const vLine = document.createElementNS(SVG_NS, "line");
144
+ vLine.setAttribute("x1", x.toString());
145
+ vLine.setAttribute("y1", margin.toString());
146
+ vLine.setAttribute("x2", x.toString());
147
+ vLine.setAttribute("y2", (margin + boardPixelSize).toString());
148
+ vLine.setAttribute("stroke", LINE_COLOR);
149
+ vLine.setAttribute("stroke-width", "1");
150
+ currentBoardSvgElement.appendChild(vLine);
151
+
152
+ // Horizontal lines
153
+ const hLine = document.createElementNS(SVG_NS, "line");
154
+ hLine.setAttribute("x1", margin.toString());
155
+ hLine.setAttribute("y1", y.toString());
156
+ hLine.setAttribute("x2", (margin + boardPixelSize).toString());
157
+ hLine.setAttribute("y2", y.toString());
158
+ hLine.setAttribute("stroke", LINE_COLOR);
159
+ hLine.setAttribute("stroke-width", "1");
160
+ currentBoardSvgElement.appendChild(hLine);
161
+ }
162
+
163
+ // Star points
164
+ const starPoints = _getStarPoints(boardSize);
165
+ starPoints.forEach(([row, col]) => {
166
+ const x = margin + col * intersectionSize;
167
+ const y = margin + row * intersectionSize;
168
+ const starPoint = document.createElementNS(SVG_NS, "circle");
169
+ starPoint.setAttribute("cx", x.toString());
170
+ starPoint.setAttribute("cy", y.toString());
171
+ starPoint.setAttribute("r", "3");
172
+ starPoint.setAttribute("fill", STAR_POINT_COLOR);
173
+ currentBoardSvgElement.appendChild(starPoint);
174
+ });
175
+
176
+ // Coordinate labels
177
+ const labelOffset = Math.max(15, margin * 0.6);
178
+
179
+ for (let i = 0; i < boardSize; i++) {
180
+ // Column labels (top and bottom)
181
+ if (i < COLUMN_LABELS.length) {
182
+ const x = margin + i * intersectionSize;
183
+
184
+ // Top labels
185
+ const topLabel = document.createElementNS(SVG_NS, "text");
186
+ topLabel.setAttribute("x", x.toString());
187
+ topLabel.setAttribute("y", labelOffset.toString());
188
+ topLabel.setAttribute("text-anchor", "middle");
189
+ topLabel.setAttribute("dominant-baseline", "middle");
190
+ topLabel.setAttribute("font-family", "Arial, sans-serif");
191
+ topLabel.setAttribute("font-size", fontSize.toString());
192
+ topLabel.setAttribute("fill", LABEL_COLOR);
193
+ topLabel.textContent = COLUMN_LABELS[i];
194
+ currentBoardSvgElement.appendChild(topLabel);
195
+
196
+ // Bottom labels
197
+ const bottomLabel = document.createElementNS(SVG_NS, "text");
198
+ bottomLabel.setAttribute("x", x.toString());
199
+ bottomLabel.setAttribute("y", (svgHeight - labelOffset + 5).toString());
200
+ bottomLabel.setAttribute("text-anchor", "middle");
201
+ bottomLabel.setAttribute("dominant-baseline", "middle");
202
+ bottomLabel.setAttribute("font-family", "Arial, sans-serif");
203
+ bottomLabel.setAttribute("font-size", fontSize.toString());
204
+ bottomLabel.setAttribute("fill", LABEL_COLOR);
205
+ bottomLabel.textContent = COLUMN_LABELS[i];
206
+ currentBoardSvgElement.appendChild(bottomLabel);
207
+ }
208
+
209
+ // Row labels (left and right) - Go rows are numbered from bottom to top
210
+ const rowNumber = boardSize - i;
211
+ const y = margin + i * intersectionSize;
212
+
213
+ // Left labels
214
+ const leftLabel = document.createElementNS(SVG_NS, "text");
215
+ leftLabel.setAttribute("x", labelOffset.toString());
216
+ leftLabel.setAttribute("y", y.toString());
217
+ leftLabel.setAttribute("text-anchor", "middle");
218
+ leftLabel.setAttribute("dominant-baseline", "middle");
219
+ leftLabel.setAttribute("font-family", "Arial, sans-serif");
220
+ leftLabel.setAttribute("font-size", fontSize.toString());
221
+ leftLabel.setAttribute("fill", LABEL_COLOR);
222
+ leftLabel.textContent = rowNumber.toString();
223
+ currentBoardSvgElement.appendChild(leftLabel);
224
+
225
+ // Right labels
226
+ const rightLabel = document.createElementNS(SVG_NS, "text");
227
+ rightLabel.setAttribute("x", (svgWidth - labelOffset).toString());
228
+ rightLabel.setAttribute("y", y.toString());
229
+ rightLabel.setAttribute("text-anchor", "middle");
230
+ rightLabel.setAttribute("dominant-baseline", "middle");
231
+ rightLabel.setAttribute("font-family", "Arial, sans-serif");
232
+ rightLabel.setAttribute("font-size", fontSize.toString());
233
+ rightLabel.setAttribute("fill", LABEL_COLOR);
234
+ rightLabel.textContent = rowNumber.toString();
235
+ currentBoardSvgElement.appendChild(rightLabel);
236
+ }
237
+
238
+ // Create intersection circles for stones
239
+ const stoneRadius = Math.max(8, intersectionSize * 0.4);
240
+
241
+ for (let row = 0; row < boardSize; row++) {
242
+ for (let col = 0; col < boardSize; col++) {
243
+ const x = margin + col * intersectionSize;
244
+ const y = margin + row * intersectionSize;
245
+ const stone = document.createElementNS(SVG_NS, "circle");
246
+ stone.setAttribute("id", `stone-${row}-${col}`);
247
+ stone.setAttribute("cx", x.toString());
248
+ stone.setAttribute("cy", y.toString());
249
+ stone.setAttribute("r", stoneRadius.toString());
250
+ stone.setAttribute("fill", "transparent");
251
+ stone.setAttribute("stroke", "none");
252
+ currentBoardSvgElement.appendChild(stone);
253
+
254
+ // Create a smaller circle for indicating the most recent move
255
+ const recentMoveRadius = Math.max(3, stoneRadius * 0.55);
256
+ const recentMoveIndicator = document.createElementNS(SVG_NS, "circle");
257
+ recentMoveIndicator.setAttribute("id", `recent-move-${row}-${col}`);
258
+ recentMoveIndicator.setAttribute("cx", x.toString());
259
+ recentMoveIndicator.setAttribute("cy", y.toString());
260
+ recentMoveIndicator.setAttribute("r", recentMoveRadius.toString());
261
+ recentMoveIndicator.setAttribute("fill", "transparent");
262
+ recentMoveIndicator.setAttribute("stroke", "none");
263
+ currentBoardSvgElement.appendChild(recentMoveIndicator);
264
+ }
265
+ }
266
+
267
+ currentRendererContainer.appendChild(currentBoardSvgElement);
268
+
269
+ const statusContainer = document.createElement('div');
270
+ statusContainer.style.padding = '10px 15px';
271
+ statusContainer.style.backgroundColor = 'white';
272
+ statusContainer.style.borderRadius = '8px';
273
+ statusContainer.style.boxShadow = '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06)';
274
+ statusContainer.style.textAlign = 'center';
275
+ statusContainer.style.width = 'auto';
276
+ statusContainer.style.minWidth = '200px';
277
+ statusContainer.style.maxWidth = '90vw';
278
+ currentRendererContainer.appendChild(statusContainer);
279
+
280
+ currentStatusTextElement = document.createElement('p');
281
+ currentStatusTextElement.style.fontSize = '1.1rem';
282
+ currentStatusTextElement.style.fontWeight = '600';
283
+ currentStatusTextElement.style.margin = '0 0 5px 0';
284
+ statusContainer.appendChild(currentStatusTextElement);
285
+
286
+ currentWinnerTextElement = document.createElement('p');
287
+ currentWinnerTextElement.style.fontSize = '1.25rem';
288
+ currentWinnerTextElement.style.fontWeight = '700';
289
+ currentWinnerTextElement.style.margin = '5px 0 0 0';
290
+ statusContainer.appendChild(currentWinnerTextElement);
291
+
292
+ parentElementToClear.appendChild(currentRendererContainer);
293
+
294
+ if (typeof document !== 'undefined' && !document.body.hasAttribute('data-renderer-initialized')) {
295
+ _showMessage("Go Renderer initialized.", "info", 1500);
296
+ document.body.setAttribute('data-renderer-initialized', 'true');
297
+ }
298
+ return true;
299
+ }
300
+
301
+ function _renderBoardDisplay_svg(gameStateToDisplay, boardSize) {
302
+ if (!currentBoardSvgElement || !currentStatusTextElement || !currentWinnerTextElement) return;
303
+
304
+ // Clear all stones and recent move indicators first
305
+ for (let row = 0; row < boardSize; row++) {
306
+ for (let col = 0; col < boardSize; col++) {
307
+ const stoneElement = currentBoardSvgElement.querySelector(`#stone-${row}-${col}`);
308
+ if (stoneElement) {
309
+ stoneElement.setAttribute("fill", "transparent");
310
+ stoneElement.setAttribute("stroke", "none");
311
+ }
312
+
313
+ const recentMoveElement = currentBoardSvgElement.querySelector(`#recent-move-${row}-${col}`);
314
+ if (recentMoveElement) {
315
+ recentMoveElement.setAttribute("fill", "transparent");
316
+ recentMoveElement.setAttribute("stroke", "none");
317
+ }
318
+ }
319
+ }
320
+
321
+ if (!gameStateToDisplay || !gameStateToDisplay.board_grid) {
322
+ currentStatusTextElement.textContent = "Waiting for game data...";
323
+ currentWinnerTextElement.textContent = "";
324
+ return;
325
+ }
326
+
327
+ const { board_grid, current_player_to_move, move_number, komi, previous_move_a1 } = gameStateToDisplay;
328
+
329
+ // Render stones on the board
330
+ // board_grid[0] is the top row (row 9 in a 9x9 board), board_grid[8] is bottom row (row 1)
331
+ for (let gridRow = 0; gridRow < board_grid.length && gridRow < boardSize; gridRow++) {
332
+ const rowData = board_grid[gridRow];
333
+ if (!Array.isArray(rowData)) continue;
334
+
335
+ for (let gridCol = 0; gridCol < rowData.length && gridCol < boardSize; gridCol++) {
336
+ const intersection = rowData[gridCol];
337
+ if (!intersection || typeof intersection !== 'object') continue;
338
+
339
+ // Extract the stone state from the intersection dictionary
340
+ const coordinate = Object.keys(intersection)[0];
341
+ const stoneState = intersection[coordinate];
342
+
343
+ if (stoneState && (stoneState === 'B' || stoneState === 'W')) {
344
+ const stoneElement = currentBoardSvgElement.querySelector(`#stone-${gridRow}-${gridCol}`);
345
+ if (stoneElement) {
346
+ stoneElement.setAttribute("fill", STONE_COLORS[stoneState]);
347
+ stoneElement.setAttribute("stroke", stoneState === 'W' ? '#666' : 'none');
348
+ stoneElement.setAttribute("stroke-width", stoneState === 'W' ? "1" : "0");
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ // Highlight the most recent move if available
355
+ if (previous_move_a1) {
356
+ // Parse the coordinate (e.g., "F4" -> column F, row 4)
357
+ const colLetter = previous_move_a1[0];
358
+ const rowNumber = parseInt(previous_move_a1.slice(1));
359
+
360
+ // Convert to array indices
361
+ const COLUMN_LABELS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'];
362
+ const colIndex = COLUMN_LABELS.indexOf(colLetter);
363
+ const rowIndex = boardSize - rowNumber; // Convert Go row numbering to array index
364
+
365
+ if (rowIndex >= 0 && rowIndex < boardSize && colIndex >= 0 && colIndex < boardSize) {
366
+ const recentMoveElement = currentBoardSvgElement.querySelector(`#recent-move-${rowIndex}-${colIndex}`);
367
+ const stoneElement = currentBoardSvgElement.querySelector(`#stone-${rowIndex}-${colIndex}`);
368
+
369
+ if (recentMoveElement && stoneElement) {
370
+ // Get the color of the stone at this position to determine the indicator color
371
+ const stoneFill = stoneElement.getAttribute("fill");
372
+
373
+ if (stoneFill === STONE_COLORS['B']) {
374
+ // Black stone - use white circle outline
375
+ recentMoveElement.setAttribute("fill", "transparent");
376
+ recentMoveElement.setAttribute("stroke", STONE_COLORS['W']);
377
+ recentMoveElement.setAttribute("stroke-width", "1.25");
378
+ } else if (stoneFill === STONE_COLORS['W']) {
379
+ // White stone - use black circle outline
380
+ recentMoveElement.setAttribute("fill", "transparent");
381
+ recentMoveElement.setAttribute("stroke", STONE_COLORS['B']);
382
+ recentMoveElement.setAttribute("stroke-width", "1.25");
383
+ }
384
+ }
385
+ }
386
+ }
387
+
388
+ // Update status display
389
+ const playerColor = current_player_to_move === 'B' ? '#2d3748' : '#f7fafc';
390
+ const playerName = current_player_to_move === 'B' ? 'Black' : 'White';
391
+
392
+ currentStatusTextElement.innerHTML = `Move ${move_number || 1}: <span style="color: ${playerColor}; font-weight: bold; ${current_player_to_move === 'W' ? 'text-shadow: 1px 1px 2px rgba(0,0,0,0.3);' : ''}">${playerName}</span> to play`;
393
+
394
+ if (previous_move_a1) {
395
+ currentWinnerTextElement.textContent = `Last move: ${previous_move_a1}${komi ? ` • Komi: ${komi}` : ''}`;
396
+ } else {
397
+ currentWinnerTextElement.textContent = komi ? `Komi: ${komi}` : '';
398
+ }
399
+ }
400
+
401
+ // --- Main execution logic ---
402
+ let boardSize = DEFAULT_BOARD_SIZE;
403
+
404
+ // Try to extract board size from game state
405
+ if (environment && environment.steps && environment.steps[step]) {
406
+ const currentStepAgents = environment.steps[step];
407
+ if (Array.isArray(currentStepAgents) && currentStepAgents.length > 0) {
408
+ const gameMasterAgent = currentStepAgents[currentStepAgents.length - 1];
409
+ if (gameMasterAgent && gameMasterAgent.observation) {
410
+ let gameState = null;
411
+
412
+ // Try to parse game state from observation
413
+ if (gameMasterAgent.observation.observationString) {
414
+ try {
415
+ gameState = JSON.parse(gameMasterAgent.observation.observationString);
416
+ } catch (e) {}
417
+ }
418
+
419
+ if (!gameState && gameMasterAgent.observation.json) {
420
+ try {
421
+ gameState = JSON.parse(gameMasterAgent.observation.json);
422
+ } catch (e) {}
423
+ }
424
+
425
+ if (gameState && gameState.board_size) {
426
+ boardSize = gameState.board_size;
427
+ }
428
+ }
429
+ }
430
+ }
431
+
432
+ if (!_ensureRendererElements(parent, boardSize)) {
433
+ if (parent && typeof parent.innerHTML !== 'undefined') {
434
+ parent.innerHTML = "<p style='color:red; font-family: sans-serif;'>Critical Error: Renderer element setup failed.</p>";
435
+ }
436
+ return;
437
+ }
438
+
439
+ if (!environment || !environment.steps || !environment.steps[step]) {
440
+ _renderBoardDisplay_svg(null, boardSize);
441
+ if(currentStatusTextElement) currentStatusTextElement.textContent = "Initializing environment...";
442
+ return;
443
+ }
444
+
445
+ const currentStepAgents = environment.steps[step];
446
+ if (!currentStepAgents || !Array.isArray(currentStepAgents) || currentStepAgents.length === 0) {
447
+ _renderBoardDisplay_svg(null, boardSize);
448
+ if(currentStatusTextElement) currentStatusTextElement.textContent = "Waiting for agent data...";
449
+ return;
450
+ }
451
+
452
+ const gameMasterAgentIndex = currentStepAgents.length - 1;
453
+ const gameMasterAgent = currentStepAgents[gameMasterAgentIndex];
454
+
455
+ if (!gameMasterAgent || typeof gameMasterAgent.observation === 'undefined') {
456
+ _renderBoardDisplay_svg(null, boardSize);
457
+ if(currentStatusTextElement) currentStatusTextElement.textContent = "Waiting for observation data...";
458
+ return;
459
+ }
460
+
461
+ const observationForRenderer = gameMasterAgent.observation;
462
+ let gameSpecificState = null;
463
+
464
+ if (observationForRenderer && typeof observationForRenderer.observationString === 'string' && observationForRenderer.observationString.trim() !== '') {
465
+ try {
466
+ gameSpecificState = JSON.parse(observationForRenderer.observationString);
467
+ } catch (e) {
468
+ _showMessage("Error: Corrupted game state (obs_string).", 'error');
469
+ }
470
+ }
471
+
472
+ if (!gameSpecificState && observationForRenderer && typeof observationForRenderer.json === 'string' && observationForRenderer.json.trim() !== '') {
473
+ try {
474
+ gameSpecificState = JSON.parse(observationForRenderer.json);
475
+ } catch (e) {
476
+ _showMessage("Error: Corrupted game state (json).", 'error');
477
+ }
478
+ }
479
+
480
+ _renderBoardDisplay_svg(gameSpecificState, boardSize);
481
+ }
@@ -0,0 +1,99 @@
1
+ """Change Go state and action string representations."""
2
+
3
+ import json
4
+ from typing import Any
5
+
6
+ import pyspiel
7
+
8
+ from ... import proxy
9
+
10
+
11
+ class GoState(proxy.State):
12
+ """Go state proxy."""
13
+
14
+ def _player_string(self, player: int) -> str:
15
+ if player < 0:
16
+ return pyspiel.PlayerId(player).name.lower()
17
+ elif player == 0:
18
+ return "B"
19
+ elif player == 1:
20
+ return "W"
21
+ else:
22
+ raise ValueError(f"Invalid player: {player}")
23
+
24
+ def _board_string_to_dict(self, board_string: str) -> dict:
25
+ lines = board_string.strip().splitlines()
26
+ if len(lines) < 3:
27
+ raise ValueError("Input string is too short to be a valid board.")
28
+ # The last line contains the column labels (e.g., "ABC...")
29
+ column_labels = lines[-1].strip()
30
+ board_rows = lines[2:-1]
31
+ board_size = len(column_labels)
32
+ if len(board_rows) != board_size:
33
+ raise ValueError(f"Board dimension mismatch: {len(column_labels)} columns but {len(board_rows)} rows.")
34
+ grid = []
35
+ symbol_map = {"+": ".", "X": "B", "O": "W"}
36
+ for i, row_line in enumerate(board_rows):
37
+ row_number = board_size - i
38
+ try:
39
+ board_content = row_line.split(maxsplit=1)[1]
40
+ except IndexError:
41
+ raise ValueError(f"Malformed board row: '{row_line}'")
42
+ current_row_list = []
43
+ for j, stone_char in enumerate(board_content):
44
+ col_letter = column_labels[j]
45
+ coordinate = f"{col_letter}{row_number}"
46
+ # TODO
47
+ point_dict = {coordinate: symbol_map.get(stone_char, "?")}
48
+ current_row_list.append(point_dict)
49
+ grid.append(current_row_list)
50
+ return grid
51
+
52
+ def state_dict(self) -> dict[str, Any]:
53
+ clone_state = self.get_game().__wrapped__.new_initial_state()
54
+ action_strs = []
55
+ for action in self.history():
56
+ action_strs.append(clone_state.action_to_string(action))
57
+ clone_state.apply_action(action)
58
+ prev_move = None if not action_strs else action_strs[-1]
59
+
60
+ return {
61
+ "board_size": self.get_game().get_parameters()["board_size"],
62
+ "komi": self.get_game().get_parameters()["komi"],
63
+ "current_player_to_move": self._player_string(self.current_player()),
64
+ "move_number": len(self.history()) + 1,
65
+ "previous_move_a1": prev_move,
66
+ "board_grid": self._board_string_to_dict(self.__wrapped__.__str__()),
67
+ }
68
+
69
+ def to_json(self) -> str:
70
+ return json.dumps(self.state_dict())
71
+
72
+ def observation_string(self, player: int) -> str:
73
+ return self.observation_json(player)
74
+
75
+ def observation_json(self, player: int) -> str:
76
+ del player
77
+ return self.to_json()
78
+
79
+ def __str__(self):
80
+ return self.to_json()
81
+
82
+
83
+ class GoGame(proxy.Game):
84
+ """Go game proxy."""
85
+
86
+ def __init__(self, params: Any | None = None):
87
+ params = params or {}
88
+ wrapped = pyspiel.load_game("go", params)
89
+ super().__init__(
90
+ wrapped,
91
+ short_name="go_proxy",
92
+ long_name="Go (proxy)",
93
+ )
94
+
95
+ def new_initial_state(self, *args) -> GoState:
96
+ return GoState(self.__wrapped__.new_initial_state(*args), game=self)
97
+
98
+
99
+ pyspiel.register_game(GoGame().get_type(), GoGame)