kaggle-environments 0.2.0__py3-none-any.whl → 1.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaggle-environments might be problematic. Click here for more details.
- kaggle_environments/__init__.py +49 -13
- kaggle_environments/agent.py +177 -124
- kaggle_environments/api.py +31 -0
- kaggle_environments/core.py +298 -173
- 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} +22 -15
- 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 +214 -50
- kaggle_environments/schemas.json +23 -18
- kaggle_environments/static/player.html +206 -74
- kaggle_environments/utils.py +46 -73
- kaggle_environments-1.20.0.dist-info/METADATA +25 -0
- kaggle_environments-1.20.0.dist-info/RECORD +211 -0
- {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
- kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
- kaggle_environments/envs/battlegeese/battlegeese.py +0 -219
- kaggle_environments/temp.py +0 -14
- kaggle_environments-0.2.0.dist-info/METADATA +0 -393
- kaggle_environments-0.2.0.dist-info/RECORD +0 -33
- kaggle_environments-0.2.0.dist-info/entry_points.txt +0 -3
- kaggle_environments-0.2.0.dist-info/top_level.txt +0 -1
- {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
|
|
2
|
+
function renderer(context) {
|
|
3
|
+
const step = context.step
|
|
4
|
+
const visList = context.environment.steps[0][0].visualize
|
|
5
|
+
const energyText = "CGRWLPFDM A"
|
|
6
|
+
|
|
7
|
+
const info = context.environment.info
|
|
8
|
+
const players = [
|
|
9
|
+
info?.TeamNames?.[0] || "Player 0",
|
|
10
|
+
info?.TeamNames?.[1] || "Player 1"
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
let canvas = context.parent.querySelector("canvas")
|
|
14
|
+
if (!canvas) {
|
|
15
|
+
container = document.createElement("div")
|
|
16
|
+
container.style.position = "relative"
|
|
17
|
+
context.parent.appendChild(container)
|
|
18
|
+
|
|
19
|
+
canvas = document.createElement("canvas")
|
|
20
|
+
canvas.width = 750
|
|
21
|
+
canvas.height = 700
|
|
22
|
+
container.appendChild(canvas)
|
|
23
|
+
|
|
24
|
+
if (visList) {
|
|
25
|
+
for (let k = 0; k < 2; k++) {
|
|
26
|
+
const button = document.createElement("button")
|
|
27
|
+
button.style.width = "120px"
|
|
28
|
+
button.style.height = "50px"
|
|
29
|
+
button.style.left = k == 0 ? "240px" : "380px"
|
|
30
|
+
button.style.top = "10px"
|
|
31
|
+
button.style.position = "absolute"
|
|
32
|
+
button.style.zIndex = 1
|
|
33
|
+
button.innerHTML = "Open Visualizer<br>" + players[k]
|
|
34
|
+
button.addEventListener("click", (e) => {
|
|
35
|
+
for (let i = 0; i < visList.length; i++) {
|
|
36
|
+
for (let j = 0; j < 2; j++) {
|
|
37
|
+
visList[i].current.players[j].ramainingTime = context.environment.steps[i][j].observation.remainingOverageTime
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
visList[0].ps = players
|
|
41
|
+
|
|
42
|
+
const input = document.createElement("input")
|
|
43
|
+
input.type = "hidden"
|
|
44
|
+
input.name = "json"
|
|
45
|
+
input.value = JSON.stringify(visList)
|
|
46
|
+
|
|
47
|
+
const form = document.createElement("form")
|
|
48
|
+
form.method = "POST"
|
|
49
|
+
form.action = "https://ptcgvis.heroz.jp/Visualizer/Replay/"
|
|
50
|
+
if (info.EpisodeId == null) {
|
|
51
|
+
form.action += k
|
|
52
|
+
} else {
|
|
53
|
+
form.action += info.EpisodeId + "/" + k
|
|
54
|
+
}
|
|
55
|
+
form.target = "_blank"
|
|
56
|
+
form.appendChild(input)
|
|
57
|
+
|
|
58
|
+
document.body.appendChild(form)
|
|
59
|
+
form.submit()
|
|
60
|
+
})
|
|
61
|
+
container.appendChild(button)
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
const ctx = canvas.getContext("2d")
|
|
65
|
+
ctx.strokeStyle = "#ccc"
|
|
66
|
+
ctx.fillStyle = "#fff"
|
|
67
|
+
ctx.font = "30px sans-serif"
|
|
68
|
+
ctx.fillText("No visualize data.", 10, 100)
|
|
69
|
+
const error = context.environment.steps[0][0].error
|
|
70
|
+
if (error) {
|
|
71
|
+
ctx.fillText(error, 10, 150)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (visList.length <= step) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
const vis = visList[step]
|
|
80
|
+
const state = vis.current
|
|
81
|
+
|
|
82
|
+
const ctx = canvas.getContext("2d")
|
|
83
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
|
84
|
+
|
|
85
|
+
ctx.strokeStyle = "#ccc"
|
|
86
|
+
ctx.fillStyle = "#fff"
|
|
87
|
+
ctx.lineWidth = 2
|
|
88
|
+
|
|
89
|
+
ctx.font = "20px sans-serif"
|
|
90
|
+
if (state.result >= 0) {
|
|
91
|
+
if (state.result == 2) {
|
|
92
|
+
ctx.fillText("Draw", 330, 70)
|
|
93
|
+
} else {
|
|
94
|
+
ctx.fillText(players[state.result] + " Win", 310, 120)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
ctx.font = "12px sans-serif"
|
|
99
|
+
|
|
100
|
+
const drawCard = (x, y, card) => {
|
|
101
|
+
ctx.beginPath()
|
|
102
|
+
ctx.rect(x, y, 80, 60)
|
|
103
|
+
ctx.stroke()
|
|
104
|
+
nm = card.name
|
|
105
|
+
nm2 = null
|
|
106
|
+
if (nm.length >= 13) {
|
|
107
|
+
for (let i = 0; i < nm.length; i++) {
|
|
108
|
+
if (nm[i] == " ") {
|
|
109
|
+
nm2 = nm.substring(i + 1)
|
|
110
|
+
nm = nm.substring(0, i)
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
ctx.fillText(nm, x + 5, y + 13)
|
|
116
|
+
if (nm2 != null) {
|
|
117
|
+
ctx.fillText(nm2, x + 5, y + 27)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const drawField = (x, y, card) => {
|
|
121
|
+
drawCard(x, y, card)
|
|
122
|
+
ctx.fillText("HP " + card.hp, x + 5, y + 41)
|
|
123
|
+
energy = ""
|
|
124
|
+
for (let e of card.energies) {
|
|
125
|
+
energy = energy + energyText[e]
|
|
126
|
+
}
|
|
127
|
+
ctx.fillText(energy, x + 5, y + 55)
|
|
128
|
+
}
|
|
129
|
+
const posY = (index, len) => {
|
|
130
|
+
const center = 290
|
|
131
|
+
let height
|
|
132
|
+
if (len <= 8) {
|
|
133
|
+
height = 35 * len
|
|
134
|
+
} else {
|
|
135
|
+
height = 280
|
|
136
|
+
}
|
|
137
|
+
return center + height * (2 * index + 1 - len) / len
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
for (let j = 0; j < state.stadium.length; j++) {
|
|
141
|
+
drawCard(330, 420, state.stadium[j])
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (let i = 0; i < 2; i++) {
|
|
145
|
+
const ps = state.players[i]
|
|
146
|
+
|
|
147
|
+
ctx.fillText("Active", i == 0 ? 245 : 425, 270)
|
|
148
|
+
ctx.fillText("Bench", i == 0 ? 145 : 525, 10)
|
|
149
|
+
ctx.fillText("Hand", i == 0 ? 15 : 655, 10)
|
|
150
|
+
ctx.fillText("Deck " + ps.deckCount, i == 0 ? 258 : 438, 150)
|
|
151
|
+
ctx.fillText("Discard " + ps.discard.length, i == 0 ? 245 : 425, 170)
|
|
152
|
+
ctx.fillText("Prize " + ps.prize.length, i == 0 ? 258 : 438, 200)
|
|
153
|
+
|
|
154
|
+
for (let j = 0; j < ps.active.length; j++) {
|
|
155
|
+
drawField(i == 0 ? 240 : 420, posY(j, ps.active.length), ps.active[j])
|
|
156
|
+
}
|
|
157
|
+
for (let j = 0; j < ps.bench.length; j++) {
|
|
158
|
+
drawField(i == 0 ? 140 : 520, posY(j, ps.bench.length), ps.bench[j])
|
|
159
|
+
}
|
|
160
|
+
for (let j = 0; j < ps.hand.length; j++) {
|
|
161
|
+
drawCard(i == 0 ? 10 : 650, posY(j, ps.hand.length), ps.hand[j])
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cabt",
|
|
3
|
+
"title": "Card Battle",
|
|
4
|
+
"description": "Limited Card Battle.",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"agents": [2],
|
|
7
|
+
"configuration": {
|
|
8
|
+
"episodeSteps": 10000,
|
|
9
|
+
"actTimeout": 0,
|
|
10
|
+
"runTimeout": 3000
|
|
11
|
+
},
|
|
12
|
+
"reward": {
|
|
13
|
+
"description": "Lost:-1, Won:1, Draw:0",
|
|
14
|
+
"enum": [-1, 0, 1],
|
|
15
|
+
"default": 0
|
|
16
|
+
},
|
|
17
|
+
"observation": {
|
|
18
|
+
"remainingOverageTime": 600
|
|
19
|
+
},
|
|
20
|
+
"action": {
|
|
21
|
+
"description": "List of option index.",
|
|
22
|
+
"type": "array",
|
|
23
|
+
"default": []
|
|
24
|
+
},
|
|
25
|
+
"status": {
|
|
26
|
+
"defaults": ["INACTIVE", "INACTIVE"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import random
|
|
4
|
+
|
|
5
|
+
from .cg.game import battle_finish, battle_select, battle_start, visualize_data
|
|
6
|
+
from .cg.sim import Battle
|
|
7
|
+
|
|
8
|
+
deck = [
|
|
9
|
+
5,
|
|
10
|
+
5,
|
|
11
|
+
5,
|
|
12
|
+
5,
|
|
13
|
+
5,
|
|
14
|
+
5,
|
|
15
|
+
5,
|
|
16
|
+
5,
|
|
17
|
+
5,
|
|
18
|
+
5,
|
|
19
|
+
9,
|
|
20
|
+
9,
|
|
21
|
+
77,
|
|
22
|
+
77,
|
|
23
|
+
77,
|
|
24
|
+
77,
|
|
25
|
+
156,
|
|
26
|
+
156,
|
|
27
|
+
156,
|
|
28
|
+
156,
|
|
29
|
+
157,
|
|
30
|
+
157,
|
|
31
|
+
157,
|
|
32
|
+
157,
|
|
33
|
+
331,
|
|
34
|
+
331,
|
|
35
|
+
331,
|
|
36
|
+
331,
|
|
37
|
+
408,
|
|
38
|
+
408,
|
|
39
|
+
408,
|
|
40
|
+
408,
|
|
41
|
+
474,
|
|
42
|
+
474,
|
|
43
|
+
474,
|
|
44
|
+
474,
|
|
45
|
+
528,
|
|
46
|
+
528,
|
|
47
|
+
528,
|
|
48
|
+
528,
|
|
49
|
+
530,
|
|
50
|
+
530,
|
|
51
|
+
530,
|
|
52
|
+
530,
|
|
53
|
+
532,
|
|
54
|
+
554,
|
|
55
|
+
554,
|
|
56
|
+
554,
|
|
57
|
+
576,
|
|
58
|
+
576,
|
|
59
|
+
576,
|
|
60
|
+
576,
|
|
61
|
+
585,
|
|
62
|
+
585,
|
|
63
|
+
585,
|
|
64
|
+
585,
|
|
65
|
+
630,
|
|
66
|
+
630,
|
|
67
|
+
630,
|
|
68
|
+
630,
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def random_agent(obs: dict) -> list[int]:
|
|
73
|
+
if obs["select"] == None:
|
|
74
|
+
return deck
|
|
75
|
+
return random.sample(list(range(len(obs["select"]["option"]))), obs["select"]["maxCount"])
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def first_agent(obs: dict) -> list[int]:
|
|
79
|
+
if obs["select"] == None:
|
|
80
|
+
return deck
|
|
81
|
+
return list(range(obs["select"]["maxCount"]))
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
agents = {"random": random_agent, "first": first_agent}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def finish(env):
|
|
88
|
+
if len(env.steps) > 0:
|
|
89
|
+
env.steps[0][0]["visualize"] = json.loads(visualize_data())
|
|
90
|
+
battle_finish()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def interpreter(state, env):
|
|
94
|
+
if env.done:
|
|
95
|
+
Battle.battle_ptr = None
|
|
96
|
+
for i in range(2):
|
|
97
|
+
state[i].status = "ACTIVE"
|
|
98
|
+
o = state[i].observation
|
|
99
|
+
o["select"] = None
|
|
100
|
+
o["logs"] = []
|
|
101
|
+
o["current"] = None
|
|
102
|
+
o["search_begin_input"] = None
|
|
103
|
+
return state
|
|
104
|
+
elif Battle.battle_ptr == None:
|
|
105
|
+
decks = [state[0].action, state[1].action]
|
|
106
|
+
error = False
|
|
107
|
+
for i in range(2):
|
|
108
|
+
if state[i].status == "TIMEOUT" or state[i].status == "ERROR":
|
|
109
|
+
error = True
|
|
110
|
+
continue
|
|
111
|
+
if len(decks[i]) != 60:
|
|
112
|
+
state[i].status = "INVALID"
|
|
113
|
+
env.steps[0][0]["error"] = f"Player {i}'s deck does not have 60 cards."
|
|
114
|
+
error = True
|
|
115
|
+
if not error:
|
|
116
|
+
_, start_data = battle_start(state[0].action, state[1].action)
|
|
117
|
+
if start_data.errorPlayer >= 0:
|
|
118
|
+
state[start_data.errorPlayer].status = "INVALID"
|
|
119
|
+
env.steps[0][0]["error"] = f"Player {i}'s deck error."
|
|
120
|
+
error = True
|
|
121
|
+
if error:
|
|
122
|
+
for i in range(2):
|
|
123
|
+
if state[i].status == "ACTIVE":
|
|
124
|
+
state[i].status = "DONE"
|
|
125
|
+
return state
|
|
126
|
+
if Battle.battle_ptr == None:
|
|
127
|
+
raise ValueError("battle_ptr None.")
|
|
128
|
+
else:
|
|
129
|
+
error = False
|
|
130
|
+
select_player = Battle.obs["current"]["yourIndex"]
|
|
131
|
+
if state[select_player].status == "TIMEOUT" or state[select_player].status == "ERROR":
|
|
132
|
+
error = True
|
|
133
|
+
else:
|
|
134
|
+
try:
|
|
135
|
+
battle_select(state[select_player].action)
|
|
136
|
+
except:
|
|
137
|
+
state[select_player].status = "INVALID"
|
|
138
|
+
error = True
|
|
139
|
+
|
|
140
|
+
if error:
|
|
141
|
+
state[select_player].reward = -1
|
|
142
|
+
state[1 - select_player].status = "DONE"
|
|
143
|
+
state[1 - select_player].reward = 1
|
|
144
|
+
finish(env)
|
|
145
|
+
return state
|
|
146
|
+
|
|
147
|
+
obs = Battle.obs
|
|
148
|
+
s = obs["current"]
|
|
149
|
+
if s["result"] >= 0:
|
|
150
|
+
state[0].status = "DONE"
|
|
151
|
+
state[1].status = "DONE"
|
|
152
|
+
if s["result"] == 0:
|
|
153
|
+
state[0].reward = 1
|
|
154
|
+
state[1].reward = -1
|
|
155
|
+
elif s["result"] == 1:
|
|
156
|
+
state[0].reward = -1
|
|
157
|
+
state[1].reward = 1
|
|
158
|
+
else:
|
|
159
|
+
state[0].reward = 0
|
|
160
|
+
state[1].reward = 0
|
|
161
|
+
finish(env)
|
|
162
|
+
else:
|
|
163
|
+
index = s["yourIndex"]
|
|
164
|
+
state[index].status = "ACTIVE"
|
|
165
|
+
state[1 - index].status = "INACTIVE"
|
|
166
|
+
o = state[index].observation
|
|
167
|
+
o["select"] = obs["select"]
|
|
168
|
+
o["logs"] = obs["logs"]
|
|
169
|
+
o["current"] = obs["current"]
|
|
170
|
+
o["search_begin_input"] = obs["search_begin_input"]
|
|
171
|
+
return state
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def renderer(state, env):
|
|
175
|
+
return json.dumps(Battle.obs)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def html_renderer():
|
|
179
|
+
jspath = os.path.abspath(os.path.join(os.path.dirname(__file__), "cabt.js"))
|
|
180
|
+
with open(jspath, encoding="utf-8") as f:
|
|
181
|
+
return f.read()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
jsonpath = os.path.abspath(os.path.join(os.path.dirname(__file__), "cabt.json"))
|
|
185
|
+
with open(jsonpath) as f:
|
|
186
|
+
specification = json.load(f)
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from .sim import Battle, StartData, lib
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _get_battle_data() -> dict:
|
|
8
|
+
"""Retrieve the current state.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
dict: Current observation.
|
|
12
|
+
"""
|
|
13
|
+
sd = lib.GetBattleData(Battle.battle_ptr)
|
|
14
|
+
Battle.obs = json.loads(sd.json.decode())
|
|
15
|
+
Battle.obs["search_begin_input"] = ctypes.string_at(sd.data, sd.count).decode("ascii")
|
|
16
|
+
return Battle.obs
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def battle_start(deck0: list[int], deck1: list[int]) -> tuple[dict, StartData]:
|
|
20
|
+
"""Start the battle.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
deck0: List of card IDs included in the first player’s deck.
|
|
24
|
+
deck1: List of card IDs included in the second player’s deck.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
tuple: A tuple containing:
|
|
28
|
+
- dict: First observation.
|
|
29
|
+
- StartData: Battle start data.
|
|
30
|
+
"""
|
|
31
|
+
if len(deck0) != 60 or len(deck1) != 60:
|
|
32
|
+
raise ValueError("The deck must contain 60 cards.")
|
|
33
|
+
cards = deck0 + deck1
|
|
34
|
+
arg = (ctypes.c_int * len(cards))(*cards)
|
|
35
|
+
start_data = lib.BattleStart(arg)
|
|
36
|
+
Battle.battle_ptr = start_data.battlePtr
|
|
37
|
+
if Battle.battle_ptr == None or Battle.battle_ptr == 0:
|
|
38
|
+
return (None, start_data)
|
|
39
|
+
else:
|
|
40
|
+
return (_get_battle_data(), start_data)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def battle_finish():
|
|
44
|
+
"""End the battle and free the memory used during it."""
|
|
45
|
+
lib.BattleFinish(Battle.battle_ptr)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def battle_select(select_list: list[int]) -> dict:
|
|
49
|
+
"""Select option.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
select_list:
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
dict: Next observation.
|
|
56
|
+
"""
|
|
57
|
+
if not isinstance(select_list, list) or not all(isinstance(i, int) for i in select_list):
|
|
58
|
+
raise ValueError("select_list is not list[int]")
|
|
59
|
+
arg = (ctypes.c_int * len(select_list))(*select_list)
|
|
60
|
+
err = lib.Select(Battle.battle_ptr, arg, len(select_list))
|
|
61
|
+
if err != 0:
|
|
62
|
+
if err == 30:
|
|
63
|
+
raise ValueError("battle_ptr broken.")
|
|
64
|
+
else:
|
|
65
|
+
raise IndexError()
|
|
66
|
+
return _get_battle_data()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def visualize_data() -> str:
|
|
70
|
+
"""Retrieve the data to be used by the visualizer.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
str: The data to be used by the visualizer.
|
|
74
|
+
"""
|
|
75
|
+
return lib.VisualizeData(Battle.battle_ptr).decode()
|
|
Binary file
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class StartData(ctypes.Structure):
|
|
6
|
+
_fields_ = [
|
|
7
|
+
("battlePtr", ctypes.c_void_p),
|
|
8
|
+
("errorPlayer", ctypes.c_int),
|
|
9
|
+
("errorType", ctypes.c_int),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SerialData(ctypes.Structure):
|
|
14
|
+
_fields_ = [
|
|
15
|
+
("json", ctypes.c_char_p),
|
|
16
|
+
("data", ctypes.POINTER(ctypes.c_ubyte)),
|
|
17
|
+
("count", ctypes.c_int),
|
|
18
|
+
("selectPlayer", ctypes.c_int),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if os.name == "nt":
|
|
23
|
+
lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cg.dll")
|
|
24
|
+
else:
|
|
25
|
+
lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "libcg.so")
|
|
26
|
+
lib = ctypes.cdll.LoadLibrary(lib_path)
|
|
27
|
+
|
|
28
|
+
lib.GameInitialize()
|
|
29
|
+
|
|
30
|
+
lib.BattleStart.restype = StartData
|
|
31
|
+
lib.BattleStart.argtypes = [ctypes.POINTER(ctypes.c_int)]
|
|
32
|
+
|
|
33
|
+
lib.BattleFinish.argtypes = [ctypes.c_void_p]
|
|
34
|
+
|
|
35
|
+
lib.GetBattleData.restype = SerialData
|
|
36
|
+
lib.GetBattleData.argtypes = [ctypes.c_void_p]
|
|
37
|
+
|
|
38
|
+
lib.Select.restype = ctypes.c_int
|
|
39
|
+
lib.Select.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int), ctypes.c_int]
|
|
40
|
+
|
|
41
|
+
lib.VisualizeData.restype = ctypes.c_char_p
|
|
42
|
+
lib.VisualizeData.argtypes = [ctypes.c_void_p]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Battle:
|
|
46
|
+
battle_ptr = None
|
|
47
|
+
obs = None
|
|
48
|
+
raminingTime = [[], []]
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from kaggle_environments import make
|
|
2
|
+
from kaggle_environments.envs.cabt.cabt import deck, first_agent, random_agent
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_cabt_inits():
|
|
6
|
+
"""
|
|
7
|
+
Test that a game runs to completion with random agents.
|
|
8
|
+
"""
|
|
9
|
+
env = make("cabt", debug=True)
|
|
10
|
+
env.run(["random", "random"])
|
|
11
|
+
env_map = env.toJSON()
|
|
12
|
+
assert env_map["name"] == "cabt"
|
|
13
|
+
assert env_map["statuses"] == ["DONE", "DONE"]
|
|
14
|
+
assert sorted(env_map["rewards"]) in [[-1, 1], [0, 0]]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_cabt_first_agent_run():
|
|
18
|
+
"""
|
|
19
|
+
Test that a game runs to completion with first_agent.
|
|
20
|
+
"""
|
|
21
|
+
env = make("cabt", debug=True)
|
|
22
|
+
env.run(["first", "first"])
|
|
23
|
+
env_map = env.toJSON()
|
|
24
|
+
assert env_map["name"] == "cabt"
|
|
25
|
+
assert env_map["statuses"] == ["DONE", "DONE"]
|
|
26
|
+
assert sorted(env_map["rewards"]) in [[-1, 1], [0, 0]]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_cabt_random_vs_first():
|
|
30
|
+
"""
|
|
31
|
+
Test a game between a random and a first agent.
|
|
32
|
+
"""
|
|
33
|
+
env = make("cabt", debug=True)
|
|
34
|
+
env.run(["random", "first"])
|
|
35
|
+
env_map = env.toJSON()
|
|
36
|
+
assert env_map["name"] == "cabt"
|
|
37
|
+
assert env_map["statuses"] == ["DONE", "DONE"]
|
|
38
|
+
assert sorted(env_map["rewards"]) in [[-1, 1], [0, 0]]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_random_agent_deck_submission():
|
|
42
|
+
"""
|
|
43
|
+
Test random_agent's deck submission phase.
|
|
44
|
+
"""
|
|
45
|
+
obs = {"select": None}
|
|
46
|
+
action = random_agent(obs)
|
|
47
|
+
assert action == deck
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_random_agent_selection():
|
|
51
|
+
"""
|
|
52
|
+
Test random_agent's selection phase.
|
|
53
|
+
"""
|
|
54
|
+
obs = {"select": {"option": ["a", "b", "c", "d"], "maxCount": 2}}
|
|
55
|
+
action = random_agent(obs)
|
|
56
|
+
assert isinstance(action, list)
|
|
57
|
+
assert len(action) == 2
|
|
58
|
+
assert all(isinstance(i, int) for i in action)
|
|
59
|
+
assert all(0 <= i < 4 for i in action)
|
|
60
|
+
assert len(set(action)) == 2 # no duplicates
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_first_agent_deck_submission():
|
|
64
|
+
"""
|
|
65
|
+
Test first_agent's deck submission phase.
|
|
66
|
+
"""
|
|
67
|
+
obs = {"select": None}
|
|
68
|
+
action = first_agent(obs)
|
|
69
|
+
assert action == deck
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_first_agent_selection():
|
|
73
|
+
"""
|
|
74
|
+
Test first_agent's selection phase.
|
|
75
|
+
"""
|
|
76
|
+
obs = {"select": {"option": ["a", "b", "c", "d"], "maxCount": 2}}
|
|
77
|
+
action = first_agent(obs)
|
|
78
|
+
assert action == [0, 1]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def invalid_deck_agent(obs, config):
|
|
82
|
+
"""An agent that submits an invalid deck."""
|
|
83
|
+
if obs["select"] is None:
|
|
84
|
+
return [1, 2, 3] # Invalid deck (not 60 cards)
|
|
85
|
+
return [0]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_invalid_deck():
|
|
89
|
+
"""
|
|
90
|
+
Test the interpreter's handling of an invalid deck submission.
|
|
91
|
+
"""
|
|
92
|
+
env = make("cabt", debug=True)
|
|
93
|
+
env.run([invalid_deck_agent, "random"])
|
|
94
|
+
env_map = env.toJSON()
|
|
95
|
+
assert env_map["statuses"] == ["INVALID", "DONE"]
|
|
96
|
+
assert env_map["rewards"] == [None, 0]
|
|
97
|
+
assert "deck does not have 60 cards" in env_map["steps"][0][0]["error"]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def invalid_selection_agent(obs, config):
|
|
101
|
+
"""An agent that makes an invalid selection."""
|
|
102
|
+
if obs["select"] is None:
|
|
103
|
+
return deck
|
|
104
|
+
# Return more items than maxCount, which may cause an error in battle_select
|
|
105
|
+
return list(range(obs["select"]["maxCount"] + 1))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_invalid_selection():
|
|
109
|
+
"""
|
|
110
|
+
Test the interpreter's handling of an invalid selection during a turn.
|
|
111
|
+
"""
|
|
112
|
+
env = make("cabt", debug=True)
|
|
113
|
+
env.run([invalid_selection_agent, "random"])
|
|
114
|
+
env_map = env.toJSON()
|
|
115
|
+
|
|
116
|
+
assert sorted(env_map["statuses"]) == ["DONE", "INVALID"]
|
|
117
|
+
if env_map["statuses"][0] == "INVALID":
|
|
118
|
+
assert env_map["rewards"] == [None, 1]
|
|
119
|
+
else:
|
|
120
|
+
assert env_map["rewards"] == [1, None]
|