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
@@ -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>
@@ -28,6 +28,7 @@
28
28
  body {
29
29
  height: 100%;
30
30
  font-family: sans-serif;
31
+ margin: 0px;
31
32
  }
32
33
  canvas {
33
34
  /* image-rendering: -moz-crisp-edges;
@@ -39,6 +40,7 @@
39
40
  <script src="https://unpkg.com/preact@10.0.1/dist/preact.umd.js"></script>
40
41
  <script src="https://unpkg.com/preact@10.0.1/hooks/dist/hooks.umd.js"></script>
41
42
  <script src="https://unpkg.com/htm@2.2.1/dist/htm.umd.js"></script>
43
+ <script src="https://unpkg.com/chess.js@0.12.0/chess.js"></script>
42
44
  <script>
43
45
  // Polyfill for Styled Components
44
46
  window.React = {
@@ -94,7 +96,7 @@
94
96
  </g>
95
97
  </svg>
96
98
  </a>
97
- `
99
+ `,
98
100
  )`
99
101
  display: inline-flex;
100
102
  `;
@@ -104,6 +106,7 @@
104
106
 
105
107
  return h`<div className=${props.className} >
106
108
  <${Logo} />
109
+ <span><b>Left / Right Arrow:</b> Increase / Decrease Step</span><span><b>0-9 Row Keys:</b> Playback Speed</span><span><b>Space:</b> Pause / Play</span>
107
110
  ${environment.title}
108
111
  </div>`;
109
112
  })`
@@ -121,44 +124,84 @@
121
124
 
122
125
  const Renderer = styled((props) => {
123
126
  const context = useContext(Context);
124
- const { animate, debug, playing, renderer, speed } = context;
125
- const ref = preact.createRef();
127
+ const { animate, debug, playing, renderer, speed, step } = context;
126
128
 
127
- useEffect(async () => {
128
- if (!ref.current) return;
129
+ const ref = useRef(null);
130
+ const animationFrameId = useRef();
129
131
 
130
- const renderFrame = async (start, step, lastFrame) => {
131
- if (step !== context.step) return;
132
- if (lastFrame === 1) {
133
- if (!animate) return;
132
+ useEffect(() => {
133
+ const element = ref.current;
134
+ if (!element) return;
135
+
136
+ // A single function to render a static frame (for resizes and step changes)
137
+ const renderStaticFrame = async () => {
138
+ if (!ref.current) return;
139
+ try {
140
+ // Pass a frame of 1 to indicate a final/static state
141
+ await renderer({
142
+ ...context,
143
+ frame: 1,
144
+ height: ref.current.clientHeight,
145
+ width: ref.current.clientWidth,
146
+ hooks: preactHooks,
147
+ parent: ref.current,
148
+ preact,
149
+ styled,
150
+ });
151
+ } catch (error) {
152
+ if (debug) console.error("Static render failed:", error);
153
+ }
154
+ };
155
+
156
+ // --- Resize Handling ---
157
+ const observer = new ResizeObserver(() => {
158
+ renderStaticFrame();
159
+ });
160
+ observer.observe(element);
161
+
162
+ // --- Animation Loop ---
163
+ let start = Date.now();
164
+ const renderAnimation = async () => {
165
+ // Stop the loop if the component unmounts or if animate is turned off
166
+ if (!ref.current || !animate) return;
167
+
168
+ const frame = Math.min((Date.now() - start) / speed, 1);
169
+ if (frame === 1) {
134
170
  start = Date.now();
135
171
  }
136
- const frame =
137
- playing || animate
138
- ? Math.min((Date.now() - start) / speed, 1)
139
- : 1;
172
+
140
173
  try {
141
- if (debug) console.time("render");
142
174
  await renderer({
143
175
  ...context,
144
176
  frame,
145
177
  height: ref.current.clientHeight,
178
+ width: ref.current.clientWidth,
146
179
  hooks: preactHooks,
147
180
  parent: ref.current,
148
181
  preact,
149
182
  styled,
150
- width: ref.current.clientWidth,
151
183
  });
152
184
  } catch (error) {
153
- if (debug) console.error(error);
154
- console.log({ ...context, frame, error });
155
- } finally {
156
- if (debug) console.timeEnd("render");
185
+ if (debug) console.error("Animation render failed:", error);
157
186
  }
158
- window.requestAnimationFrame(() => renderFrame(start, step, frame));
187
+
188
+ animationFrameId.current = requestAnimationFrame(renderAnimation);
159
189
  };
160
190
 
161
- await renderFrame(Date.now(), context.step);
191
+ // --- Initial Action ---
192
+ if (animate) {
193
+ // If animate is on, start the animation loop
194
+ renderAnimation();
195
+ } else {
196
+ // Otherwise, just render a single static frame for the current step
197
+ renderStaticFrame();
198
+ }
199
+
200
+ // --- Cleanup ---
201
+ return () => {
202
+ observer.disconnect();
203
+ cancelAnimationFrame(animationFrameId.current);
204
+ };
162
205
  }, [ref.current, context.step, context.renderer]);
163
206
 
164
207
  return h`<div className=${props.className} ref=${ref} />`;
@@ -196,12 +239,7 @@
196
239
  ${processing && h`<${Processing} />`}
197
240
  </div>`;
198
241
  })`
199
- background-color: #000b2a;
200
- background-image: radial-gradient(
201
- circle closest-side,
202
- #000b49,
203
- #000b2a
204
- );
242
+ background-color: #1c1d20;
205
243
  display: flex;
206
244
  flex: 1;
207
245
  overflow: hidden;
@@ -209,27 +247,46 @@
209
247
  width: 100%;
210
248
  `;
211
249
 
250
+ // Partitions the elements of arr into subarrays of max length num.
251
+ const groupIntoSets = (arr, num) => {
252
+ const sets = [];
253
+ arr.forEach((a) => {
254
+ if (sets.length === 0 || sets[sets.length - 1].length === num) {
255
+ sets.push([]);
256
+ }
257
+ sets[sets.length - 1].push(a);
258
+ });
259
+ return sets;
260
+ };
261
+
262
+ // Expects `width` input prop to set proper max-width for agent name span.
212
263
  const Legend = styled((props) => {
213
264
  const { agents, legend } = useContext(Context);
214
265
 
266
+ const agentPairs = groupIntoSets(
267
+ agents.sort((a, b) => a.index - b.index),
268
+ 2,
269
+ );
270
+
215
271
  return h`<div className=${props.className}>
216
- <ul>
217
- ${agents
218
- .sort((a, b) => a.index - b.index)
219
- .map(
220
- (a) =>
221
- h`<li key=${a.id} title="id: ${a.id}" style="color:${
222
- a.color || "#FFF"
223
- }">${a.image && h`<img src=${a.image} />`}<span>${
224
- a.name
225
- }</span></li>`
226
- )}
227
- </ul>
272
+ ${agentPairs.map(
273
+ (agentList) =>
274
+ h`<ul>
275
+ ${agentList.map(
276
+ (a) =>
277
+ h`<li key=${a.id} title="id: ${a.id}" style="color:${a.color || "#FFF"}">
278
+ ${a.image && h`<img src=${a.image} />`}
279
+ <span>${a.name}</span>
280
+ </li>`,
281
+ )}
282
+ </ul>`,
283
+ )}
228
284
  </div>`;
229
285
  })`
230
- background-color: #000b2a;
286
+ background-color: #1c1d20;
231
287
  font-family: sans-serif;
232
288
  font-size: 14px;
289
+ height: 48px;
233
290
  width: 100%;
234
291
 
235
292
  ul {
@@ -242,12 +299,11 @@
242
299
  li {
243
300
  align-items: center;
244
301
  display: inline-flex;
245
- padding: 8px;
246
302
  transition: color 1s;
247
303
  }
248
304
 
249
305
  span {
250
- max-width: 100px;
306
+ max-width: ${(p) => (p.width || 400) * 0.5 - 36}px;
251
307
  overflow: hidden;
252
308
  text-overflow: ellipsis;
253
309
  white-space: nowrap;
@@ -255,6 +311,7 @@
255
311
 
256
312
  img {
257
313
  height: 24px;
314
+ margin-left: 4px;
258
315
  margin-right: 4px;
259
316
  width: 24px;
260
317
  }
@@ -332,9 +389,8 @@
332
389
  `;
333
390
 
334
391
  const Controls = styled((props) => {
335
- const { environment, pause, play, playing, setStep, step } = useContext(
336
- Context
337
- );
392
+ const { environment, pause, play, playing, setStep, step } =
393
+ useContext(Context);
338
394
  const value = step + 1;
339
395
  const onClick = () => (playing ? pause() : play());
340
396
  const onInput = (e) => {
@@ -345,13 +401,11 @@
345
401
  return h`
346
402
  <div className=${props.className}>
347
403
  <${PlayButton} onClick=${onClick}><svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#FFFFFF">${
348
- playing
349
- ? h`<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/>`
350
- : h`<path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/>`
351
- }</svg><//>
352
- <${StepInput} min="1" max=${
353
- environment.steps.length
354
- } value="${value}" onInput=${onInput} />
404
+ playing
405
+ ? h`<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/>`
406
+ : h`<path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/>`
407
+ }</svg><//>
408
+ <${StepInput} min="1" max=${environment.steps.length} value="${value}" onInput=${onInput} />
355
409
  <${StepCount}>${value} / ${environment.steps.length}<//>
356
410
  </div>
357
411
  `;
@@ -390,9 +444,8 @@
390
444
  `;
391
445
 
392
446
  const Settings = styled((props) => {
393
- const { environment, pause, play, playing, setStep, step } = useContext(
394
- Context
395
- );
447
+ const { environment, pause, play, playing, setStep, step } =
448
+ useContext(Context);
396
449
 
397
450
  return h`
398
451
  <div className=${props.className}>
@@ -413,20 +466,20 @@
413
466
 
414
467
  const Player = styled((props) => {
415
468
  const context = useContext(Context);
416
- const { agents, controls, header, legend, loading, settings } = context;
469
+ const { agents, controls, header, legend, loading, settings, width } =
470
+ context;
417
471
  return h`
418
472
  <div className=${props.className}>
419
473
  ${loading && h`<${Loading} />`}
420
474
  ${!loading && header && h`<${Header} />`}
421
475
  ${!loading && h`<${Viewer} />`}
422
- ${!loading && agents.length > 0 && legend && h`<${Legend} />`}
476
+ ${!loading && legend && agents?.length > 0 && h`<${Legend} width=${width}/>`}
423
477
  ${!loading && controls && h`<${Controls} />`}
424
478
  ${!loading && settings && h`<${Settings} />`}
425
479
  </div>`;
426
480
  })`
427
481
  align-items: center;
428
482
  background: #212121;
429
- border: 4px solid #212121;
430
483
  box-sizing: border-box;
431
484
  display: flex;
432
485
  flex-direction: column;
@@ -434,20 +487,37 @@
434
487
  justify-content: center;
435
488
  position: relative;
436
489
  width: 100%;
490
+ &:not(.no-border) {
491
+ border: 4px solid #212121;
492
+ }
437
493
  `;
438
494
 
439
495
  const App = () => {
440
496
  const renderCountRef = useRef(0);
441
497
  const [_, setRenderCount] = useState(0);
442
498
 
499
+ // These are bindings to the 0-9 keys and are milliseconds of timeout per step
500
+ const speeds = [
501
+ 0,
502
+ 3000,
503
+ 1000,
504
+ 500,
505
+ 333, // Default
506
+ 200,
507
+ 100,
508
+ 50,
509
+ 25,
510
+ 10,
511
+ ];
512
+
443
513
  const contextRef = useRef({
444
514
  animate: false,
445
515
  agents: [],
446
- autoplay: false,
447
516
  controls: false,
448
517
  debug: false,
449
- environment: { steps: [] },
518
+ environment: { steps: [], info: {} },
450
519
  header: window.innerHeight >= 600,
520
+ height: window.innerHeight,
451
521
  interactive: false,
452
522
  legend: true,
453
523
  loading: false,
@@ -455,8 +525,9 @@
455
525
  processing: false,
456
526
  renderer: () => "DNE",
457
527
  settings: false,
458
- speed: 500,
528
+ speed: speeds[4],
459
529
  step: 0,
530
+ width: window.innerWidth,
460
531
  });
461
532
 
462
533
  // Context helpers.
@@ -505,9 +576,6 @@
505
576
  environment: { ...context.environment, ...(o.environment || {}) },
506
577
  });
507
578
  rerender();
508
-
509
- // If autoplay, toggle to playing.
510
- if (context.autoplay) play();
511
579
  };
512
580
 
513
581
  // First time setup.
@@ -516,6 +584,11 @@
516
584
  setTimeout(() => {
517
585
  // Initialize context with window.kaggle.
518
586
  updateContext(window.kaggle || {});
587
+
588
+ if (window.kaggle?.playing) {
589
+ play(true);
590
+ }
591
+
519
592
  // Listen for messages received to update the context.
520
593
  window.addEventListener(
521
594
  "message",
@@ -523,14 +596,66 @@
523
596
  // Ensure the environment names match before updating.
524
597
  try {
525
598
  if (
526
- event.data.environment.name ==
527
- contextRef.current.environment.name
599
+ event.data.environment?.name ==
600
+ contextRef.current.environment.name ||
601
+ (event.data.environment?.name &&
602
+ !contextRef.current.environment.name) ||
603
+ event.data.environment?.loading !==
604
+ contextRef.current.environment.loading
605
+ ) {
606
+ const nextContext = {
607
+ ...event.data,
608
+ environment: {
609
+ ...event.data.environment,
610
+ steps: event.data.environment?.steps ?? [],
611
+ },
612
+ };
613
+ if (
614
+ !nextContext.renderer ||
615
+ typeof nextContext.renderer !== "function"
616
+ ) {
617
+ nextContext.renderer = contextRef.current.renderer;
618
+ }
619
+ window.kaggle = nextContext;
620
+ updateContext(nextContext);
621
+ }
622
+ if (event.data.setSteps) {
623
+ const nextContext = {
624
+ ...(window.kaggle ?? {}),
625
+ environment: {
626
+ ...(window.kaggle?.environment ?? {}),
627
+ steps: event.data.setSteps,
628
+ },
629
+ };
630
+ if (
631
+ !nextContext.renderer ||
632
+ typeof nextContext.renderer !== "function"
633
+ ) {
634
+ nextContext.renderer = contextRef.current.renderer;
635
+ }
636
+
637
+ window.kaggle = nextContext;
638
+ updateContext(nextContext);
639
+ }
640
+
641
+ // Side load the renderer script if it is specified by the post message event and not already loaded.
642
+ const renderScriptId = "rendererScript";
643
+ if (
644
+ event.data.environment?.rendererUrl &&
645
+ !document.querySelector(`#${renderScriptId}`)
528
646
  ) {
529
- updateContext(event.data);
647
+ window.rendererUrl = event.data.environment?.rendererUrl;
648
+ const script = document.createElement("script");
649
+ script.id = renderScriptId;
650
+ script.onload = () => {
651
+ window.kaggle.renderer = window.renderer;
652
+ };
653
+ script.src = window.rendererUrl;
654
+ document.body.appendChild(script);
530
655
  }
531
656
  } catch {}
532
657
  },
533
- false
658
+ false,
534
659
  );
535
660
  // Listen for keyboard commands.
536
661
  window.addEventListener(
@@ -544,28 +669,35 @@
544
669
  environment,
545
670
  } = contextRef.current;
546
671
  const key = event.keyCode;
672
+ const zero_key = 48;
673
+ const nine_key = 57;
547
674
  if (
548
675
  interactive ||
549
676
  isInteractive() ||
550
- (key !== 32 && key !== 37 && key !== 39)
677
+ (key !== 32 &&
678
+ key !== 37 &&
679
+ key !== 39 &&
680
+ !(key >= zero_key && key <= nine_key))
551
681
  )
552
682
  return;
553
683
 
554
684
  if (key === 32) {
555
685
  playing ? pause() : play();
556
- } else if (event.keyCode === 39) {
686
+ } else if (key === 39) {
557
687
  contextRef.current.playing = false;
558
688
  if (step < environment.steps.length - 1) setStep(step + 1);
559
689
  rerender();
560
- } else if (event.keyCode === 37) {
690
+ } else if (key === 37) {
561
691
  contextRef.current.playing = false;
562
692
  if (step > 0) setStep(step - 1);
563
693
  rerender();
694
+ } else if (key >= zero_key && key <= nine_key) {
695
+ contextRef.current.speed = speeds[key - zero_key];
564
696
  }
565
697
  event.preventDefault();
566
698
  return false;
567
699
  },
568
- false
700
+ false,
569
701
  );
570
702
  }, 1);
571
703
  }, []);
@@ -637,7 +769,7 @@
637
769
 
638
770
  return h`
639
771
  <${Context.Provider} value=${contextRef.current}>
640
- <${Player} />
772
+ <${Player} className="${contextRef.current.environment.viewer ? "no-border" : ""}" />
641
773
  <//>`;
642
774
  };
643
775