kaggle-environments 1.15.3__py2.py3-none-any.whl → 1.16.0__py2.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 +1 -1
- kaggle_environments/envs/chess/chess.json +4 -4
- kaggle_environments/envs/chess/chess.py +209 -51
- kaggle_environments/envs/chess/test_chess.py +43 -1
- kaggle_environments/envs/connectx/connectx.ipynb +3183 -0
- kaggle_environments/envs/football/football.ipynb +75 -0
- kaggle_environments/envs/halite/halite.ipynb +44736 -0
- kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +112 -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/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/ts/README.md +55 -0
- kaggle_environments/envs/lux_ai_2021/README.md +3 -0
- kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
- kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -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_s2/.gitignore +1 -0
- kaggle_environments/envs/lux_ai_s2/README.md +21 -0
- kaggle_environments/envs/lux_ai_s2/luxai_s2/.DS_Store +0 -0
- kaggle_environments/envs/lux_ai_s2/luxai_s2/map_generator/.DS_Store +0 -0
- kaggle_environments/envs/lux_ai_s3/README.md +21 -0
- kaggle_environments/envs/lux_ai_s3/agents.py +4 -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 +138 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +924 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +13 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +140 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +270 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +30 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +399 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
- kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +187 -0
- kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +71 -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 +27 -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 +53 -0
- kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
- kaggle_environments/envs/tictactoe/tictactoe.ipynb +1393 -0
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/METADATA +2 -2
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/RECORD +68 -10
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/WHEEL +1 -1
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/LICENSE +0 -0
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/entry_points.txt +0 -0
- {kaggle_environments-1.15.3.dist-info → kaggle_environments-1.16.0.dist-info}/top_level.txt +0 -0
kaggle_environments/__init__.py
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"agents": [2],
|
|
7
7
|
"configuration": {
|
|
8
8
|
"episodeSteps": 1000,
|
|
9
|
-
"actTimeout": 1,
|
|
9
|
+
"actTimeout": 0.1,
|
|
10
10
|
"agentTimeout": {
|
|
11
11
|
"description": "Obsolete field kept for backwards compatibility, please use observation.remainingOverageTime.",
|
|
12
12
|
"type": "number",
|
|
13
13
|
"minimum": 0,
|
|
14
|
-
"default":
|
|
14
|
+
"default": 10
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"reward": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"defaults": ["white", "black"],
|
|
32
32
|
"enum": ["white", "black"]
|
|
33
33
|
},
|
|
34
|
-
"remainingOverageTime":
|
|
34
|
+
"remainingOverageTime": 10
|
|
35
35
|
},
|
|
36
36
|
"action": {
|
|
37
37
|
"description": "Move in UCI notation (e.g., e2e4)",
|
|
@@ -41,4 +41,4 @@
|
|
|
41
41
|
"status": {
|
|
42
42
|
"defaults": ["ACTIVE", "INACTIVE"]
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|
|
@@ -1,28 +1,194 @@
|
|
|
1
|
-
import
|
|
1
|
+
import math
|
|
2
2
|
import random
|
|
3
3
|
import json
|
|
4
4
|
from os import path
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
|
|
7
|
+
from Chessnut import Game
|
|
5
8
|
|
|
6
9
|
ERROR = "ERROR"
|
|
7
10
|
DONE = "DONE"
|
|
8
11
|
INACTIVE = "INACTIVE"
|
|
9
12
|
ACTIVE = "ACTIVE"
|
|
13
|
+
WHITE = "white"
|
|
14
|
+
|
|
15
|
+
OPENINGS = [
|
|
16
|
+
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
|
17
|
+
"rnbqkbnr/1p2pp1p/p2p2p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq - 0 6",
|
|
18
|
+
"r1b1kb1r/ppppq1pp/2n2n2/1B2p3/4N3/5N2/PPPPQPPP/R1B1K2R w KQkq - 3 7",
|
|
19
|
+
"rnbqkb1r/p2ppppp/5n2/2pP4/2p5/2N5/PP2PPPP/R1BQKBNR w KQkq - 0 5",
|
|
20
|
+
"rnbqk1nr/p1p1bppp/1p2p3/3pP3/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq - 0 5",
|
|
21
|
+
"r2qk1nr/ppp2pp1/2np3p/2b1p3/2B1P1b1/2PP1N2/PP3PPP/RNBQ1RK1 w kq - 0 7",
|
|
22
|
+
"rn1qk1nr/pp2ppbp/3p2p1/2p5/2PP2b1/2N1PN2/PP3PPP/R1BQKB1R w KQkq c6 0 6",
|
|
23
|
+
"rnbqkbnr/1p2pp1p/p2p2p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq - 0 6",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
MOVES = [
|
|
28
|
+
"",
|
|
29
|
+
"e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 a7a6 c2c4 g7g6",
|
|
30
|
+
"e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4 g8f6 d1e2 d8e7",
|
|
31
|
+
"d2d4 g8f6 c2c4 c7c5 d4d5 b7b5 b1c3 b5c4",
|
|
32
|
+
"e2e4 e7e6 d2d4 d7d5 b1c3 f8e7 e4e5 b7b6",
|
|
33
|
+
"e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 d7d6 c2c3 c8g4 d2d3 h7h6",
|
|
34
|
+
"d2d4 g7g6 c2c4 f8g7 b1c3 d7d6 g1f3 c8g4 e2e3 c7c5",
|
|
35
|
+
"e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 a7a6 c2c4 g7g6"
|
|
36
|
+
]
|
|
37
|
+
|
|
10
38
|
|
|
11
39
|
def random_agent(obs):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
40
|
+
"""
|
|
41
|
+
Selects a random legal move from the board.
|
|
42
|
+
Returns:
|
|
15
43
|
A string representing the chosen move in UCI notation (e.g., "e2e4").
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
44
|
+
"""
|
|
45
|
+
game = Game(obs.board)
|
|
46
|
+
moves = list(game.get_moves())
|
|
47
|
+
return random.choice(moves) if moves else None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def king_shuffle_agent(obs):
|
|
51
|
+
"""Moves the king pawn and then shuffles the king."""
|
|
52
|
+
game = Game(obs.board)
|
|
53
|
+
moves = list(game.get_moves())
|
|
54
|
+
|
|
55
|
+
to_move = ["e7e5", "e2e4", "e8e7", "e7e8", "e1e2", "e2e1"]
|
|
56
|
+
for move in to_move:
|
|
57
|
+
if move in moves:
|
|
58
|
+
return move
|
|
59
|
+
|
|
60
|
+
# If no other moves are possible, pick a random legal move (or return None)
|
|
61
|
+
return random.choice(moves) if moves else None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def board_shuffle_agent(obs):
|
|
65
|
+
"""Moves the king panw and then shuffles pieces."""
|
|
66
|
+
game = Game(obs.board)
|
|
67
|
+
moves = list(game.get_moves())
|
|
68
|
+
|
|
69
|
+
to_move = ["e7e5", "e2e4", "e8e7", "e7e6", "e1e2", "e2e3"]
|
|
70
|
+
for move in to_move:
|
|
71
|
+
if move in moves:
|
|
72
|
+
return move
|
|
73
|
+
|
|
74
|
+
# add shuffle moves for knights and bishop
|
|
75
|
+
to_shuffle = [
|
|
76
|
+
"b1c3",
|
|
77
|
+
"c3b1",
|
|
78
|
+
"g1f3",
|
|
79
|
+
"f3g1",
|
|
80
|
+
"b8c6",
|
|
81
|
+
"c6b8",
|
|
82
|
+
"g8f6",
|
|
83
|
+
"f6g8",
|
|
84
|
+
"f1e2",
|
|
85
|
+
"e2f1",
|
|
86
|
+
"f8e7",
|
|
87
|
+
"e7f8",
|
|
88
|
+
]
|
|
89
|
+
# filter to only shuffle king moves
|
|
90
|
+
for move in moves:
|
|
91
|
+
f1 = move[0]
|
|
92
|
+
f2 = move[2]
|
|
93
|
+
r1 = int(move[1])
|
|
94
|
+
r2 = int(move[3])
|
|
95
|
+
df = abs(ord(f1) - ord(f2))
|
|
96
|
+
dr = abs(r2 - r1)
|
|
97
|
+
if r1 < 3 or r1 > 6:
|
|
98
|
+
continue
|
|
99
|
+
if r2 < 3 or r2 > 6:
|
|
100
|
+
continue
|
|
101
|
+
if dr > 1 or df > 1:
|
|
102
|
+
continue
|
|
103
|
+
if move[2:4] == "e5":
|
|
104
|
+
continue
|
|
105
|
+
if move[2:4] == "e4":
|
|
106
|
+
continue
|
|
107
|
+
to_shuffle.append(move)
|
|
108
|
+
random.shuffle(to_shuffle)
|
|
109
|
+
for move in to_shuffle:
|
|
110
|
+
if move in moves:
|
|
111
|
+
return move
|
|
112
|
+
|
|
113
|
+
# If no other moves are possible, pick a random legal move (or return None)
|
|
114
|
+
return random.choice(moves) if moves else None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
agents = {
|
|
118
|
+
"random": random_agent,
|
|
119
|
+
"king_shuffle": king_shuffle_agent,
|
|
120
|
+
"board_shuffle": board_shuffle_agent}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def sufficient_material(pieces):
|
|
124
|
+
"""Checks if the given pieces are sufficient for checkmate."""
|
|
125
|
+
if pieces['q'] > 0 or pieces['r'] > 0 or pieces['p'] > 0:
|
|
126
|
+
return True
|
|
127
|
+
# we only have knights and bishops left on this team
|
|
128
|
+
knight_bishop_count = pieces['n'] + pieces['b']
|
|
129
|
+
if knight_bishop_count >= 3:
|
|
130
|
+
return True
|
|
131
|
+
if knight_bishop_count == 2 and pieces['b'] >= 1:
|
|
132
|
+
return True
|
|
21
133
|
|
|
22
|
-
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def is_insufficient_material(board):
|
|
138
|
+
white_pieces = defaultdict(int)
|
|
139
|
+
black_pieces = defaultdict(int)
|
|
140
|
+
|
|
141
|
+
for square in range(64):
|
|
142
|
+
piece = board.get_piece(square)
|
|
143
|
+
if piece and piece != " ":
|
|
144
|
+
if piece.isupper():
|
|
145
|
+
white_pieces[piece.lower()] += 1
|
|
146
|
+
else:
|
|
147
|
+
black_pieces[piece.lower()] += 1
|
|
148
|
+
|
|
149
|
+
if not sufficient_material(
|
|
150
|
+
white_pieces) and not sufficient_material(black_pieces):
|
|
151
|
+
return True
|
|
152
|
+
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def square_str_to_int(square_str):
|
|
157
|
+
"""Converts a square string (e.g., "a2") to an integer index (0-63)."""
|
|
158
|
+
if len(square_str) != 2 or not (
|
|
159
|
+
'a' <= square_str[0] <= 'h' and '1' <= square_str[1] <= '8'):
|
|
160
|
+
raise ValueError("Invalid square string")
|
|
161
|
+
|
|
162
|
+
col = ord(square_str[0]) - ord('a') # Get column index (0-7)
|
|
163
|
+
row = int(square_str[1]) - 1 # Get row index (0-7)
|
|
164
|
+
return row * 8 + col
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
seen_positions = defaultdict(int)
|
|
168
|
+
game_one_complete = False
|
|
169
|
+
game_start_position = math.floor(random.random() * len(OPENINGS))
|
|
23
170
|
|
|
24
171
|
def interpreter(state, env):
|
|
172
|
+
global seen_positions
|
|
173
|
+
global game_one_complete
|
|
174
|
+
global game_start_position
|
|
25
175
|
if env.done:
|
|
176
|
+
game_one_complete = False
|
|
177
|
+
seen_positions = defaultdict(int)
|
|
178
|
+
game_start_position = math.floor(random.random() * len(OPENINGS))
|
|
179
|
+
state[0].observation.board = OPENINGS[game_start_position]
|
|
180
|
+
state[0].observation.remainingOverageTime = 10
|
|
181
|
+
state[1].observation.board = OPENINGS[game_start_position]
|
|
182
|
+
state[1].observation.remainingOverageTime = 10
|
|
183
|
+
return state
|
|
184
|
+
|
|
185
|
+
if state[0].status == ACTIVE and state[1].status == ACTIVE:
|
|
186
|
+
# set up new game
|
|
187
|
+
state[0].observation.mark, state[1].observation.mark = state[1].observation.mark, state[0].observation.mark
|
|
188
|
+
state[0].observation.board = OPENINGS[game_start_position]
|
|
189
|
+
state[1].observation.board = OPENINGS[game_start_position]
|
|
190
|
+
state[0].status = ACTIVE if state[0].observation.mark == WHITE else INACTIVE
|
|
191
|
+
state[0].status = ACTIVE if state[0].observation.mark == WHITE else INACTIVE
|
|
26
192
|
return state
|
|
27
193
|
|
|
28
194
|
# Isolate the active and inactive agents.
|
|
@@ -36,39 +202,46 @@ def interpreter(state, env):
|
|
|
36
202
|
# The board is shared, only update the first state.
|
|
37
203
|
board = state[0].observation.board
|
|
38
204
|
|
|
39
|
-
|
|
40
|
-
|
|
205
|
+
# Create a chessnut game object from the FEN string
|
|
206
|
+
game = Game(board)
|
|
41
207
|
|
|
42
208
|
# Get the action (move) from the agent
|
|
43
209
|
action = active.action
|
|
44
210
|
|
|
45
211
|
# Check if the move is legal
|
|
46
212
|
try:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
raise ValueError("Illegal move")
|
|
50
|
-
except:
|
|
213
|
+
game.apply_move(action)
|
|
214
|
+
except BaseException:
|
|
51
215
|
active.status = ERROR
|
|
52
216
|
active.reward = -1
|
|
53
217
|
inactive.status = DONE
|
|
54
218
|
return state
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
219
|
+
fen = game.get_fen()
|
|
220
|
+
board_str = fen.split(" ", maxsplit=1)[0]
|
|
221
|
+
seen_positions[board_str] += 1
|
|
58
222
|
|
|
59
223
|
# Update the board in the observation
|
|
60
|
-
state[0].observation.board =
|
|
61
|
-
state[1].observation.board =
|
|
224
|
+
state[0].observation.board = fen
|
|
225
|
+
state[1].observation.board = fen
|
|
62
226
|
|
|
227
|
+
terminal_state = DONE if game_one_complete else ACTIVE
|
|
228
|
+
pawn_or_capture_move_count = int(
|
|
229
|
+
fen.split(" ")[4]) # fen keeps track of this
|
|
63
230
|
# Check for game end conditions
|
|
64
|
-
if
|
|
65
|
-
|
|
66
|
-
active.status =
|
|
67
|
-
inactive.
|
|
68
|
-
|
|
69
|
-
elif
|
|
70
|
-
active.status =
|
|
71
|
-
inactive.status =
|
|
231
|
+
if pawn_or_capture_move_count == 100 or is_insufficient_material(
|
|
232
|
+
game.board):
|
|
233
|
+
active.status = terminal_state
|
|
234
|
+
inactive.status = terminal_state
|
|
235
|
+
game_one_complete = True
|
|
236
|
+
elif seen_positions[board_str] >= 3 or game.status == Game.STALEMATE:
|
|
237
|
+
active.status = terminal_state
|
|
238
|
+
inactive.status = terminal_state
|
|
239
|
+
game_one_complete = True
|
|
240
|
+
elif game.status == Game.CHECKMATE:
|
|
241
|
+
active.reward += 1
|
|
242
|
+
active.status = terminal_state
|
|
243
|
+
inactive.status = terminal_state
|
|
244
|
+
game_one_complete = True
|
|
72
245
|
else:
|
|
73
246
|
# Switch turns
|
|
74
247
|
active.status = INACTIVE
|
|
@@ -76,34 +249,19 @@ def interpreter(state, env):
|
|
|
76
249
|
|
|
77
250
|
return state
|
|
78
251
|
|
|
252
|
+
|
|
79
253
|
def renderer(state, env):
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# Unicode characters for chess pieces
|
|
84
|
-
piece_symbols = {
|
|
85
|
-
'P': '♙', 'R': '♖', 'N': '♘', 'B': '♗', 'Q': '♕', 'K': '♔',
|
|
86
|
-
'p': '♟', 'r': '♜', 'n': '♞', 'b': '♝', 'q': '♛', 'k': '♚',
|
|
87
|
-
'.': ' ' # Empty square
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
board_repr = ""
|
|
91
|
-
for square in chess.SQUARES:
|
|
92
|
-
piece = board_obj.piece_at(square)
|
|
93
|
-
if piece:
|
|
94
|
-
board_repr += piece_symbols[piece.symbol()]
|
|
95
|
-
else:
|
|
96
|
-
board_repr += piece_symbols['.']
|
|
97
|
-
if chess.square_file(square) == 7: # End of a rank
|
|
98
|
-
board_repr += "\n"
|
|
254
|
+
board_fen = state[0].observation.board
|
|
255
|
+
game = Game(board_fen)
|
|
256
|
+
return game.board
|
|
99
257
|
|
|
100
|
-
return board_repr
|
|
101
258
|
|
|
102
259
|
jsonpath = path.abspath(path.join(path.dirname(__file__), "chess.json"))
|
|
103
260
|
with open(jsonpath) as f:
|
|
104
261
|
specification = json.load(f)
|
|
105
262
|
|
|
263
|
+
|
|
106
264
|
def html_renderer():
|
|
107
265
|
jspath = path.abspath(path.join(path.dirname(__file__), "chess.js"))
|
|
108
|
-
with open(jspath) as
|
|
109
|
-
return
|
|
266
|
+
with open(jspath) as g:
|
|
267
|
+
return g.read()
|
|
@@ -1,8 +1,50 @@
|
|
|
1
1
|
from kaggle_environments import make
|
|
2
|
+
from Chessnut import Game
|
|
3
|
+
from chess import is_insufficient_material
|
|
2
4
|
|
|
3
5
|
def test_chess_inits():
|
|
4
6
|
env = make("chess", debug=True)
|
|
5
7
|
env.run(["random", "random"])
|
|
6
8
|
json = env.toJSON()
|
|
7
9
|
assert json["name"] == "chess"
|
|
8
|
-
assert json["statuses"] == ["
|
|
10
|
+
assert json["statuses"] == ["DONE", "DONE"]
|
|
11
|
+
|
|
12
|
+
def test_chess_three_fold():
|
|
13
|
+
env = make("chess", debug=True)
|
|
14
|
+
env.run(["king_shuffle", "king_shuffle"])
|
|
15
|
+
json = env.toJSON()
|
|
16
|
+
assert json["name"] == "chess"
|
|
17
|
+
assert json["statuses"] == ["DONE", "DONE"]
|
|
18
|
+
assert json["rewards"] == [0, 0]
|
|
19
|
+
|
|
20
|
+
def test_chess_100_move_rule():
|
|
21
|
+
env = make("chess", debug=True)
|
|
22
|
+
env.run(["board_shuffle", "board_shuffle"])
|
|
23
|
+
json = env.toJSON()
|
|
24
|
+
assert json["name"] == "chess"
|
|
25
|
+
assert json["statuses"] == ["DONE", "DONE"]
|
|
26
|
+
assert json["rewards"] == [0, 0]
|
|
27
|
+
|
|
28
|
+
def test_sufficient_material():
|
|
29
|
+
game = Game()
|
|
30
|
+
assert not is_insufficient_material(game.board)
|
|
31
|
+
|
|
32
|
+
def test_insufficient_material_with_two_kings():
|
|
33
|
+
game = Game('8/8/K7/8/8/3k4/8/8 w - - 58 282')
|
|
34
|
+
assert is_insufficient_material(game.board)
|
|
35
|
+
|
|
36
|
+
def test_insufficient_material_with_two_kings_and_bishop():
|
|
37
|
+
game = Game('6k1/8/7B/8/8/8/8/2K5 b - - 90 250')
|
|
38
|
+
assert is_insufficient_material(game.board)
|
|
39
|
+
|
|
40
|
+
def test_insufficient_material_with_two_kings_and_two_knights():
|
|
41
|
+
game = Game('6k1/8/6NN/8/8/8/8/2K5 b - - 90 250')
|
|
42
|
+
assert is_insufficient_material(game.board)
|
|
43
|
+
|
|
44
|
+
def test_sufficient_material_with_king_knight_and_bishop():
|
|
45
|
+
game = Game('6k1/8/6NB/8/8/8/8/2K5 b - - 90 250')
|
|
46
|
+
assert not is_insufficient_material(game.board)
|
|
47
|
+
|
|
48
|
+
def test_sufficient_material_with_king_bishop_and_bishop():
|
|
49
|
+
game = Game('6k1/8/6BB/8/8/8/8/2K5 b - - 90 250')
|
|
50
|
+
assert not is_insufficient_material(game.board)
|