kaggle-environments 0.2.1__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 +295 -170
  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} +21 -14
  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 +340 -0
  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.1.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 -223
  210. kaggle_environments/temp.py +0 -14
  211. kaggle_environments-0.2.1.dist-info/METADATA +0 -393
  212. kaggle_environments-0.2.1.dist-info/RECORD +0 -32
  213. kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
  214. kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
  215. {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,1397 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Tic Tac Toe - Kaggle Environment"
8
+ ]
9
+ },
10
+ {
11
+ "cell_type": "code",
12
+ "execution_count": 10,
13
+ "metadata": {},
14
+ "outputs": [
15
+ {
16
+ "name": "stdout",
17
+ "output_type": "stream",
18
+ "text": [
19
+ "tictactoe 1.0.0\n",
20
+ "Default Agents: random reaction\n"
21
+ ]
22
+ }
23
+ ],
24
+ "source": [
25
+ "from kaggle_environments import make\n",
26
+ "\n",
27
+ "env = make(\"tictactoe\")\n",
28
+ "print(env.name, env.version)\n",
29
+ "print(\"Default Agents: \", *env.agents)"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "markdown",
34
+ "metadata": {},
35
+ "source": [
36
+ "## TLDR;"
37
+ ]
38
+ },
39
+ {
40
+ "cell_type": "code",
41
+ "execution_count": 2,
42
+ "metadata": {},
43
+ "outputs": [
44
+ {
45
+ "data": {
46
+ "text/html": [
47
+ "<iframe srcdoc=\"<!--\n",
48
+ " Copyright 2020 Kaggle Inc\n",
49
+ "\n",
50
+ " Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);\n",
51
+ " you may not use this file except in compliance with the License.\n",
52
+ " You may obtain a copy of the License at\n",
53
+ "\n",
54
+ " http://www.apache.org/licenses/LICENSE-2.0\n",
55
+ "\n",
56
+ " Unless required by applicable law or agreed to in writing, software\n",
57
+ " distributed under the License is distributed on an &quot;AS IS&quot; BASIS,\n",
58
+ " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
59
+ " See the License for the specific language governing permissions and\n",
60
+ " limitations under the License.\n",
61
+ "-->\n",
62
+ "<!DOCTYPE html>\n",
63
+ "<html lang=&quot;en&quot;>\n",
64
+ " <head>\n",
65
+ " <title>Kaggle Simulation Player</title>\n",
66
+ " <meta name=&quot;viewport&quot; content=&quot;width=device-width,initial-scale=1&quot; />\n",
67
+ " <link\n",
68
+ " rel=&quot;stylesheet&quot;\n",
69
+ " href=&quot;https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css&quot;\n",
70
+ " crossorigin=&quot;anonymous&quot;\n",
71
+ " />\n",
72
+ " <style type=&quot;text/css&quot;>\n",
73
+ " html,\n",
74
+ " body {\n",
75
+ " height: 100%;\n",
76
+ " font-family: sans-serif;\n",
77
+ " }\n",
78
+ " canvas {\n",
79
+ " position: absolute;\n",
80
+ " top: 0;\n",
81
+ " left: 0;\n",
82
+ " width: 100%;\n",
83
+ " height: 100%;\n",
84
+ " /* image-rendering: -moz-crisp-edges;\n",
85
+ " image-rendering: -webkit-crisp-edges;\n",
86
+ " image-rendering: pixelated;\n",
87
+ " image-rendering: crisp-edges; */\n",
88
+ " }\n",
89
+ " </style>\n",
90
+ " <script src=&quot;https://unpkg.com/preact@10.0.1/dist/preact.umd.js&quot;></script>\n",
91
+ " <script src=&quot;https://unpkg.com/preact@10.0.1/hooks/dist/hooks.umd.js&quot;></script>\n",
92
+ " <script src=&quot;https://unpkg.com/htm@2.2.1/dist/htm.umd.js&quot;></script>\n",
93
+ " <script>\n",
94
+ " // Polyfill for Styled Components\n",
95
+ " window.React = {\n",
96
+ " ...preact,\n",
97
+ " createElement: preact.h,\n",
98
+ " PropTypes: { func: {} },\n",
99
+ " };\n",
100
+ " </script>\n",
101
+ " <script src=&quot;https://unpkg.com/styled-components@3.5.0-0/dist/styled-components.min.js&quot;></script>\n",
102
+ " <link rel=&quot;canonical&quot; href=&quot;someurl&quot; />\n",
103
+ " </head>\n",
104
+ " <body>\n",
105
+ " <script>\n",
106
+ " \n",
107
+ "window.kaggle = {\n",
108
+ " &quot;debug&quot;: true,\n",
109
+ " &quot;autoplay&quot;: true,\n",
110
+ " &quot;step&quot;: 0,\n",
111
+ " &quot;controls&quot;: true,\n",
112
+ " &quot;environment&quot;: {\n",
113
+ " &quot;name&quot;: &quot;tictactoe&quot;,\n",
114
+ " &quot;title&quot;: &quot;Tic Tac Toe&quot;,\n",
115
+ " &quot;description&quot;: &quot;Classic Tic Tac Toe&quot;,\n",
116
+ " &quot;version&quot;: &quot;1.0.0&quot;,\n",
117
+ " &quot;configuration&quot;: {\n",
118
+ " &quot;steps&quot;: 10,\n",
119
+ " &quot;timeout&quot;: 2\n",
120
+ " },\n",
121
+ " &quot;specification&quot;: {\n",
122
+ " &quot;action&quot;: {\n",
123
+ " &quot;description&quot;: &quot;Position to place a mark on the board.&quot;,\n",
124
+ " &quot;type&quot;: &quot;integer&quot;,\n",
125
+ " &quot;minimum&quot;: 0,\n",
126
+ " &quot;maximum&quot;: 8,\n",
127
+ " &quot;default&quot;: 0\n",
128
+ " },\n",
129
+ " &quot;agents&quot;: [\n",
130
+ " 2\n",
131
+ " ],\n",
132
+ " &quot;configuration&quot;: {\n",
133
+ " &quot;steps&quot;: {\n",
134
+ " &quot;description&quot;: &quot;Maximum number of steps the environment can run.&quot;,\n",
135
+ " &quot;type&quot;: &quot;integer&quot;,\n",
136
+ " &quot;minimum&quot;: 10,\n",
137
+ " &quot;default&quot;: 10\n",
138
+ " },\n",
139
+ " &quot;timeout&quot;: {\n",
140
+ " &quot;description&quot;: &quot;Seconds an agent can run before timing out.&quot;,\n",
141
+ " &quot;type&quot;: &quot;integer&quot;,\n",
142
+ " &quot;minimum&quot;: 1,\n",
143
+ " &quot;default&quot;: 2\n",
144
+ " }\n",
145
+ " },\n",
146
+ " &quot;info&quot;: {},\n",
147
+ " &quot;observation&quot;: {\n",
148
+ " &quot;board&quot;: {\n",
149
+ " &quot;description&quot;: &quot;Serialized 3x3 grid. 0 = Empty, 1 = X, 2 = O&quot;,\n",
150
+ " &quot;type&quot;: &quot;array&quot;,\n",
151
+ " &quot;default&quot;: [\n",
152
+ " 0,\n",
153
+ " 0,\n",
154
+ " 0,\n",
155
+ " 0,\n",
156
+ " 0,\n",
157
+ " 0,\n",
158
+ " 0,\n",
159
+ " 0,\n",
160
+ " 0\n",
161
+ " ],\n",
162
+ " &quot;minItems&quot;: 9,\n",
163
+ " &quot;maxItems&quot;: 9\n",
164
+ " },\n",
165
+ " &quot;mark&quot;: {\n",
166
+ " &quot;description&quot;: &quot;Mark for the agent to use&quot;,\n",
167
+ " &quot;enum&quot;: [\n",
168
+ " 1,\n",
169
+ " 2\n",
170
+ " ]\n",
171
+ " }\n",
172
+ " },\n",
173
+ " &quot;reward&quot;: {\n",
174
+ " &quot;description&quot;: &quot;0 = Lost, 0.5 = Draw, 1 = Won&quot;,\n",
175
+ " &quot;enum&quot;: [\n",
176
+ " 0,\n",
177
+ " 0.5,\n",
178
+ " 1\n",
179
+ " ],\n",
180
+ " &quot;default&quot;: 0.5,\n",
181
+ " &quot;type&quot;: [\n",
182
+ " &quot;number&quot;,\n",
183
+ " &quot;null&quot;\n",
184
+ " ]\n",
185
+ " },\n",
186
+ " &quot;reset&quot;: {\n",
187
+ " &quot;status&quot;: [\n",
188
+ " &quot;ACTIVE&quot;,\n",
189
+ " &quot;INACTIVE&quot;\n",
190
+ " ],\n",
191
+ " &quot;observation&quot;: [\n",
192
+ " {\n",
193
+ " &quot;mark&quot;: 1\n",
194
+ " },\n",
195
+ " {\n",
196
+ " &quot;mark&quot;: 2\n",
197
+ " }\n",
198
+ " ],\n",
199
+ " &quot;reward&quot;: 0.5\n",
200
+ " }\n",
201
+ " },\n",
202
+ " &quot;steps&quot;: [\n",
203
+ " [\n",
204
+ " {\n",
205
+ " &quot;action&quot;: 0,\n",
206
+ " &quot;reward&quot;: 0.5,\n",
207
+ " &quot;info&quot;: {},\n",
208
+ " &quot;observation&quot;: {\n",
209
+ " &quot;board&quot;: [\n",
210
+ " 0,\n",
211
+ " 0,\n",
212
+ " 0,\n",
213
+ " 0,\n",
214
+ " 0,\n",
215
+ " 0,\n",
216
+ " 0,\n",
217
+ " 0,\n",
218
+ " 0\n",
219
+ " ],\n",
220
+ " &quot;mark&quot;: 1\n",
221
+ " },\n",
222
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
223
+ " },\n",
224
+ " {\n",
225
+ " &quot;action&quot;: 0,\n",
226
+ " &quot;reward&quot;: 0.5,\n",
227
+ " &quot;info&quot;: {},\n",
228
+ " &quot;observation&quot;: {\n",
229
+ " &quot;board&quot;: [\n",
230
+ " 0,\n",
231
+ " 0,\n",
232
+ " 0,\n",
233
+ " 0,\n",
234
+ " 0,\n",
235
+ " 0,\n",
236
+ " 0,\n",
237
+ " 0,\n",
238
+ " 0\n",
239
+ " ],\n",
240
+ " &quot;mark&quot;: 2\n",
241
+ " },\n",
242
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
243
+ " }\n",
244
+ " ],\n",
245
+ " [\n",
246
+ " {\n",
247
+ " &quot;action&quot;: 4,\n",
248
+ " &quot;reward&quot;: 0.5,\n",
249
+ " &quot;info&quot;: {},\n",
250
+ " &quot;observation&quot;: {\n",
251
+ " &quot;board&quot;: [\n",
252
+ " 0,\n",
253
+ " 0,\n",
254
+ " 0,\n",
255
+ " 0,\n",
256
+ " 1,\n",
257
+ " 0,\n",
258
+ " 0,\n",
259
+ " 0,\n",
260
+ " 0\n",
261
+ " ],\n",
262
+ " &quot;mark&quot;: 1\n",
263
+ " },\n",
264
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
265
+ " },\n",
266
+ " {\n",
267
+ " &quot;action&quot;: 0,\n",
268
+ " &quot;reward&quot;: 0.5,\n",
269
+ " &quot;info&quot;: {},\n",
270
+ " &quot;observation&quot;: {\n",
271
+ " &quot;board&quot;: [\n",
272
+ " 0,\n",
273
+ " 0,\n",
274
+ " 0,\n",
275
+ " 0,\n",
276
+ " 1,\n",
277
+ " 0,\n",
278
+ " 0,\n",
279
+ " 0,\n",
280
+ " 0\n",
281
+ " ],\n",
282
+ " &quot;mark&quot;: 2\n",
283
+ " },\n",
284
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
285
+ " }\n",
286
+ " ],\n",
287
+ " [\n",
288
+ " {\n",
289
+ " &quot;action&quot;: 0,\n",
290
+ " &quot;reward&quot;: 0.5,\n",
291
+ " &quot;info&quot;: {},\n",
292
+ " &quot;observation&quot;: {\n",
293
+ " &quot;board&quot;: [\n",
294
+ " 0,\n",
295
+ " 0,\n",
296
+ " 0,\n",
297
+ " 0,\n",
298
+ " 1,\n",
299
+ " 0,\n",
300
+ " 0,\n",
301
+ " 2,\n",
302
+ " 0\n",
303
+ " ],\n",
304
+ " &quot;mark&quot;: 1\n",
305
+ " },\n",
306
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
307
+ " },\n",
308
+ " {\n",
309
+ " &quot;action&quot;: 7,\n",
310
+ " &quot;reward&quot;: 0.5,\n",
311
+ " &quot;info&quot;: {},\n",
312
+ " &quot;observation&quot;: {\n",
313
+ " &quot;board&quot;: [\n",
314
+ " 0,\n",
315
+ " 0,\n",
316
+ " 0,\n",
317
+ " 0,\n",
318
+ " 1,\n",
319
+ " 0,\n",
320
+ " 0,\n",
321
+ " 2,\n",
322
+ " 0\n",
323
+ " ],\n",
324
+ " &quot;mark&quot;: 2\n",
325
+ " },\n",
326
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
327
+ " }\n",
328
+ " ],\n",
329
+ " [\n",
330
+ " {\n",
331
+ " &quot;action&quot;: 0,\n",
332
+ " &quot;reward&quot;: 0.5,\n",
333
+ " &quot;info&quot;: {},\n",
334
+ " &quot;observation&quot;: {\n",
335
+ " &quot;board&quot;: [\n",
336
+ " 1,\n",
337
+ " 0,\n",
338
+ " 0,\n",
339
+ " 0,\n",
340
+ " 1,\n",
341
+ " 0,\n",
342
+ " 0,\n",
343
+ " 2,\n",
344
+ " 0\n",
345
+ " ],\n",
346
+ " &quot;mark&quot;: 1\n",
347
+ " },\n",
348
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
349
+ " },\n",
350
+ " {\n",
351
+ " &quot;action&quot;: 0,\n",
352
+ " &quot;reward&quot;: 0.5,\n",
353
+ " &quot;info&quot;: {},\n",
354
+ " &quot;observation&quot;: {\n",
355
+ " &quot;board&quot;: [\n",
356
+ " 1,\n",
357
+ " 0,\n",
358
+ " 0,\n",
359
+ " 0,\n",
360
+ " 1,\n",
361
+ " 0,\n",
362
+ " 0,\n",
363
+ " 2,\n",
364
+ " 0\n",
365
+ " ],\n",
366
+ " &quot;mark&quot;: 2\n",
367
+ " },\n",
368
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
369
+ " }\n",
370
+ " ],\n",
371
+ " [\n",
372
+ " {\n",
373
+ " &quot;action&quot;: 0,\n",
374
+ " &quot;reward&quot;: 0.5,\n",
375
+ " &quot;info&quot;: {},\n",
376
+ " &quot;observation&quot;: {\n",
377
+ " &quot;board&quot;: [\n",
378
+ " 1,\n",
379
+ " 0,\n",
380
+ " 0,\n",
381
+ " 2,\n",
382
+ " 1,\n",
383
+ " 0,\n",
384
+ " 0,\n",
385
+ " 2,\n",
386
+ " 0\n",
387
+ " ],\n",
388
+ " &quot;mark&quot;: 1\n",
389
+ " },\n",
390
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
391
+ " },\n",
392
+ " {\n",
393
+ " &quot;action&quot;: 3,\n",
394
+ " &quot;reward&quot;: 0.5,\n",
395
+ " &quot;info&quot;: {},\n",
396
+ " &quot;observation&quot;: {\n",
397
+ " &quot;board&quot;: [\n",
398
+ " 1,\n",
399
+ " 0,\n",
400
+ " 0,\n",
401
+ " 2,\n",
402
+ " 1,\n",
403
+ " 0,\n",
404
+ " 0,\n",
405
+ " 2,\n",
406
+ " 0\n",
407
+ " ],\n",
408
+ " &quot;mark&quot;: 2\n",
409
+ " },\n",
410
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
411
+ " }\n",
412
+ " ],\n",
413
+ " [\n",
414
+ " {\n",
415
+ " &quot;action&quot;: 2,\n",
416
+ " &quot;reward&quot;: 0.5,\n",
417
+ " &quot;info&quot;: {},\n",
418
+ " &quot;observation&quot;: {\n",
419
+ " &quot;board&quot;: [\n",
420
+ " 1,\n",
421
+ " 0,\n",
422
+ " 1,\n",
423
+ " 2,\n",
424
+ " 1,\n",
425
+ " 0,\n",
426
+ " 0,\n",
427
+ " 2,\n",
428
+ " 0\n",
429
+ " ],\n",
430
+ " &quot;mark&quot;: 1\n",
431
+ " },\n",
432
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
433
+ " },\n",
434
+ " {\n",
435
+ " &quot;action&quot;: 0,\n",
436
+ " &quot;reward&quot;: 0.5,\n",
437
+ " &quot;info&quot;: {},\n",
438
+ " &quot;observation&quot;: {\n",
439
+ " &quot;board&quot;: [\n",
440
+ " 1,\n",
441
+ " 0,\n",
442
+ " 1,\n",
443
+ " 2,\n",
444
+ " 1,\n",
445
+ " 0,\n",
446
+ " 0,\n",
447
+ " 2,\n",
448
+ " 0\n",
449
+ " ],\n",
450
+ " &quot;mark&quot;: 2\n",
451
+ " },\n",
452
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
453
+ " }\n",
454
+ " ],\n",
455
+ " [\n",
456
+ " {\n",
457
+ " &quot;action&quot;: 0,\n",
458
+ " &quot;reward&quot;: 0.5,\n",
459
+ " &quot;info&quot;: {},\n",
460
+ " &quot;observation&quot;: {\n",
461
+ " &quot;board&quot;: [\n",
462
+ " 1,\n",
463
+ " 0,\n",
464
+ " 1,\n",
465
+ " 2,\n",
466
+ " 1,\n",
467
+ " 0,\n",
468
+ " 0,\n",
469
+ " 2,\n",
470
+ " 2\n",
471
+ " ],\n",
472
+ " &quot;mark&quot;: 1\n",
473
+ " },\n",
474
+ " &quot;status&quot;: &quot;ACTIVE&quot;\n",
475
+ " },\n",
476
+ " {\n",
477
+ " &quot;action&quot;: 8,\n",
478
+ " &quot;reward&quot;: 0.5,\n",
479
+ " &quot;info&quot;: {},\n",
480
+ " &quot;observation&quot;: {\n",
481
+ " &quot;board&quot;: [\n",
482
+ " 1,\n",
483
+ " 0,\n",
484
+ " 1,\n",
485
+ " 2,\n",
486
+ " 1,\n",
487
+ " 0,\n",
488
+ " 0,\n",
489
+ " 2,\n",
490
+ " 2\n",
491
+ " ],\n",
492
+ " &quot;mark&quot;: 2\n",
493
+ " },\n",
494
+ " &quot;status&quot;: &quot;INACTIVE&quot;\n",
495
+ " }\n",
496
+ " ],\n",
497
+ " [\n",
498
+ " {\n",
499
+ " &quot;action&quot;: 6,\n",
500
+ " &quot;reward&quot;: 1,\n",
501
+ " &quot;info&quot;: {},\n",
502
+ " &quot;observation&quot;: {\n",
503
+ " &quot;board&quot;: [\n",
504
+ " 1,\n",
505
+ " 0,\n",
506
+ " 1,\n",
507
+ " 2,\n",
508
+ " 1,\n",
509
+ " 0,\n",
510
+ " 1,\n",
511
+ " 2,\n",
512
+ " 2\n",
513
+ " ],\n",
514
+ " &quot;mark&quot;: 1\n",
515
+ " },\n",
516
+ " &quot;status&quot;: &quot;DONE&quot;\n",
517
+ " },\n",
518
+ " {\n",
519
+ " &quot;action&quot;: 0,\n",
520
+ " &quot;reward&quot;: 0,\n",
521
+ " &quot;info&quot;: {},\n",
522
+ " &quot;observation&quot;: {\n",
523
+ " &quot;board&quot;: [\n",
524
+ " 1,\n",
525
+ " 0,\n",
526
+ " 1,\n",
527
+ " 2,\n",
528
+ " 1,\n",
529
+ " 0,\n",
530
+ " 1,\n",
531
+ " 2,\n",
532
+ " 2\n",
533
+ " ],\n",
534
+ " &quot;mark&quot;: 2\n",
535
+ " },\n",
536
+ " &quot;status&quot;: &quot;DONE&quot;\n",
537
+ " }\n",
538
+ " ]\n",
539
+ " ],\n",
540
+ " &quot;rewards&quot;: [\n",
541
+ " 1,\n",
542
+ " 0\n",
543
+ " ],\n",
544
+ " &quot;statuses&quot;: [\n",
545
+ " &quot;DONE&quot;,\n",
546
+ " &quot;DONE&quot;\n",
547
+ " ],\n",
548
+ " &quot;schema_version&quot;: 1\n",
549
+ " },\n",
550
+ " &quot;mode&quot;: &quot;ipython&quot;\n",
551
+ "};\n",
552
+ "\n",
553
+ "\n",
554
+ "window.kaggle.renderer = // Copyright 2020 Kaggle Inc\n",
555
+ "//\n",
556
+ "// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);\n",
557
+ "// you may not use this file except in compliance with the License.\n",
558
+ "// You may obtain a copy of the License at\n",
559
+ "//\n",
560
+ "// http://www.apache.org/licenses/LICENSE-2.0\n",
561
+ "//\n",
562
+ "// Unless required by applicable law or agreed to in writing, software\n",
563
+ "// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,\n",
564
+ "// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
565
+ "// See the License for the specific language governing permissions and\n",
566
+ "// limitations under the License.\n",
567
+ "\n",
568
+ "function renderer({\n",
569
+ " parent,\n",
570
+ " step,\n",
571
+ " frame,\n",
572
+ " environment,\n",
573
+ " width = 400,\n",
574
+ " height = 400,\n",
575
+ "}) {\n",
576
+ " // Canvas Setup.\n",
577
+ " let canvas = parent.querySelector(&quot;canvas&quot;);\n",
578
+ " if (!canvas) {\n",
579
+ " canvas = document.createElement(&quot;canvas&quot;);\n",
580
+ " parent.appendChild(canvas);\n",
581
+ "\n",
582
+ " canvas.addEventListener(&quot;click&quot;, () => {\n",
583
+ " console.log(&quot;canvas click&quot;);\n",
584
+ " });\n",
585
+ " }\n",
586
+ "\n",
587
+ " // Common Dimensions.\n",
588
+ " const canvasSize = Math.min(height, width);\n",
589
+ " const unit = 8;\n",
590
+ " const offset = canvasSize > 400 ? canvasSize * 0.1 : unit / 2;\n",
591
+ " const cellSize = (canvasSize - offset * 2) / 3;\n",
592
+ "\n",
593
+ " // Canvas setup and reset.\n",
594
+ " const c = canvas.getContext(&quot;2d&quot;);\n",
595
+ " canvas.width = canvasSize;\n",
596
+ " canvas.height = canvasSize;\n",
597
+ " c.clearRect(0, 0, canvas.width, canvas.height);\n",
598
+ "\n",
599
+ " const drawStyle = ({\n",
600
+ " lineWidth = 1,\n",
601
+ " lineCap,\n",
602
+ " strokeStyle = &quot;#FFF&quot;,\n",
603
+ " shadow,\n",
604
+ " }) => {\n",
605
+ " c.lineWidth = lineWidth;\n",
606
+ " c.strokeStyle = strokeStyle;\n",
607
+ " if (lineCap) c.lineCap = lineCap;\n",
608
+ " if (shadow) {\n",
609
+ " c.shadowOffsetX = shadow.offsetX || 0;\n",
610
+ " c.shadowOffsetY = shadow.offsetY || 0;\n",
611
+ " c.shadowColor = shadow.color || strokeStyle;\n",
612
+ " c.shadowBlur = shadow.blur || 0;\n",
613
+ " }\n",
614
+ " };\n",
615
+ "\n",
616
+ " const drawLine = ({ x1, y1, x2, y2, style }) => {\n",
617
+ " c.beginPath();\n",
618
+ " drawStyle(style || {});\n",
619
+ " c.moveTo((x1 || 0) + offset, (y1 || 0) + offset);\n",
620
+ " c.lineTo((x2 || x1) + offset, (y2 || y1) + offset);\n",
621
+ " c.stroke();\n",
622
+ " };\n",
623
+ "\n",
624
+ " const drawArc = ({ x, y, radius, sAngle, eAngle, style }) => {\n",
625
+ " drawStyle(style || {});\n",
626
+ " c.beginPath();\n",
627
+ " c.arc(x, y, radius, sAngle, eAngle);\n",
628
+ " c.stroke();\n",
629
+ " };\n",
630
+ "\n",
631
+ " // Draw the Grid.\n",
632
+ " const gridFrame = step === 0 ? frame : 1;\n",
633
+ " const drawGridLine = ({\n",
634
+ " x1s = 0,\n",
635
+ " y1s = 0,\n",
636
+ " x2s,\n",
637
+ " y2s,\n",
638
+ " x1o = 0,\n",
639
+ " x2o = 0,\n",
640
+ " y1o = 0,\n",
641
+ " y2o = 0,\n",
642
+ " }) =>\n",
643
+ " drawLine({\n",
644
+ " x1: x1s * cellSize + x1o * unit,\n",
645
+ " x2: (x2s || x1s) * cellSize + x2o * unit,\n",
646
+ " y1: y1s * cellSize + y1o * unit,\n",
647
+ " y2: (y2s || y1s) * cellSize + y2o * unit,\n",
648
+ " style: { strokeStyle: &quot;#046BBF&quot; },\n",
649
+ " });\n",
650
+ "\n",
651
+ " // Vertical.\n",
652
+ " drawGridLine({ x1s: 1, y1s: 0, y2s: gridFrame, y2o: -1 });\n",
653
+ " drawGridLine({ x1s: 2, y1s: 0, y2s: gridFrame, y2o: -1 });\n",
654
+ " drawGridLine({ x1s: 1, y1s: 1, y2s: 1 + gridFrame, y1o: 1, y2o: -1 });\n",
655
+ " drawGridLine({ x1s: 2, y1s: 1, y2s: 1 + gridFrame, y1o: 1, y2o: -1 });\n",
656
+ " drawGridLine({ x1s: 1, y1s: 2, y2s: 2 + gridFrame, y1o: 1 });\n",
657
+ " drawGridLine({ x1s: 2, y1s: 2, y2s: 2 + gridFrame, y1o: 1 });\n",
658
+ "\n",
659
+ " // Horizontal.\n",
660
+ " drawGridLine({ x1s: 0, y1s: 1, x2s: gridFrame, x2o: -1 });\n",
661
+ " drawGridLine({ x1s: 1, y1s: 1, x2s: 1 + gridFrame, x1o: 1, x2o: -1 });\n",
662
+ " drawGridLine({ x1s: 2, y1s: 1, x2s: 2 + gridFrame, x1o: 1 });\n",
663
+ " drawGridLine({ x1s: 0, y1s: 2, x2s: gridFrame, x2o: -1 });\n",
664
+ " drawGridLine({ x1s: 1, y1s: 2, x2s: 1 + gridFrame, x1o: 1, x2o: -1 });\n",
665
+ " drawGridLine({ x1s: 2, y1s: 2, x2s: 2 + gridFrame, x1o: 1 });\n",
666
+ "\n",
667
+ " // Draw the Pieces.\n",
668
+ " const drawX = (cell, cellFrame) => {\n",
669
+ " const part = cellSize / 4;\n",
670
+ " const gap = Math.min(Math.sqrt((unit * unit) / 2), canvasSize / 50);\n",
671
+ " const row = Math.floor(cell / 3);\n",
672
+ " const col = cell % 3;\n",
673
+ "\n",
674
+ " const drawXLine = ({ x1, y1, x2, y2 }) =>\n",
675
+ " drawLine({\n",
676
+ " x1: col * cellSize + x1,\n",
677
+ " y1: row * cellSize + y1,\n",
678
+ " x2: col * cellSize + x2,\n",
679
+ " y2: row * cellSize + y2,\n",
680
+ " style: {\n",
681
+ " strokeStyle: &quot;#00FFFF&quot;,\n",
682
+ " lineWidth: 2,\n",
683
+ " lineCap: &quot;round&quot;,\n",
684
+ " shadow: { blur: 8 },\n",
685
+ " },\n",
686
+ " });\n",
687
+ "\n",
688
+ " drawXLine({\n",
689
+ " x1: part,\n",
690
+ " y1: part,\n",
691
+ " x2: part + part * 2 * cellFrame,\n",
692
+ " y2: part + part * 2 * cellFrame,\n",
693
+ " });\n",
694
+ " if (Math.round(cellFrame) === 1) {\n",
695
+ " drawXLine({\n",
696
+ " x1: part,\n",
697
+ " y1: part * 3,\n",
698
+ " x2: part * 2 - gap,\n",
699
+ " y2: part * 2 + gap,\n",
700
+ " });\n",
701
+ " drawXLine({\n",
702
+ " x1: part * 2 + gap,\n",
703
+ " y1: part * 2 - gap,\n",
704
+ " x2: part * 3,\n",
705
+ " y2: part,\n",
706
+ " });\n",
707
+ " }\n",
708
+ " };\n",
709
+ " const drawO = (cell, cellFrame) => {\n",
710
+ " const row = Math.floor(cell / 3);\n",
711
+ " const col = cell % 3;\n",
712
+ " const radius = cellSize / 4 + 1; // +1 is for optical illusion.\n",
713
+ " const gap =\n",
714
+ " (Math.acos((2 * (radius ^ 2) - (unit ^ 2)) / (2 * radius * radius)) /\n",
715
+ " 180) *\n",
716
+ " Math.PI *\n",
717
+ " unit;\n",
718
+ " const x = cellSize * col + cellSize / 2 + offset;\n",
719
+ " const y = cellSize * row + cellSize / 2 + offset;\n",
720
+ "\n",
721
+ " const drawOArc = (sAngle, eAngle) =>\n",
722
+ " drawArc({\n",
723
+ " x,\n",
724
+ " y,\n",
725
+ " radius,\n",
726
+ " sAngle,\n",
727
+ " eAngle,\n",
728
+ " style: {\n",
729
+ " lineWidth: 2,\n",
730
+ " strokeStyle: &quot;#FFF&quot;,\n",
731
+ " shadow: { blur: 8 },\n",
732
+ " },\n",
733
+ " });\n",
734
+ "\n",
735
+ " drawOArc(\n",
736
+ " -Math.PI / 2 + gap,\n",
737
+ " -Math.PI / 2 + gap + (Math.PI - gap * 2) * cellFrame\n",
738
+ " );\n",
739
+ " drawOArc(\n",
740
+ " Math.PI / 2 + gap,\n",
741
+ " Math.PI / 2 + gap + (Math.PI - gap * 2) * cellFrame\n",
742
+ " );\n",
743
+ " };\n",
744
+ "\n",
745
+ " const board = environment.steps[step][0].observation.board;\n",
746
+ "\n",
747
+ " board.forEach((value, cell) => {\n",
748
+ " const cellFrame =\n",
749
+ " step <= 1 ||\n",
750
+ " environment.steps[step - 1][0].observation.board[cell] !== value\n",
751
+ " ? frame\n",
752
+ " : 1;\n",
753
+ " if (value === 1) drawX(cell, cellFrame);\n",
754
+ " if (value === 2) drawO(cell, cellFrame);\n",
755
+ " });\n",
756
+ "\n",
757
+ " // Draw the winning line.\n",
758
+ " // [cell1, cell2, cell3, x1, y1, x2, y2]\n",
759
+ " const checks = [\n",
760
+ " [0, 1, 2, 1 / 19, 1 / 6, 18 / 19, 1 / 6],\n",
761
+ " [3, 4, 5, 1 / 19, 1 / 2, 18 / 19, 1 / 2],\n",
762
+ " [6, 7, 8, 1 / 19, 5 / 6, 18 / 19, 5 / 6],\n",
763
+ " [0, 3, 6, 1 / 6, 1 / 19, 1 / 6, 18 / 19],\n",
764
+ " [1, 4, 7, 1 / 2, 1 / 19, 1 / 2, 18 / 19],\n",
765
+ " [2, 5, 8, 5 / 6, 1 / 19, 5 / 6, 18 / 19],\n",
766
+ " [0, 4, 8, 1 / 19, 1 / 19, 18 / 19, 18 / 19],\n",
767
+ " [2, 4, 6, 18 / 19, 1 / 19, 1 / 19, 18 / 19],\n",
768
+ " ];\n",
769
+ " for (const check of checks) {\n",
770
+ " if (\n",
771
+ " board[check[0]] !== 0 &&\n",
772
+ " board[check[0]] === board[check[1]] &&\n",
773
+ " board[check[0]] === board[check[2]]\n",
774
+ " ) {\n",
775
+ " const x1 = check[3] * (cellSize * 3);\n",
776
+ " const y1 = check[4] * (cellSize * 3);\n",
777
+ " const winFrame = frame < 0.5 ? 0 : (frame - 0.5) / 0.5;\n",
778
+ " if (winFrame > 0) {\n",
779
+ " drawLine({\n",
780
+ " x1,\n",
781
+ " y1,\n",
782
+ " x2: x1 + (check[5] * (cellSize * 3) - x1) * winFrame,\n",
783
+ " y2: y1 + (check[6] * (cellSize * 3) - y1) * winFrame,\n",
784
+ " style: {\n",
785
+ " strokeStyle: &quot;#FFF&quot;,\n",
786
+ " lineWidth: 3 * winFrame,\n",
787
+ " shadow: { blur: 8 * winFrame },\n",
788
+ " },\n",
789
+ " });\n",
790
+ " }\n",
791
+ " break;\n",
792
+ " }\n",
793
+ " }\n",
794
+ "};\n",
795
+ "\n",
796
+ "\n",
797
+ " \n",
798
+ " </script>\n",
799
+ " <script>\n",
800
+ " const h = htm.bind(preact.h);\n",
801
+ " const { useContext, useEffect, useRef, useState } = preactHooks;\n",
802
+ " const styled = window.styled.default;\n",
803
+ "\n",
804
+ " const Context = preact.createContext({});\n",
805
+ "\n",
806
+ " const Loading = styled.div`\n",
807
+ " animation: rotate360 1.1s infinite linear;\n",
808
+ " border: 8px solid rgba(255, 255, 255, 0.2);\n",
809
+ " border-left-color: #0cb1ed;\n",
810
+ " border-radius: 50%;\n",
811
+ " height: 40px;\n",
812
+ " position: relative;\n",
813
+ " transform: translateZ(0);\n",
814
+ " width: 40px;\n",
815
+ "\n",
816
+ " @keyframes rotate360 {\n",
817
+ " 0% {\n",
818
+ " transform: rotate(0deg);\n",
819
+ " }\n",
820
+ " 100% {\n",
821
+ " transform: rotate(360deg);\n",
822
+ " }\n",
823
+ " }\n",
824
+ " `;\n",
825
+ "\n",
826
+ " const Logo = styled(\n",
827
+ " props => h`\n",
828
+ " <a href=&quot;https://kaggle.com&quot; target=&quot;_blank&quot; className=${props.className}>\n",
829
+ " <svg width=&quot;62px&quot; height=&quot;20px&quot; viewBox=&quot;0 0 62 24&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;>\n",
830
+ " <g fill=&quot;#1EBEFF&quot; fill-rule=&quot;nonzero&quot;>\n",
831
+ " <path d=&quot;M10.2,17.8c0,0.1-0.1,0.1-0.2,0.1H7.7c-0.1,0-0.3-0.1-0.4-0.2l-3.8-4.9l-1.1,1v3.8 c0,0.2-0.1,0.3-0.3,0.3H0.3c-0.2,0-0.3-0.1-0.3-0.3V0.3C0.1,0.1,0.2,0,0.3,0h1.8c0.2,0,0.3,0.1,0.3,0.3V11L7,6.3 c0.1-0.1,0.2-0.2,0.4-0.2h2.4c0.1,0,0.2,0,0.2,0.1c0,0.1,0,0.2,0,0.2l-4.9,4.7l5.1,6.3C10.2,17.6,10.2,17.7,10.2,17.8z&quot;/>\n",
832
+ " <path d=&quot;M19.6,17.9h-1.8c-0.2,0-0.3-0.1-0.3-0.3v-0.4c-0.8,0.6-1.8,0.9-3,0.9c-1.1,0-2-0.3-2.8-1 c-0.8-0.7-1.2-1.6-1.2-2.7c0-1.7,1.1-2.9,3.2-3.5c0.8-0.2,2.1-0.5,3.8-0.6c0.1-0.6-0.1-1.2-0.5-1.7c-0.4-0.5-1-0.7-1.7-0.7 c-1,0-2,0.4-3,1C12.2,9.1,12.1,9.1,12,9l-0.9-1.3C11,7.5,11,7.4,11.1,7.3c1.3-0.9,2.7-1.4,4.2-1.4c1.1,0,2.1,0.3,2.8,0.8 c1.1,0.8,1.7,2,1.7,3.7v7.3C19.9,17.8,19.8,17.9,19.6,17.9z M17.5,12.4c-1.7,0.2-2.9,0.4-3.5,0.7c-0.9,0.4-1.2,0.9-1.1,1.6 c0.1,0.4,0.2,0.7,0.6,0.9c0.3,0.2,0.7,0.4,1.1,0.4c1.2,0.1,2.2-0.2,2.9-1V12.4z&quot;/>\n",
833
+ " <path d=&quot;M30.6,22.5c-0.9,1-2.3,1.5-4,1.5c-1,0-2-0.3-2.9-0.8c-0.2-0.1-0.4-0.3-0.7-0.5 c-0.3-0.2-0.6-0.5-0.9-0.7c-0.1-0.1-0.1-0.2,0-0.4l1.2-1.2c0.1-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1c1,1,1.9,1.5,2.8,1.5 c2.1,0,3.2-1.1,3.2-3.3v-1.4c-0.8,0.7-1.9,1-3.3,1c-1.7,0-3-0.6-4-1.9c-0.8-1.1-1.3-2.5-1.3-4.2c0-1.6,0.4-3,1.2-4.1 c0.9-1.3,2.3-2,4-2c1.3,0,2.4,0.3,3.3,1V6.4c0-0.2,0.1-0.3,0.3-0.3h1.8c0.2,0,0.3,0.1,0.3,0.3v11.7C32,20,31.5,21.5,30.6,22.5z M29.7,9.9c-0.4-1.1-1.4-1.7-3-1.7c-2,0-3.1,1.3-3.1,3.8c0,1.4,0.3,2.4,1,3.1c0.5,0.5,1.2,0.8,2,0.8c1.6,0,2.7-0.6,3.1-1.7V9.9z&quot;/>\n",
834
+ " <path d=&quot;M42.9,22.5c-0.9,1-2.3,1.5-4,1.5c-1,0-2-0.3-2.9-0.8c-0.2-0.1-0.4-0.3-0.7-0.5 c-0.3-0.2-0.6-0.5-0.9-0.7c-0.1-0.1-0.1-0.2,0-0.4l1.2-1.2c0.1-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1c1,1,1.9,1.5,2.8,1.5 c2.1,0,3.2-1.1,3.2-3.3v-1.4c-0.8,0.7-1.9,1-3.3,1c-1.7,0-3-0.6-4-1.9c-0.8-1.1-1.3-2.5-1.3-4.2c0-1.6,0.4-3,1.2-4.1 c0.9-1.3,2.3-2,4-2c1.3,0,2.4,0.3,3.3,1V6.4c0-0.2,0.1-0.3,0.3-0.3H44c0.2,0,0.3,0.1,0.3,0.3v11.7C44.3,20,43.8,21.5,42.9,22.5z M42,9.9c-0.4-1.1-1.4-1.7-3-1.7c-2,0-3.1,1.3-3.1,3.8c0,1.4,0.3,2.4,1,3.1c0.5,0.5,1.2,0.8,2,0.8c1.6,0,2.7-0.6,3.1-1.7L42,9.9 L42,9.9z&quot;/>\n",
835
+ " <path d=&quot;M48.3,17.9h-1.8c-0.2,0-0.3-0.1-0.3-0.3V0.3c0-0.2,0.1-0.3,0.3-0.3h1.8c0.2,0,0.3,0.1,0.3,0.3 v17.3C48.5,17.8,48.5,17.9,48.3,17.9z&quot;/>\n",
836
+ " <path d=&quot;M61.4,12.6c0,0.2-0.1,0.3-0.3,0.3h-8.5c0.1,0.9,0.5,1.6,1.1,2.2c0.7,0.6,1.6,0.9,2.7,0.9 c1,0,1.8-0.3,2.6-0.8c0.2-0.1,0.3-0.1,0.4,0l1.2,1.3c0.1,0.1,0.1,0.3,0,0.4c-1.3,0.9-2.7,1.4-4.4,1.4c-1.8,0-3.3-0.6-4.4-1.8 c-1.1-1.2-1.7-2.7-1.7-4.5c0-1.7,0.6-3.2,1.7-4.4c1-1.1,2.4-1.6,4.1-1.6c1.6,0,2.9,0.6,4,1.7c1.1,1.2,1.6,2.6,1.5,4.4L61.4,12.6 z M58,8.7c-0.6-0.5-1.3-0.8-2.1-0.8c-0.8,0-1.5,0.3-2.1,0.8c-0.6,0.5-1,1.2-1.1,2H59C59,9.9,58.6,9.3,58,8.7z&quot;/>\n",
837
+ " </g>\n",
838
+ " </svg>\n",
839
+ " </a>\n",
840
+ " `\n",
841
+ " )`\n",
842
+ " display: inline-flex;\n",
843
+ " `;\n",
844
+ "\n",
845
+ " const Header = styled(props => {\n",
846
+ " const { environment } = useContext(Context);\n",
847
+ "\n",
848
+ " return h`<div className=${props.className} >\n",
849
+ " <${Logo} />\n",
850
+ " ${environment.title}\n",
851
+ " </div>`;\n",
852
+ " })`\n",
853
+ " align-items: center;\n",
854
+ " border-bottom: 4px solid #212121;\n",
855
+ " box-sizing: border-box;\n",
856
+ " color: #fff;\n",
857
+ " display: flex;\n",
858
+ " flex: 0 0 36px;\n",
859
+ " font-size: 14px;\n",
860
+ " justify-content: space-between;\n",
861
+ " padding: 0 8px;\n",
862
+ " width: 100%;\n",
863
+ " `;\n",
864
+ "\n",
865
+ " const Viewer = styled(props => {\n",
866
+ " const {\n",
867
+ " animate,\n",
868
+ " debug,\n",
869
+ " playing,\n",
870
+ " renderer,\n",
871
+ " step,\n",
872
+ " speed,\n",
873
+ " environment,\n",
874
+ " } = useContext(Context);\n",
875
+ " const ref = preact.createRef();\n",
876
+ " const stepRef = useRef(-1);\n",
877
+ " stepRef.current = step;\n",
878
+ "\n",
879
+ " useEffect(async () => {\n",
880
+ " if (!ref.current) return;\n",
881
+ "\n",
882
+ " const renderFrame = async (start, startStep, lastFrame) => {\n",
883
+ " if (startStep !== stepRef.current) return;\n",
884
+ " if (lastFrame === 1) {\n",
885
+ " if (!animate) return;\n",
886
+ " start = Date.now();\n",
887
+ " }\n",
888
+ " const frame =\n",
889
+ " playing || animate\n",
890
+ " ? Math.min((Date.now() - start) / speed, 1)\n",
891
+ " : 1;\n",
892
+ " try {\n",
893
+ " if (debug) console.time(&quot;render&quot;);\n",
894
+ " await renderer({\n",
895
+ " parent: ref.current,\n",
896
+ " environment,\n",
897
+ " step,\n",
898
+ " frame,\n",
899
+ " width: ref.current.clientWidth,\n",
900
+ " height: ref.current.clientHeight,\n",
901
+ " styled,\n",
902
+ " preact,\n",
903
+ " hooks: preactHooks,\n",
904
+ " });\n",
905
+ " } catch (e) {\n",
906
+ " console.log(\n",
907
+ " &quot;Frame:&quot;,\n",
908
+ " frame,\n",
909
+ " &quot;Step:&quot;,\n",
910
+ " step,\n",
911
+ " &quot;Environment:&quot;,\n",
912
+ " environment,\n",
913
+ " &quot;Error:&quot;,\n",
914
+ " e\n",
915
+ " );\n",
916
+ " } finally {\n",
917
+ " if (debug) console.timeEnd(&quot;render&quot;);\n",
918
+ " }\n",
919
+ " window.requestAnimationFrame(() =>\n",
920
+ " renderFrame(start, startStep, frame)\n",
921
+ " );\n",
922
+ " };\n",
923
+ "\n",
924
+ " await renderFrame(Date.now(), stepRef.current);\n",
925
+ " }, [ref.current, step]);\n",
926
+ "\n",
927
+ " return h`<div className=${props.className} ref=${ref} />`;\n",
928
+ " })`\n",
929
+ " align-items: center;\n",
930
+ " background-color: #000b2a;\n",
931
+ " background-image: radial-gradient(\n",
932
+ " circle closest-side,\n",
933
+ " #000b49,\n",
934
+ " #000b2a\n",
935
+ " );\n",
936
+ " box-sizing: border-box;\n",
937
+ " display: flex;\n",
938
+ " flex: 1;\n",
939
+ " justify-content: center;\n",
940
+ " overflow: auto;\n",
941
+ " position: relative;\n",
942
+ " width: 100%;\n",
943
+ " `;\n",
944
+ "\n",
945
+ " const StepInput = styled.input.attrs({\n",
946
+ " type: &quot;range&quot;,\n",
947
+ " })`\n",
948
+ " appearance: none;\n",
949
+ " background: rgba(255, 255, 255, 0.15);\n",
950
+ " border-radius: 2px;\n",
951
+ " display: block;\n",
952
+ " flex: 1;\n",
953
+ " height: 4px;\n",
954
+ " opacity: 0.8;\n",
955
+ " outline: none;\n",
956
+ " transition: opacity 0.2s;\n",
957
+ " width: 100%;\n",
958
+ "\n",
959
+ " &:hover {\n",
960
+ " opacity: 1;\n",
961
+ " }\n",
962
+ "\n",
963
+ " &::-webkit-slider-thumb {\n",
964
+ " appearance: none;\n",
965
+ " background: #1ebeff;\n",
966
+ " border-radius: 100%;\n",
967
+ " cursor: pointer;\n",
968
+ " height: 12px;\n",
969
+ " margin: 0;\n",
970
+ " position: relative;\n",
971
+ " width: 12px;\n",
972
+ "\n",
973
+ " &::after {\n",
974
+ " content: &quot;hello&quot;;\n",
975
+ " position: absolute;\n",
976
+ " top: 0px;\n",
977
+ " left: 0px;\n",
978
+ " width: 200px;\n",
979
+ " height: 8px;\n",
980
+ " background: green;\n",
981
+ " }\n",
982
+ " }\n",
983
+ " `;\n",
984
+ "\n",
985
+ " const PlayButton = styled.button`\n",
986
+ " align-items: center;\n",
987
+ " background: none;\n",
988
+ " border: none;\n",
989
+ " color: white;\n",
990
+ " cursor: pointer;\n",
991
+ " display: flex;\n",
992
+ " flex: 0 0 56px;\n",
993
+ " font-size: 20px;\n",
994
+ " height: 40px;\n",
995
+ " justify-content: center;\n",
996
+ " opacity: 0.8;\n",
997
+ " outline: none;\n",
998
+ " transition: opacity 0.2s;\n",
999
+ "\n",
1000
+ " &:hover {\n",
1001
+ " opacity: 1;\n",
1002
+ " }\n",
1003
+ " `;\n",
1004
+ "\n",
1005
+ " const StepCount = styled.span`\n",
1006
+ " align-items: center;\n",
1007
+ " color: white;\n",
1008
+ " display: flex;\n",
1009
+ " font-size: 14px;\n",
1010
+ " justify-content: center;\n",
1011
+ " opacity: 0.8;\n",
1012
+ " padding: 0 16px;\n",
1013
+ " pointer-events: none;\n",
1014
+ " `;\n",
1015
+ "\n",
1016
+ " const Controls = styled(props => {\n",
1017
+ " const { environment, pause, play, playing, setStep, step } = useContext(\n",
1018
+ " Context\n",
1019
+ " );\n",
1020
+ " const value = step + 1;\n",
1021
+ " const onClick = () => (playing ? pause() : play());\n",
1022
+ " const onInput = e => {\n",
1023
+ " pause();\n",
1024
+ " setStep(parseInt(e.target.value) - 1);\n",
1025
+ " };\n",
1026
+ "\n",
1027
+ " return h`\n",
1028
+ " <div className=${props.className}>\n",
1029
+ " <${PlayButton} onClick=${onClick}><svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24px&quot; height=&quot;24px&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;#FFFFFF&quot;>${\n",
1030
+ " playing\n",
1031
+ " ? h`<path d=&quot;M6 19h4V5H6v14zm8-14v14h4V5h-4z&quot;/><path d=&quot;M0 0h24v24H0z&quot; fill=&quot;none&quot;/>`\n",
1032
+ " : h`<path d=&quot;M8 5v14l11-7z&quot;/><path d=&quot;M0 0h24v24H0z&quot; fill=&quot;none&quot;/>`\n",
1033
+ " }</svg><//>\n",
1034
+ " <${StepInput} min=&quot;1&quot; max=${\n",
1035
+ " environment.steps.length\n",
1036
+ " } value=&quot;${value}&quot; onInput=${onInput} />\n",
1037
+ " <${StepCount}>${value} / ${environment.steps.length}<//>\n",
1038
+ " </div>\n",
1039
+ " `;\n",
1040
+ " })`\n",
1041
+ " align-items: center;\n",
1042
+ " border-top: 4px solid #212121;\n",
1043
+ " display: flex;\n",
1044
+ " flex: 0 0 44px;\n",
1045
+ " width: 100%;\n",
1046
+ " `;\n",
1047
+ "\n",
1048
+ " const Info = styled(props => {\n",
1049
+ " const {\n",
1050
+ " environment,\n",
1051
+ " playing,\n",
1052
+ " step,\n",
1053
+ " speed,\n",
1054
+ " animate,\n",
1055
+ " header,\n",
1056
+ " controls,\n",
1057
+ " settings,\n",
1058
+ " } = useContext(Context);\n",
1059
+ "\n",
1060
+ " return h`\n",
1061
+ " <div className=${props.className}>\n",
1062
+ " info:\n",
1063
+ " step(${step}),\n",
1064
+ " playing(${playing ? &quot;T&quot; : &quot;F&quot;}),\n",
1065
+ " speed(${speed}),\n",
1066
+ " animate(${animate ? &quot;T&quot; : &quot;F&quot;})\n",
1067
+ " </div>`;\n",
1068
+ " })`\n",
1069
+ " color: #888;\n",
1070
+ " font-family: monospace;\n",
1071
+ " font-size: 12px;\n",
1072
+ " `;\n",
1073
+ "\n",
1074
+ " const Settings = styled(props => {\n",
1075
+ " const { environment, pause, play, playing, setStep, step } = useContext(\n",
1076
+ " Context\n",
1077
+ " );\n",
1078
+ "\n",
1079
+ " return h`\n",
1080
+ " <div className=${props.className}>\n",
1081
+ " <${Info} />\n",
1082
+ " </div>\n",
1083
+ " `;\n",
1084
+ " })`\n",
1085
+ " background: #fff;\n",
1086
+ " border-top: 4px solid #212121;\n",
1087
+ " box-sizing: border-box;\n",
1088
+ " padding: 20px;\n",
1089
+ " width: 100%;\n",
1090
+ "\n",
1091
+ " h1 {\n",
1092
+ " font-size: 20px;\n",
1093
+ " }\n",
1094
+ " `;\n",
1095
+ "\n",
1096
+ " const Player = styled(props => {\n",
1097
+ " const context = useContext(Context);\n",
1098
+ " const { controls, header, loading, settings } = context;\n",
1099
+ " return h`\n",
1100
+ " <div className=${props.className}>\n",
1101
+ " ${loading && h`<${Loading} />`}\n",
1102
+ " ${!loading && header && h`<${Header} />`}\n",
1103
+ " ${!loading && h`<${Viewer} />`}\n",
1104
+ " ${!loading && controls && h`<${Controls} />`}\n",
1105
+ " ${!loading && settings && h`<${Settings} />`}\n",
1106
+ " </div>`;\n",
1107
+ " })`\n",
1108
+ " align-items: center;\n",
1109
+ " background: #212121;\n",
1110
+ " border: 4px solid #212121;\n",
1111
+ " box-sizing: border-box;\n",
1112
+ " display: flex;\n",
1113
+ " flex-direction: column;\n",
1114
+ " height: 100%;\n",
1115
+ " justify-content: center;\n",
1116
+ " position: relative;\n",
1117
+ " width: 100%;\n",
1118
+ " `;\n",
1119
+ "\n",
1120
+ " const App = () => {\n",
1121
+ " const renderCountRef = useRef(0);\n",
1122
+ " const [_, setRenderCount] = useState(0);\n",
1123
+ "\n",
1124
+ " const contextRef = useRef({\n",
1125
+ " animate: false,\n",
1126
+ " autoplay: false,\n",
1127
+ " controls: false,\n",
1128
+ " debug: false,\n",
1129
+ " header: window.innerHeight >= 600,\n",
1130
+ " loading: false,\n",
1131
+ " environment: { steps: [] },\n",
1132
+ " playing: false,\n",
1133
+ " renderer: () => &quot;DNE&quot;,\n",
1134
+ " settings: false,\n",
1135
+ " speed: 500,\n",
1136
+ " step: 0,\n",
1137
+ " });\n",
1138
+ "\n",
1139
+ " // Context helpers.\n",
1140
+ " const rerender = (contextRef.current.rerender = () =>\n",
1141
+ " setRenderCount((renderCountRef.current += 1)));\n",
1142
+ " const setStep = (contextRef.current.setStep = newStep => {\n",
1143
+ " contextRef.current.step = newStep;\n",
1144
+ " rerender();\n",
1145
+ " });\n",
1146
+ " const setPlaying = (contextRef.current.setPlaying = playing => {\n",
1147
+ " contextRef.current.playing = playing;\n",
1148
+ " rerender();\n",
1149
+ " });\n",
1150
+ " const pause = (contextRef.current.pause = () => setPlaying(false));\n",
1151
+ "\n",
1152
+ " const playNext = () => {\n",
1153
+ " const context = contextRef.current;\n",
1154
+ "\n",
1155
+ " if (\n",
1156
+ " context.playing &&\n",
1157
+ " context.step < context.environment.steps.length - 1\n",
1158
+ " ) {\n",
1159
+ " setStep(context.step + 1);\n",
1160
+ " play(true);\n",
1161
+ " } else {\n",
1162
+ " pause();\n",
1163
+ " }\n",
1164
+ " };\n",
1165
+ "\n",
1166
+ " const play = (contextRef.current.play = continuing => {\n",
1167
+ " const context = contextRef.current;\n",
1168
+ " if (context.playing && !continuing) return;\n",
1169
+ " if (!context.playing) setPlaying(true);\n",
1170
+ " if (\n",
1171
+ " !continuing &&\n",
1172
+ " context.step === context.environment.steps.length - 1\n",
1173
+ " ) {\n",
1174
+ " setStep(0);\n",
1175
+ " }\n",
1176
+ " setTimeout(playNext, context.speed);\n",
1177
+ " });\n",
1178
+ "\n",
1179
+ " const updateContext = o => {\n",
1180
+ " const context = contextRef.current;\n",
1181
+ " Object.assign(context, o, {\n",
1182
+ " environment: { ...context.environment, ...(o.environment || {}) },\n",
1183
+ " });\n",
1184
+ " rerender();\n",
1185
+ "\n",
1186
+ " // If autoplay, toggle to playing.\n",
1187
+ " if (context.autoplay) play();\n",
1188
+ " };\n",
1189
+ "\n",
1190
+ " // First time setup.\n",
1191
+ " useEffect(() => {\n",
1192
+ " // Timeout is used to ensure useEffect renders once.\n",
1193
+ " setTimeout(() => {\n",
1194
+ " // Initialize context with window.kaggle.\n",
1195
+ " updateContext(window.kaggle || {});\n",
1196
+ " // Listen for messages received to update the context.\n",
1197
+ " window.addEventListener(\n",
1198
+ " &quot;message&quot;,\n",
1199
+ " event => {\n",
1200
+ " // Ensure the environment names match before updating.\n",
1201
+ " try {\n",
1202
+ " if (\n",
1203
+ " event.data.environment.name ==\n",
1204
+ " contextRef.current.environment.name\n",
1205
+ " ) {\n",
1206
+ " updateContext(event.data);\n",
1207
+ " }\n",
1208
+ " } catch {}\n",
1209
+ " },\n",
1210
+ " false\n",
1211
+ " );\n",
1212
+ " }, 1);\n",
1213
+ " }, []);\n",
1214
+ "\n",
1215
+ " if (contextRef.current.debug) {\n",
1216
+ " console.log(&quot;context&quot;, contextRef.current);\n",
1217
+ " }\n",
1218
+ "\n",
1219
+ " return h`\n",
1220
+ " <${Context.Provider} value=${contextRef.current}>\n",
1221
+ " <${Player} />\n",
1222
+ " <//>`;\n",
1223
+ " };\n",
1224
+ "\n",
1225
+ " preact.render(h`<${App} />`, document.body);\n",
1226
+ " </script>\n",
1227
+ " </body>\n",
1228
+ "</html>\n",
1229
+ "\" width=\"300\" height=\"300\" frameborder=\"0\"></iframe> "
1230
+ ],
1231
+ "text/plain": [
1232
+ "<IPython.core.display.HTML object>"
1233
+ ]
1234
+ },
1235
+ "metadata": {},
1236
+ "output_type": "display_data"
1237
+ }
1238
+ ],
1239
+ "source": [
1240
+ "def agent(observation):\n",
1241
+ " board = observation.board\n",
1242
+ " play_order = [4, 0, 2, 6, 8, 1, 3, 5, 7]\n",
1243
+ " EMPTY = 0\n",
1244
+ " return [c for c in play_order if board[c] == EMPTY][0]\n",
1245
+ "\n",
1246
+ "\n",
1247
+ "env = make(\"tictactoe\", debug=True)\n",
1248
+ "\n",
1249
+ "# play agent above vs default random agent.\n",
1250
+ "env.run([agent, \"random\"])\n",
1251
+ "env.render(mode=\"ipython\")"
1252
+ ]
1253
+ },
1254
+ {
1255
+ "cell_type": "markdown",
1256
+ "metadata": {},
1257
+ "source": [
1258
+ "## Specification"
1259
+ ]
1260
+ },
1261
+ {
1262
+ "cell_type": "code",
1263
+ "execution_count": 3,
1264
+ "metadata": {
1265
+ "scrolled": false
1266
+ },
1267
+ "outputs": [
1268
+ {
1269
+ "name": "stdout",
1270
+ "output_type": "stream",
1271
+ "text": [
1272
+ "Observation: {\n",
1273
+ " \"board\": {\n",
1274
+ " \"default\": [\n",
1275
+ " 0,\n",
1276
+ " 0,\n",
1277
+ " 0,\n",
1278
+ " 0,\n",
1279
+ " 0,\n",
1280
+ " 0,\n",
1281
+ " 0,\n",
1282
+ " 0,\n",
1283
+ " 0\n",
1284
+ " ],\n",
1285
+ " \"description\": \"Serialized 3x3 grid. 0 = Empty, 1 = X, 2 = O\",\n",
1286
+ " \"maxItems\": 9,\n",
1287
+ " \"minItems\": 9,\n",
1288
+ " \"type\": \"array\"\n",
1289
+ " },\n",
1290
+ " \"mark\": {\n",
1291
+ " \"description\": \"Mark for the agent to use\",\n",
1292
+ " \"enum\": [\n",
1293
+ " 1,\n",
1294
+ " 2\n",
1295
+ " ]\n",
1296
+ " }\n",
1297
+ "}\n",
1298
+ "Action: {\n",
1299
+ " \"default\": 0,\n",
1300
+ " \"description\": \"Position to place a mark on the board.\",\n",
1301
+ " \"maximum\": 8,\n",
1302
+ " \"minimum\": 0,\n",
1303
+ " \"type\": \"integer\"\n",
1304
+ "}\n"
1305
+ ]
1306
+ }
1307
+ ],
1308
+ "source": [
1309
+ "import json\n",
1310
+ "\n",
1311
+ "print(\"Observation:\", json.dumps(env.specification.observation, indent=4, sort_keys=True))\n",
1312
+ "print(\"Action:\", json.dumps(env.specification.action, indent=4, sort_keys=True))"
1313
+ ]
1314
+ },
1315
+ {
1316
+ "cell_type": "markdown",
1317
+ "metadata": {},
1318
+ "source": [
1319
+ "## Training using Gym"
1320
+ ]
1321
+ },
1322
+ {
1323
+ "cell_type": "code",
1324
+ "execution_count": 9,
1325
+ "metadata": {},
1326
+ "outputs": [
1327
+ {
1328
+ "name": "stdout",
1329
+ "output_type": "stream",
1330
+ "text": [
1331
+ " X | X | O \n",
1332
+ "---+---+---\n",
1333
+ " X | O | \n",
1334
+ "---+---+---\n",
1335
+ " O | | \n"
1336
+ ]
1337
+ }
1338
+ ],
1339
+ "source": [
1340
+ "import gym\n",
1341
+ "\n",
1342
+ "from kaggle_environments import make\n",
1343
+ "\n",
1344
+ "\n",
1345
+ "class TicTacToe(gym.Env):\n",
1346
+ " def __init__(self):\n",
1347
+ " self.env = make(\"tictactoe\", debug=True)\n",
1348
+ " self.trainer = self.env.train([None, \"random\"])\n",
1349
+ "\n",
1350
+ " # Define required gym fields (examples):\n",
1351
+ " self.action_space = gym.spaces.Discrete(9)\n",
1352
+ " self.observation_space = gym.spaces.Discrete(27)\n",
1353
+ "\n",
1354
+ " def step(self, action):\n",
1355
+ " return self.trainer.step(action)\n",
1356
+ "\n",
1357
+ " def reset(self):\n",
1358
+ " return self.trainer.reset()\n",
1359
+ "\n",
1360
+ " def render(self, **kwargs):\n",
1361
+ " return self.env.render(**kwargs)\n",
1362
+ "\n",
1363
+ "\n",
1364
+ "env = TicTacToe()\n",
1365
+ "\n",
1366
+ "done = False\n",
1367
+ "obs = env.reset()\n",
1368
+ "while not done:\n",
1369
+ " # Choose first available empty cell as the action.\n",
1370
+ " action = [i for i in range(len(obs.board)) if obs.board[i] == 0][0]\n",
1371
+ " obs, reward, done, info = env.step(action)\n",
1372
+ "env.render()"
1373
+ ]
1374
+ }
1375
+ ],
1376
+ "metadata": {
1377
+ "kernelspec": {
1378
+ "display_name": "Python 3",
1379
+ "language": "python",
1380
+ "name": "python3"
1381
+ },
1382
+ "language_info": {
1383
+ "codemirror_mode": {
1384
+ "name": "ipython",
1385
+ "version": 3
1386
+ },
1387
+ "file_extension": ".py",
1388
+ "mimetype": "text/x-python",
1389
+ "name": "python",
1390
+ "nbconvert_exporter": "python",
1391
+ "pygments_lexer": "ipython3",
1392
+ "version": "3.7.6"
1393
+ }
1394
+ },
1395
+ "nbformat": 4,
1396
+ "nbformat_minor": 2
1397
+ }