kaggle-environments 0.2.1__py3-none-any.whl → 1.20.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +295 -170
- kaggle_environments/envs/cabt/cabt.js +164 -0
- kaggle_environments/envs/cabt/cabt.json +28 -0
- kaggle_environments/envs/cabt/cabt.py +186 -0
- kaggle_environments/envs/cabt/cg/__init__.py +0 -0
- kaggle_environments/envs/cabt/cg/cg.dll +0 -0
- kaggle_environments/envs/cabt/cg/game.py +75 -0
- kaggle_environments/envs/cabt/cg/libcg.so +0 -0
- kaggle_environments/envs/cabt/cg/sim.py +48 -0
- kaggle_environments/envs/cabt/test_cabt.py +120 -0
- kaggle_environments/envs/chess/chess.js +4289 -0
- kaggle_environments/envs/chess/chess.json +60 -0
- kaggle_environments/envs/chess/chess.py +4241 -0
- kaggle_environments/envs/chess/test_chess.py +60 -0
- kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
- kaggle_environments/envs/connectx/connectx.js +1 -1
- kaggle_environments/envs/connectx/connectx.json +15 -1
- kaggle_environments/envs/connectx/connectx.py +6 -23
- kaggle_environments/envs/connectx/test_connectx.py +70 -24
- kaggle_environments/envs/football/football.ipynb +75 -0
- kaggle_environments/envs/football/football.json +91 -0
- kaggle_environments/envs/football/football.py +277 -0
- kaggle_environments/envs/football/helpers.py +95 -0
- kaggle_environments/envs/football/test_football.py +360 -0
- kaggle_environments/envs/halite/__init__.py +0 -0
- kaggle_environments/envs/halite/halite.ipynb +44741 -0
- kaggle_environments/envs/halite/halite.js +199 -83
- kaggle_environments/envs/halite/halite.json +31 -18
- kaggle_environments/envs/halite/halite.py +164 -303
- kaggle_environments/envs/halite/helpers.py +720 -0
- kaggle_environments/envs/halite/test_halite.py +190 -0
- kaggle_environments/envs/hungry_geese/__init__.py +0 -0
- kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
- kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +21 -14
- kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
- kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
- kaggle_environments/envs/identity/identity.json +6 -5
- kaggle_environments/envs/identity/identity.py +15 -2
- kaggle_environments/envs/kore_fleets/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
- kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
- kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
- kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
- kaggle_environments/envs/lux_ai_2021/README.md +3 -0
- kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
- kaggle_environments/envs/lux_ai_2021/index.html +43 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
- kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
- kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
- kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
- kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
- kaggle_environments/envs/lux_ai_s3/README.md +21 -0
- kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
- kaggle_environments/envs/lux_ai_s3/index.html +42 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
- kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
- kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
- kaggle_environments/envs/mab/__init__.py +0 -0
- kaggle_environments/envs/mab/agents.py +12 -0
- kaggle_environments/envs/mab/mab.js +100 -0
- kaggle_environments/envs/mab/mab.json +74 -0
- kaggle_environments/envs/mab/mab.py +146 -0
- kaggle_environments/envs/open_spiel/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
- kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
- kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
- kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
- kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
- kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
- kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
- kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
- kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
- kaggle_environments/envs/open_spiel/observation.py +128 -0
- kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
- kaggle_environments/envs/open_spiel/proxy.py +138 -0
- kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
- kaggle_environments/envs/rps/__init__.py +0 -0
- kaggle_environments/envs/rps/agents.py +84 -0
- kaggle_environments/envs/rps/helpers.py +25 -0
- kaggle_environments/envs/rps/rps.js +117 -0
- kaggle_environments/envs/rps/rps.json +63 -0
- kaggle_environments/envs/rps/rps.py +90 -0
- kaggle_environments/envs/rps/test_rps.py +110 -0
- kaggle_environments/envs/rps/utils.py +7 -0
- kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
- kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
- kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
- kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
- kaggle_environments/errors.py +2 -4
- kaggle_environments/helpers.py +377 -0
- kaggle_environments/main.py +340 -0
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/METADATA +36 -114
- kaggle_environments-1.20.1.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.1.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -223
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.1.dist-info/RECORD +0 -32
- kaggle_environments-0.2.1.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.1.dist-info/top_level.txt +0 -1
- {kaggle_environments-0.2.1.dist-info → kaggle_environments-1.20.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
function renderer(options) {
|
|
2
|
+
const { environment, step, parent, width = 400, height = 400 } = options; // Chess-specific constants
|
|
3
|
+
|
|
4
|
+
const DEFAULT_NUM_ROWS = 8;
|
|
5
|
+
const DEFAULT_NUM_COLS = 8;
|
|
6
|
+
const PIECE_IMAGES_SRC = {
|
|
7
|
+
p: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKaSURBVGiB7Zo9axVBFIafNyYoGhSNYFDUoI1CGtEgooIo/oGAhWApWlhoivgLgp32tlqJBEEsBMXGr0ILkYiVhRaCICL4gUXisbi5QaIkOzvnzL25975wujnvnIezOzs7uzIzukl9rS6gtHrAna4ecKerB9zp6jrg/lZMKmknMAbsAF4DL83sa5HJzaxYACPAA8AWxSxwBVgdXYNKbS0lHQbuA4NLDJsBDpnZ96g6itzDkgaBGywNCzAKXI2spdSiNQnsqjj2nKR9UYWUAj4SPL6ySgGndmzFd/hn8PjKKgX8Jnh8ZZUCvpMw9jdwN6qQcGBJJ4GphJQ+YFrSlpB6IjcekvYAL1j++fs/PQaOm9msZ01hHZY0AExTDxbgKI3tpqvCOizpDHAz0+YXsN3MPjuUBMTewxcdPNYA5x18FhQCLGkDcMDJ7oSTDxDX4ar75ira7egVBrzN0WtYkrzMooDfOnrNmOPKGgJsZu+AT052z518gNhV+qmTzzMnHyAW+JGDxxzwxMFnQZHA12lsD3N02cw+eBSzoOBTymHgI/+eUlaJmxE1Re6l1wIXgE01LY5JOuVYUkNBnd0LvKdeZxfHPRzPqyNgtzrCNuMW8y86bQUMrAdeOcM241pbAQMDwMMg2GZMtBPwVDCs0TjvGms5MI1TjS8FgA24nVOr12PpLLDRyWs5jUuq/cqYDSypH7iU65OgPmCidrbD5XyaMpfy3/EDGGrVJT3p4JGq5i4uWVnAkkYI/PC1jMbrJOV2+GBmfo5GJa1LTVrJwKuA/alJucCjmfm5Sp4/F3goMz9XyfP3gBO1OTM/V8nz1wae/zqYvEo6K3k7m/Pr4RytewY39S01odifeO2irvubtgfc6eoBd7q6DvgP/gH4mMhDFawAAAAASUVORK5CYII=',
|
|
8
|
+
r: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJSSURBVGiB7ZqxixNBFMa/b/HOFBGbSDRgoRCQK01IndrG1j/BI0QQ7JLG2sIg5AQ7QbCystByIYVFKq1sUh0kmyKolWE37rPwxDOG252ZzcabnR+8YsObt+/bmXkzO1mKCIqEt+sE8sYJth0n2HacYNtxgm1HWzDJEsn3JGWDHZGkgr+Q/ETyyob7HJKM0/onIiJaBqANQM6wq4r+AuD+hvsEKv5JdkH5CaXnLslvp64PUrRpkry39lspw5y22sN5mHIPu6JlO+ddMJNd/sZE8CXf97VrgKnN53N4nnddNWnqnniQ3G+1Wp9rtdoNrQCGLBaLr6PR6KaIfFFqaPKUAewBeIH8q/M7AJd1ctbu4dOQfADgab/f95rNpnG8TUynU3Q6HYjIAMAjEfmhEyeTjYeIPCO5H0XRk+VymUXIfwjDECLySkQeGgXKqoggn42I8kbDbTx2nUDeOMG24wTbjhNsO06w7TjBtuME206WB/EXG40G6vV6hiH/EAQBfN8vGwfK8H34te/7si1ms5mQ/GicZ0ZibwEIkc951h2TXI2HNMlSpVJ5MxgM9spl8xF3FnEco9frvSR5W0SOdWJkMYffrlargzAMsa3zrN9EUYQwDCsAPpCsi8h31RjGp5YkAwBVoyB6XBORQLVR4Zalwgk2nsPVatVrt9tY+8Jhq4zHY0wmE73GGkvQIYAYJ8tEt9s1X2QVGQ6H60vVEU7qUZIpF60dFqkkUhWxws1hJ9h2dAQ/xq9C8T/xHMA8jWMm/w+fJ9yQth0n2HacYNspnOCf287BmtabMhEAAAAASUVORK5CYII=',
|
|
9
|
+
b: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAARpSURBVGiB7Zo/bFtVFMZ/x7EhUdN2cFSkDMSCdEnKgkSH0IAZACkgAgpL2yhCDGz8UZNgRYINhpQgQAgQIwNiARRRJJOJAVhAuEhtBUIijhpRZJyAGpw4jRMfhmcjU/XZ78XnvbhuPunIkt/1ud/ne8699517RVW5lRDZawJhY19wu2NfcLtjTwSLSEJEBkUk9P5D7VBEhkXkZyALXATyIvJcmBxQ1VAMuB8oAXoDS4XFQ8LaeIjIRWDQ5XEJSKjqlaB5hBLSItKLu1iAGPBgGFzCyuHbPbTpDJwFIQlW1Szwe4Nm34XBJcxZ+qU6z95T1V/DIBGm4C+Bj3Fm5Vr8CMyGxiKE5agTOAP8wY2XJAWKwDtAb+B8AhZ7J3C+jtDr7W/g4ZtSMHACyPkQW7Vt4PmbSjDwLHBtF2Jr7UOgo+UFA48A5SbFVu31lhYM9ABXGgmZnZ3VdDqtkUikkeAdYLiVBc97GblsNquqqn19fV5GeQk4bMXRbB0WkceAUY9t//fZAH3AK7smdh2iVo6A024PRISpqSkGB533h56eHgDm5uYoFAqsr68zMzPD2tqam4uTIvKyVsKoKRiFchfwDy5hGY/HdXt7W+thbGysUWifsOBqNcKPAt1uD1dXV0kmk/T39wPOyMbjcaanp1lZWSGfz5NOpxv18TTwbdNMjUb4DD6Wm6WlJVVVTSQSfpaoL1pp0rrNT+OtrS0AyuVyYH24wSqkY34ap1IpBgYGWF5eDqwPVxiF9DPY7Kzq2UetFNLncDb9QWLewomJYFVdBb628OWCIrBg4ciy4nEW56UhCLypqhsmnizyoiaXp7HP3XNAxIyjpeCK6LNAaWhoSHO5nG5ubvqyjY0NnZycrIr9Cjhkyc9yL11FCjja2dn5ZDwep6Ojw9ePVZVoNAqwCJxSVdcN9m5gftQiIi8CbwNEo9Eqec8ol8v/bUyAeVV9ypSgcTjfjTOjWubwaUuO1nXpUeyPTE5aOjPN4fHx8dGRkREiEbv/MZPJPCQiola5ZxjOsYWFhS01RrFY1O7u7geseFqOcGxiYiKWTCa9lm48IZPJUCgUDlj5M52lRSSPU7m0xjFVvWThyHrS+tzYH8AlwO5k0So3KpESAV6gTn3Lh5WBDzDeaQVyx0NEDgKP49ShhnHC3EtirwEXgM+AT1XVV4XAE7fdChZnZuoFjuBUI2rtQOX7OyqfvTiHa0dc3G3gFOiywJ8VywFXcS681NpV4LKqlnbF26tgETkOPAHcC9wFJPB2dyMI7OBcoVgEfgLeVdVFT7/0kJeHgE8IvoTTjJWAV6kMYF09DcR2Ad+0gCCvlgbizQh+vwVE+LXzzey0Cg2e+8VvwA/A9zhL133AceAYdvv6Qr29d8NJS0ROAW/gzLwXgF+AyzWWw1lyokBHxQRnYqnaNpBT1b9c+ujCOSWs9VH9A2p97AAHK22rdhS4BzgMvAW8pqrXXPUEsQ7vBby+UbWNYK/YvxHf7tgX3O645QT/Cym/GLJbVZClAAAAAElFTkSuQmCC',
|
|
10
|
+
q: 'data:image/png;base64,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',
|
|
11
|
+
N: 'data:image/png;base64,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',
|
|
12
|
+
K: 'data:image/png;base64,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',
|
|
13
|
+
P: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASLSURBVGiB7ZrLS2NnGIefL6YJEuM4GaOiUvDCgJIKI0Y7KFJ3BSm00j9gil1ULbRi+1cUV92U7gahSLvUzeAiVG3QCoOggxmvgRlRY2uKSLSivl3oV2JJgyfnYrw8EDgh3+X35P3ycc7JUSLCXcJ13QGc5l74tnMvfNu5F77t3Dlh93VMqpQKAmGgEVgGfheRbUcmFxHHXkAx8CMgGV4/AaV2Z1BOnVoqpaqAKPCux+Ohra2NUChELBZjZmaGw8NDgF2gXURWbAviYHVfANLS0iJLS0uSTjwel87OTl3pKFBgWw6HZD8BJBAIyNbWlmQimUxKZWWllv7MrixO7dIdAAMDA1RUVGRsUFJSwtDQ0KX2duCU8BOAcDictVHa50/sCuKUcArg5OQka6PT01N9eGRXEKeEXwFMTExkbRSJRPRhzLYkDm1a7wPi8XgkHo9n3LR2d3fF7/frTevDG7tpKaUeA88BPB4P8Xg8Y7u3b9/idv974veDUsqe37HNlS0GXgMSCoUkFotlrK5mY2NDwuGwrvImUGZ5JpuFfwakqalJDg4Osspqjo6OpKOjQ0tP3Bhhzi8MpKioSNbW1q4kq0kkElJaWqqlO6zMZedv+EuA3t5eamtrDXUMBoP09/frt19ZmsrGCq8DMj8/b6i6ms3NTV3hPStz2XK1pJRyA0cul6sglUrh9XpzGicQCJBMJgECIpK0IptdS7oMKCgpKclZFs6FL6iyIhRg65L+A5CNjY2clvTe3p4opQQ4BgqtymXnpjUDMD09nVPnaDSqv7iXInJoVSg7haMAk5OTOXWemprSh79ZlOccG5d0OyBer1dmZ2cNLedYLCbFxcV6l/7I0lx2CV9Ifw9IdXW17OzsXEl2f39fGhoatOwvlmeyWdgNRADp7OyU4+PjrLJnZ2fS09OjZReBohsjzPn+8AXwJyBut1vGxsayCkejUfF6vVr4L+BrwJ33wsBDYPYiuHR1dcni4mJWWc3q6qp0d3en369eACryVhjwAr8CUlVVJaOjo1cS/S/j4+NSV1enpV8C/rwTBhQwqjeqN2/e5CSrSSQSUl9fr6VfAO/km/B3gDx48EAWFhZMyWpWV1elrKxMSz/PG2Ggh4v7VpFIxBJZzdzcnPh8Pi39eb4IzwEyPDxsqaxmZGREC78GXNcqDHzAxV8pV72VY5STkxOpqanR0h/nmtWqc+lv4PyvFJ/PZ9GQlykoKGBwcPDSfDlhQXUbgbPCwkJJJBK2VFdzcHAggUBAV/npdVV4CFDPnj0jGAxaMNz/4/P56Ovr02+/zWkQCyq8A8jy8rKt1dVsb2+Ly+US4G/AazivSdk6QCorKx2R1TQ2Nupl3WY0s9kl/RSgtbXV5DDGSJuvzWhfs8LvATQ3N5scxhhp84WM9jUrXApQXl5uchhjpM33yGhfs8KP4NLtVEdIm8+wsKkb8UqpaaC9trYWv9+f8zhGSaVSrKysALwSEUPL2uyTeA8B1tfXTQ5jbn4jmBX+lPML/usi+0MjGXDsSbx84c49TXsvfNu5F77t3DnhfwDnGIncxPZT9AAAAABJRU5ErkJggg==',
|
|
14
|
+
R: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMiSURBVGiB7ZqxTxNRHMc/P2jC2dDCYmhtB8cuJgQaWQwFRx1kdHAQHCr/ghOyMLAQBnRhI4Q4MTBoTEzYJDQhONIOGG3aktCQGHFo6HOAMyBX2nv3oHq9T/JLmrv3fvf73nv37t7vV1FK0Ul0tTuAmyYQ7HcCwX4nEOx3AsF+R1uwiFgi8l5ElIMtiYi4aK9E5IuI3Ha4zrSI1Ftt3xSllJYBY4C6wmIu2yvgpcN1ym7aNzPPUzqTyVxwODAwYJ96IiJPbQMeOrVXSpHNZu0+6fN9zvpZAKVSyam9a0LaPRvQ399PpVIBeNvo/BXHXpzZBXp6erAsy0h8xgWvr68zOztLvV6/dM6yLObn5y8dn5mZ4fj4mIODA0efU1NTjjdKB+OCU6kUq6urrvpYlsXi4qLpUBzxLLhcLrO2tmYilpbZ29vT7+xhlX5G81X3um3Zbdyim/EQkTCQB+6Ew2HGx8fp7e3V8tUqtVqNzc1NDg8PAX4AQ0qpgisnuiN8dqP6gM+ASiaTKp/Pq+vi6OhIjYyM2CO7D9zViVl7hG1EpA/4AIwkk0nm5uYIhYyvhSwsLLC1tQXwFRhTSu3r+PEsGP6I/hSNRoeGh4fPf3wYoVqtsru7S6VSKQIPdMUC3qb0X9P7MaAymYzx6ZzNZu2p/MprnCZ3Sz8N+mpE1auDYHvodwLBficQ7HcCwX4nEOx3AsF+p+MEm9yp9wDs7OwwMTFh0C3kcjn7Z8SrL5OCnwOk02kmJycNuoVIJMLKygqcJg4vJ7bdYGjznwJqXV1dant723gCoFQqqWg0aicBHnmJ1fMIi4gFvANCg4ODFAoFCgV3icRWGB0dZWNjA2BZRO4rpb5pOTIwuh+54Xy0iHwHbrVlhIF7AIlEgu7ubgPurqZYLHJycpLgNEX8y21/Y4tWLpcjFouZcteQWCxmVye16Lj3cMcJ1lmkpoE67S+knbclzooKzcx15UFEyoDZ0oIZ4kqpcrNG2lP6/H8u2mluyzod9wxrv5bi8bjJOG4MnRF+zelC8S/xBmjp5WykXPo/0XHPcCDY7wSC/U4g2O/8BtFWHbaczITCAAAAAElFTkSuQmCC',
|
|
15
|
+
B: 'data:image/png;base64,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',
|
|
16
|
+
Q: 'data:image/png;base64,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',
|
|
17
|
+
n: 'data:image/png;base64,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',
|
|
18
|
+
k: 'data:image/png;base64,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'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const LIGHT_SQUARE_COLOR = '#f0d9b5';
|
|
22
|
+
const DARK_SQUARE_COLOR = '#b58863';
|
|
23
|
+
|
|
24
|
+
let currentBoardElement = null;
|
|
25
|
+
let currentStatusTextElement = null;
|
|
26
|
+
let currentWinnerTextElement = null;
|
|
27
|
+
let currentMessageBoxElement = typeof document !== 'undefined' ? document.getElementById('messageBox') : null;
|
|
28
|
+
let currentRendererContainer = null;
|
|
29
|
+
let currentBoardContainer = null;
|
|
30
|
+
let currentTitleElement = null;
|
|
31
|
+
let squareSize = 0;
|
|
32
|
+
|
|
33
|
+
function _showMessage(message, type = 'info', duration = 3000) {
|
|
34
|
+
if (typeof document === 'undefined' || !document.body) return;
|
|
35
|
+
if (!currentMessageBoxElement) {
|
|
36
|
+
currentMessageBoxElement = document.createElement('div');
|
|
37
|
+
currentMessageBoxElement.id = 'messageBox';
|
|
38
|
+
Object.assign(currentMessageBoxElement.style, {
|
|
39
|
+
position: 'fixed',
|
|
40
|
+
top: '10px',
|
|
41
|
+
left: '50%',
|
|
42
|
+
transform: 'translateX(-50%)',
|
|
43
|
+
padding: '0.75rem 1rem',
|
|
44
|
+
borderRadius: '0.375rem',
|
|
45
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
46
|
+
zIndex: '1000',
|
|
47
|
+
opacity: '0',
|
|
48
|
+
transition: 'opacity 0.3s ease-in-out, background-color 0.3s',
|
|
49
|
+
fontSize: '0.875rem',
|
|
50
|
+
fontFamily: "'Inter', sans-serif",
|
|
51
|
+
color: 'white'
|
|
52
|
+
});
|
|
53
|
+
document.body.appendChild(currentMessageBoxElement);
|
|
54
|
+
}
|
|
55
|
+
currentMessageBoxElement.textContent = message;
|
|
56
|
+
currentMessageBoxElement.style.backgroundColor = type === 'error' ? '#ef4444' : '#10b981';
|
|
57
|
+
currentMessageBoxElement.style.opacity = '1';
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
if (currentMessageBoxElement) currentMessageBoxElement.style.opacity = '0';
|
|
60
|
+
}, duration);
|
|
61
|
+
}
|
|
62
|
+
function _ensureRendererElements(parentElementToClear, rows, cols) {
|
|
63
|
+
if (!parentElementToClear) return false;
|
|
64
|
+
parentElementToClear.innerHTML = '';
|
|
65
|
+
|
|
66
|
+
// NEW: Check for mobile screen size to apply responsive styles.
|
|
67
|
+
const isMobile = window.innerWidth < 768;
|
|
68
|
+
|
|
69
|
+
currentRendererContainer = document.createElement('div');
|
|
70
|
+
Object.assign(currentRendererContainer.style, {
|
|
71
|
+
display: 'flex',
|
|
72
|
+
flexDirection: 'column',
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
padding: isMobile ? '10px' : '20px', // Responsive padding
|
|
75
|
+
boxSizing: 'border-box',
|
|
76
|
+
width: '100%',
|
|
77
|
+
height: '100%',
|
|
78
|
+
fontFamily: "'Inter', sans-serif"
|
|
79
|
+
});
|
|
80
|
+
parentElementToClear.appendChild(currentRendererContainer);
|
|
81
|
+
|
|
82
|
+
if (!environment.viewer) {
|
|
83
|
+
const headerContainer = document.createElement('div');
|
|
84
|
+
Object.assign(headerContainer.style, {
|
|
85
|
+
display: 'flex',
|
|
86
|
+
justifyContent: 'center',
|
|
87
|
+
alignItems: 'center',
|
|
88
|
+
width: '100%',
|
|
89
|
+
marginBottom: '1rem',
|
|
90
|
+
color: 'white',
|
|
91
|
+
flexShrink: '0',
|
|
92
|
+
flexDirection: isMobile ? 'column' : 'row' // Stacks header vertically on mobile
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Player 2 (White) - Left side
|
|
96
|
+
const whitePlayerContainer = document.createElement('div');
|
|
97
|
+
Object.assign(whitePlayerContainer.style, {
|
|
98
|
+
display: 'flex',
|
|
99
|
+
alignItems: 'center'
|
|
100
|
+
});
|
|
101
|
+
const whitePawnImg = document.createElement('img');
|
|
102
|
+
whitePawnImg.src = PIECE_IMAGES_SRC.P;
|
|
103
|
+
Object.assign(whitePawnImg.style, { height: '30px', marginRight: '8px' });
|
|
104
|
+
const whitePlayerName = document.createElement('span');
|
|
105
|
+
whitePlayerName.textContent = environment.info?.TeamNames?.[1] || 'Player 2';
|
|
106
|
+
Object.assign(whitePlayerName.style, {
|
|
107
|
+
fontSize: isMobile ? '1rem' : '1.1rem', // Responsive font size
|
|
108
|
+
fontWeight: 'bold'
|
|
109
|
+
});
|
|
110
|
+
whitePlayerContainer.appendChild(whitePawnImg);
|
|
111
|
+
whitePlayerContainer.appendChild(whitePlayerName);
|
|
112
|
+
|
|
113
|
+
// Center Title
|
|
114
|
+
currentTitleElement = document.createElement('h1');
|
|
115
|
+
currentTitleElement.textContent = 'Chess';
|
|
116
|
+
Object.assign(currentTitleElement.style, {
|
|
117
|
+
fontSize: isMobile ? '1.5rem' : '1.875rem', // Responsive font size
|
|
118
|
+
fontWeight: 'bold',
|
|
119
|
+
textAlign: 'center',
|
|
120
|
+
color: '#e5e7eb',
|
|
121
|
+
margin: isMobile ? '10px 0' : '0 40px', // Responsive margin
|
|
122
|
+
order: isMobile ? '0' : 'initial' // Ensures title is between players on desktop
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Player 1 (Black) - Right side
|
|
126
|
+
const blackPlayerContainer = document.createElement('div');
|
|
127
|
+
Object.assign(blackPlayerContainer.style, {
|
|
128
|
+
display: 'flex',
|
|
129
|
+
alignItems: 'center'
|
|
130
|
+
});
|
|
131
|
+
const blackPlayerName = document.createElement('span');
|
|
132
|
+
blackPlayerName.textContent = environment.info?.TeamNames?.[0] || 'Player 1';
|
|
133
|
+
Object.assign(blackPlayerName.style, {
|
|
134
|
+
fontSize: isMobile ? '1rem' : '1.1rem', // Responsive font size
|
|
135
|
+
fontWeight: 'bold'
|
|
136
|
+
});
|
|
137
|
+
const blackPawnImg = document.createElement('img');
|
|
138
|
+
blackPawnImg.src = PIECE_IMAGES_SRC.p;
|
|
139
|
+
Object.assign(blackPawnImg.style, { height: '30px', marginLeft: '8px' });
|
|
140
|
+
blackPlayerContainer.appendChild(blackPlayerName);
|
|
141
|
+
blackPlayerContainer.appendChild(blackPawnImg);
|
|
142
|
+
|
|
143
|
+
// Assemble the header - order matters for mobile stacking
|
|
144
|
+
if (isMobile) {
|
|
145
|
+
// On mobile: White Player, then Black Player, then Title for a "vs" feel
|
|
146
|
+
headerContainer.appendChild(whitePlayerContainer);
|
|
147
|
+
const vsText = document.createElement('div');
|
|
148
|
+
vsText.textContent = 'vs';
|
|
149
|
+
Object.assign(vsText.style, { margin: '4px 0', fontStyle: 'italic' });
|
|
150
|
+
headerContainer.appendChild(vsText);
|
|
151
|
+
headerContainer.appendChild(blackPlayerContainer);
|
|
152
|
+
// Title is not added here for mobile to keep it separate or could be added last
|
|
153
|
+
} else {
|
|
154
|
+
// On desktop: White Player, Title, Black Player
|
|
155
|
+
headerContainer.appendChild(whitePlayerContainer);
|
|
156
|
+
headerContainer.appendChild(currentTitleElement);
|
|
157
|
+
headerContainer.appendChild(blackPlayerContainer);
|
|
158
|
+
}
|
|
159
|
+
currentRendererContainer.appendChild(headerContainer);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ... (The rest of the function for the board and status container remains the same, but let's add responsive fonts to the status)
|
|
163
|
+
|
|
164
|
+
// Board container...
|
|
165
|
+
currentBoardContainer = document.createElement('div');
|
|
166
|
+
Object.assign(currentBoardContainer.style, {
|
|
167
|
+
display: 'flex',
|
|
168
|
+
justifyContent: 'center',
|
|
169
|
+
alignItems: 'center',
|
|
170
|
+
flexGrow: '1',
|
|
171
|
+
width: '100%',
|
|
172
|
+
minHeight: '0'
|
|
173
|
+
});
|
|
174
|
+
currentRendererContainer.appendChild(currentBoardContainer);
|
|
175
|
+
|
|
176
|
+
// ... code to create board and squares ...
|
|
177
|
+
currentBoardElement = document.createElement('div');
|
|
178
|
+
Object.assign(currentBoardElement.style, {
|
|
179
|
+
display: 'grid',
|
|
180
|
+
border: '2px solid #333'
|
|
181
|
+
});
|
|
182
|
+
currentBoardContainer.appendChild(currentBoardElement);
|
|
183
|
+
for (let r = 0; r < rows; r++) {
|
|
184
|
+
for (let c = 0; c < cols; c++) {
|
|
185
|
+
const square = document.createElement('div');
|
|
186
|
+
square.id = `cell-${r}-${c}`;
|
|
187
|
+
Object.assign(square.style, {
|
|
188
|
+
backgroundColor: (r + c) % 2 === 0 ? LIGHT_SQUARE_COLOR : DARK_SQUARE_COLOR,
|
|
189
|
+
display: 'flex',
|
|
190
|
+
alignItems: 'center',
|
|
191
|
+
justifyContent: 'center'
|
|
192
|
+
});
|
|
193
|
+
currentBoardElement.appendChild(square);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Status Container
|
|
198
|
+
const statusContainer = document.createElement('div');
|
|
199
|
+
Object.assign(statusContainer.style, {
|
|
200
|
+
padding: '5px',
|
|
201
|
+
backgroundColor: 'white',
|
|
202
|
+
borderRadius: '8px',
|
|
203
|
+
boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06)',
|
|
204
|
+
textAlign: 'center',
|
|
205
|
+
width: 'auto',
|
|
206
|
+
minWidth: '200px',
|
|
207
|
+
maxWidth: '90vw',
|
|
208
|
+
marginTop: '10px',
|
|
209
|
+
flexShrink: '0'
|
|
210
|
+
});
|
|
211
|
+
if (!environment.viewer) {
|
|
212
|
+
currentRendererContainer.appendChild(statusContainer);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
currentStatusTextElement = document.createElement('p');
|
|
216
|
+
Object.assign(currentStatusTextElement.style, {
|
|
217
|
+
fontSize: isMobile ? '0.8rem' : '1.1rem', // Responsive font size
|
|
218
|
+
fontWeight: '600',
|
|
219
|
+
margin: '0 0 5px 0'
|
|
220
|
+
});
|
|
221
|
+
statusContainer.appendChild(currentStatusTextElement);
|
|
222
|
+
|
|
223
|
+
currentWinnerTextElement = document.createElement('p');
|
|
224
|
+
Object.assign(currentWinnerTextElement.style, {
|
|
225
|
+
fontSize: isMobile ? '0.9rem' : '1.1rem', // Responsive font size
|
|
226
|
+
fontWeight: '700',
|
|
227
|
+
margin: '5px 0 0 0'
|
|
228
|
+
});
|
|
229
|
+
statusContainer.appendChild(currentWinnerTextElement);
|
|
230
|
+
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function _getTeamNameForColor(color, teamNames) {
|
|
235
|
+
if (!teamNames || teamNames.length < 2) return null;
|
|
236
|
+
return color.toLowerCase() === 'white' ? teamNames[1] : teamNames[0];
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function _deriveWinnerFromRewards(currentStepAgents, teamNames) {
|
|
240
|
+
if (!currentStepAgents || currentStepAgents.length < 2) return null;
|
|
241
|
+
|
|
242
|
+
const player0Reward = currentStepAgents[0].reward;
|
|
243
|
+
const player1Reward = currentStepAgents[1].reward;
|
|
244
|
+
|
|
245
|
+
if (player0Reward === player1Reward) {
|
|
246
|
+
return 'draw';
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const winnerPlayerIndex = player0Reward === 1 ? 0 : 1;
|
|
250
|
+
const color = winnerPlayerIndex === 0 ? 'Black' : 'White';
|
|
251
|
+
|
|
252
|
+
if (teamNames) {
|
|
253
|
+
const teamName = _getTeamNameForColor(color, teamNames);
|
|
254
|
+
return `${color} (${teamName})`;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return color.toLowerCase();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function _parseFen(fen) {
|
|
261
|
+
if (!fen || typeof fen !== 'string') return null;
|
|
262
|
+
|
|
263
|
+
const [piecePlacement, activeColor, castling, enPassant, halfmoveClock, fullmoveNumber] = fen.split(' ');
|
|
264
|
+
const board = [];
|
|
265
|
+
const rows = piecePlacement.split('/');
|
|
266
|
+
|
|
267
|
+
for (const row of rows) {
|
|
268
|
+
const boardRow = [];
|
|
269
|
+
for (const char of row) {
|
|
270
|
+
if (isNaN(parseInt(char))) {
|
|
271
|
+
boardRow.push(char);
|
|
272
|
+
} else {
|
|
273
|
+
for (let i = 0; i < parseInt(char); i++) {
|
|
274
|
+
boardRow.push(null);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
board.push(boardRow);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
board,
|
|
283
|
+
activeColor,
|
|
284
|
+
castling,
|
|
285
|
+
enPassant,
|
|
286
|
+
halfmoveClock,
|
|
287
|
+
fullmoveNumber
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function _renderBoardDisplay(gameStateToDisplay, displayRows, displayCols) {
|
|
292
|
+
if (!currentBoardContainer || !currentBoardElement || !currentStatusTextElement || !currentWinnerTextElement)
|
|
293
|
+
return;
|
|
294
|
+
|
|
295
|
+
const isMobile = window.innerWidth < 768;
|
|
296
|
+
|
|
297
|
+
// Calculate and apply board size
|
|
298
|
+
const containerWidth = currentBoardContainer?.clientWidth ?? width;
|
|
299
|
+
const containerHeight = currentBoardContainer?.clientHeight ?? height;
|
|
300
|
+
let smallestContainerEdge = Math.min(containerWidth, containerHeight);
|
|
301
|
+
// This is greedily trying to take as much space as possible, which can cause some conflict with flex box calculations for other elements
|
|
302
|
+
// we are going to take 24px off (arbitrary) to give the flex box renderer a bit of space to work with. Without it we will get some clipping.
|
|
303
|
+
smallestContainerEdge = smallestContainerEdge > 200 ? smallestContainerEdge - 24 : smallestContainerEdge;
|
|
304
|
+
const newSquareSize = Math.floor(smallestContainerEdge / displayCols);
|
|
305
|
+
|
|
306
|
+
if (newSquareSize !== squareSize) {
|
|
307
|
+
squareSize = newSquareSize;
|
|
308
|
+
Object.assign(currentBoardElement.style, {
|
|
309
|
+
gridTemplateColumns: `repeat(${displayCols}, ${squareSize}px)`,
|
|
310
|
+
gridTemplateRows: `repeat(${displayRows}, ${squareSize}px)`,
|
|
311
|
+
width: `${displayCols * squareSize}px`,
|
|
312
|
+
height: `${displayRows * squareSize}px`
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const squares = currentBoardElement.querySelectorAll('div[id^="cell-"]');
|
|
316
|
+
squares.forEach((square) => {
|
|
317
|
+
Object.assign(square.style, {
|
|
318
|
+
width: `${squareSize}px`,
|
|
319
|
+
height: `${squareSize}px`
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Clear and render board pieces...
|
|
325
|
+
for (let r = 0; r < displayRows; r++) {
|
|
326
|
+
for (let c = 0; c < displayCols; c++) {
|
|
327
|
+
const squareElement = currentBoardElement.querySelector(`#cell-${r}-${c}`);
|
|
328
|
+
if (squareElement) squareElement.innerHTML = '';
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (!gameStateToDisplay || !gameStateToDisplay.board) {
|
|
333
|
+
currentStatusTextElement.textContent = 'Waiting for game data...';
|
|
334
|
+
currentWinnerTextElement.textContent = '';
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const { board, activeColor, isTerminal, winner } = gameStateToDisplay;
|
|
339
|
+
const pieceSize = Math.floor(squareSize * 0.9);
|
|
340
|
+
for (let r_data = 0; r_data < displayRows; r_data++) {
|
|
341
|
+
for (let c_data = 0; c_data < displayCols; c_data++) {
|
|
342
|
+
const piece = board[r_data][c_data];
|
|
343
|
+
const squareElement = currentBoardElement.querySelector(`#cell-${r_data}-${c_data}`);
|
|
344
|
+
if (squareElement && piece) {
|
|
345
|
+
const pieceImg = document.createElement('img');
|
|
346
|
+
pieceImg.src = PIECE_IMAGES_SRC[piece];
|
|
347
|
+
pieceImg.style.width = `${pieceSize}px`;
|
|
348
|
+
pieceImg.style.height = `${pieceSize}px`;
|
|
349
|
+
squareElement.appendChild(pieceImg);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Render status text
|
|
355
|
+
currentStatusTextElement.innerHTML = '';
|
|
356
|
+
currentWinnerTextElement.innerHTML = '';
|
|
357
|
+
if (isTerminal) {
|
|
358
|
+
const winnerText = winner
|
|
359
|
+
? String(winner).toLowerCase() === 'draw'
|
|
360
|
+
? "It's a Draw!"
|
|
361
|
+
: winner
|
|
362
|
+
: 'Game ended.';
|
|
363
|
+
if (isMobile) {
|
|
364
|
+
currentStatusTextElement.innerHTML = `<div style="font-size: 0.9rem; color: #666;">Winner</div>`;
|
|
365
|
+
currentWinnerTextElement.innerHTML = `<div style="font-size: 1.1rem; font-weight: bold;">${winnerText}</div>`;
|
|
366
|
+
} else {
|
|
367
|
+
currentStatusTextElement.textContent = 'Game Over!';
|
|
368
|
+
currentWinnerTextElement.innerHTML = `Winner: <span style="font-weight: bold;">${winnerText}</span>`;
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
const playerColor = String(activeColor).toLowerCase() === 'w' ? 'White' : 'Black';
|
|
372
|
+
const teamName = _getTeamNameForColor(playerColor, environment.info?.TeamNames);
|
|
373
|
+
const currentPlayerText = teamName ? `${playerColor} (${teamName})` : playerColor;
|
|
374
|
+
|
|
375
|
+
if (isMobile) {
|
|
376
|
+
currentStatusTextElement.innerHTML = `<div style="font-size: 0.9rem; color: #666;">Current Player</div>`;
|
|
377
|
+
currentWinnerTextElement.innerHTML = `<div style="font-size: 1.1rem; font-weight: bold;">${currentPlayerText}</div>`;
|
|
378
|
+
} else {
|
|
379
|
+
currentStatusTextElement.innerHTML = `Current Player: <span style="font-weight: bold;">${currentPlayerText}</span>`;
|
|
380
|
+
currentWinnerTextElement.innerHTML = ''; // Clear winner text when game is active
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (!_ensureRendererElements(parent, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS)) {
|
|
386
|
+
if (parent && typeof parent.innerHTML !== 'undefined') {
|
|
387
|
+
parent.innerHTML =
|
|
388
|
+
"<p style='color:red; font-family: sans-serif;'>Critical Error: Renderer element setup failed.</p>";
|
|
389
|
+
}
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (!environment || !environment.steps || !environment.steps[step]) {
|
|
394
|
+
_renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
|
|
395
|
+
if (currentStatusTextElement) currentStatusTextElement.textContent = 'Initializing environment...';
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const currentStepAgents = environment.steps[step];
|
|
400
|
+
if (!currentStepAgents || !Array.isArray(currentStepAgents) || currentStepAgents.length === 0) {
|
|
401
|
+
_renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
|
|
402
|
+
if (currentStatusTextElement) currentStatusTextElement.textContent = 'Waiting for agent data...';
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const agent = currentStepAgents[0];
|
|
407
|
+
|
|
408
|
+
if (!agent || typeof agent.observation === 'undefined') {
|
|
409
|
+
_renderBoardDisplay(null, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
|
|
410
|
+
if (currentStatusTextElement) currentStatusTextElement.textContent = 'Waiting for observation data...';
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const observationForRenderer = agent.observation;
|
|
414
|
+
|
|
415
|
+
let gameSpecificState = null;
|
|
416
|
+
|
|
417
|
+
if (
|
|
418
|
+
observationForRenderer &&
|
|
419
|
+
typeof observationForRenderer.observationString === 'string' &&
|
|
420
|
+
observationForRenderer.observationString.trim() !== ''
|
|
421
|
+
) {
|
|
422
|
+
try {
|
|
423
|
+
const fen = observationForRenderer.observationString;
|
|
424
|
+
const parsedFen = _parseFen(fen);
|
|
425
|
+
if (parsedFen) {
|
|
426
|
+
const winner = observationForRenderer.isTerminal
|
|
427
|
+
? _deriveWinnerFromRewards(currentStepAgents, environment.info?.TeamNames)
|
|
428
|
+
: null;
|
|
429
|
+
gameSpecificState = {
|
|
430
|
+
...parsedFen,
|
|
431
|
+
isTerminal: observationForRenderer.isTerminal,
|
|
432
|
+
winner: winner
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
} catch (e) {
|
|
436
|
+
_showMessage('Error: Corrupted game state (obs_string).', 'error');
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
_renderBoardDisplay(gameSpecificState, DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
|
|
441
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{"color": "green", "pieceSet": "caliente"}
|
|
2
|
+
{"color": "blue", "pieceSet": "cardinal"}
|
|
3
|
+
{"color": "brown", "pieceSet": "cburnett"}
|
|
4
|
+
{"color": "brown", "pieceSet": "celtic"}
|
|
5
|
+
{"color": "ic", "pieceSet": "chessnut"}
|
|
6
|
+
{"color": "ic", "pieceSet": "companion"}
|
|
7
|
+
{"color": "green", "pieceSet": "dubrovny"}
|
|
8
|
+
{"color": "blue", "pieceSet": "fantasy"}
|
|
9
|
+
{"color": "green", "pieceSet": "fresca"}
|
|
10
|
+
{"color": "green", "pieceSet": "gioco"}
|
|
11
|
+
{"color": "purple", "pieceSet": "icpieces"}
|
|
12
|
+
{"color": "blue", "pieceSet": "leipzig"}
|
|
13
|
+
{"color": "brown", "pieceSet": "libra"}
|
|
14
|
+
{"color": "blue", "pieceSet": "maestro"}
|
|
15
|
+
{"color": "brown", "pieceSet": "merida"}
|
|
16
|
+
{"color": "ic", "pieceSet": "mpchess"}
|
|
17
|
+
{"color": "brown", "pieceSet": "pirouetti"}
|
|
18
|
+
{"color": "green", "pieceSet": "spatial"}
|
|
19
|
+
{"color": "purple", "pieceSet": "staunty"}
|
|
20
|
+
{"color": "pink", "pieceSet": "tatiana"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{"name": "Sicilian Defense", "eco": "B20", "pgn": "1. e4 c5", "fen": "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 1258]}
|
|
2
|
+
{"name": "King's Pawn Game", "eco": "C20", "pgn": "1. e4 e5", "fen": "rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 2426]}
|
|
3
|
+
{"name": "Indian Defense", "eco": "A45", "pgn": "1. d4 Nf6", "fen": "rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 1 2", "initialActions": [1842, 3572]}
|
|
4
|
+
{"name": "Queen's Pawn Game", "eco": "D00", "pgn": "1. d4 d5", "fen": "rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 1842]}
|
|
5
|
+
{"name": "French Defense", "eco": "C00", "pgn": "1. e4 e6", "fen": "rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 2425]}
|
|
6
|
+
{"name": "Scandinavian Defense", "eco": "B01", "pgn": "1. e4 d5", "fen": "rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 1842]}
|
|
7
|
+
{"name": "Caro-Kann Defense", "eco": "B10", "pgn": "1. e4 c6", "fen": "rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 1257]}
|
|
8
|
+
{"name": "Horwitz Defense", "eco": "A40", "pgn": "1. d4 e6", "fen": "rnbqkbnr/pppp1ppp/4p3/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 2425]}
|
|
9
|
+
{"name": "Pirc Defense", "eco": "B00", "pgn": "1. e4 d6", "fen": "rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 1841]}
|
|
10
|
+
{"name": "Modern Defense", "eco": "B06", "pgn": "1. e4 g6", "fen": "rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", "initialActions": [2426, 3593]}
|
|
11
|
+
{"name": "Benoni Defense: Old Benoni", "eco": "A43", "pgn": "1. d4 c5", "fen": "rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 1258]}
|
|
12
|
+
{"name": "Alekhine Defense", "eco": "B02", "pgn": "1. e4 Nf6", "fen": "rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2", "initialActions": [2426, 3572]}
|
|
13
|
+
{"name": "Zukertort Opening", "eco": "A06", "pgn": "1. Nf3 d5", "fen": "rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq - 0 2", "initialActions": [3572, 1842]}
|
|
14
|
+
{"name": "Queen's Pawn Game: Modern Defense", "eco": "A40", "pgn": "1. d4 g6", "fen": "rnbqkbnr/pppppp1p/6p1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 3593]}
|
|
15
|
+
{"name": "Queen's Pawn Game", "eco": "A41", "pgn": "1. d4 d6", "fen": "rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 1841]}
|
|
16
|
+
{"name": "Zukertort Opening", "eco": "A05", "pgn": "1. Nf3 Nf6", "fen": "rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq - 2 2", "initialActions": [3572, 3572]}
|
|
17
|
+
{"name": "Queen's Pawn Game", "eco": "A40", "pgn": "1. d4 c6", "fen": "rnbqkbnr/pp1ppppp/2p5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1842, 1257]}
|
|
18
|
+
{"name": "English Opening: Anglo-Indian Defense", "eco": "A15", "pgn": "1. c4 Nf6", "fen": "rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - 1 2", "initialActions": [1258, 3572]}
|
|
19
|
+
{"name": "English Opening: King's English Variation", "eco": "A20", "pgn": "1. c4 e5", "fen": "rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - 0 2", "initialActions": [1258, 2426]}
|
|
20
|
+
{"name": "Nimzowitsch Defense", "eco": "B00", "pgn": "1. e4 Nc6", "fen": "r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2", "initialActions": [2426, 656]}
|
|
File without changes
|