2Contains classes for collecting command line input, and converting to a form
3that will be convenient for instantiating all of the objects needed to play a
9from dataclasses
import dataclass
10from typing
import Any, Literal
12import xiangqi_bindings
as xb
20 player_type: Literal[
None,
"ai",
"person"]
21 algo: Literal[
None,
"minimax",
"random"]
24 number_zobrist_states: int =
None
25 zkeys_seed: int =
None
30 if self.
algoalgo in [
"minimax",
None]:
31 return xb.EvaluatorType.kMinimax
33 return xb.EvaluatorType.kRandom
35 return xb.EvaluatorType.kHuman
40 xb.EvaluatorType.kRandom,
41 xb.EvaluatorType.kHuman,
53 xb.EvaluatorType.kRandom,
54 xb.EvaluatorType.kHuman,
63 xb.EvaluatorType.kRandom,
64 xb.EvaluatorType.kHuman,
77 return random.randint(a=0, b=2**32 -1)
91 run_kwargs: dict[str, Any], color_enum: xb.PieceColor, color_prefix: str
93 player_info = {
"color": color_enum} | {
94 key.removeprefix(color_prefix): val
95 for key, val
in run_kwargs.items()
96 if key.startswith(color_prefix)
101def build_game_runner(run_kwargs: dict[str, Any]) -> xb.GameRunner:
103 run_kwargs=run_kwargs,
104 color_enum=xb.PieceColor.kRed,
108 run_kwargs=run_kwargs,
109 color_enum=xb.PieceColor.kBlk,
110 color_prefix=
"black_",
113 game_runner = xb.GameRunner(
114 red_player_spec=red_player_spec, black_player_spec=black_player_spec
122 save_summary: bool =
False
123 output_dir_suffix: str =
""
126def get_output_file_info(run_kwargs: dict[str, Any]) -> OutputFileInfo:
128 save_summary=run_kwargs[
"save_summary"],
129 output_dir_suffix=run_kwargs[
"output_dir_suffix"],
136 Container for info collected
from command line
for specific player.
139 player_type: PlayerType
143 num_zobrist_states: int
144 zkeys_seed: int | None =
None
149 Converts command line input related to a player into PlayerInput object.
152 _player_input_dispatch = {
154 "person": PlayerType.HUMAN,
158 _minimax_key_size_dispatch = {
159 32: xb.MinimaxMoveEvaluator32,
160 64: xb.MinimaxMoveEvaluator64,
161 128: xb.MinimaxMoveEvaluator128,
164 _default_key_size = 64
166 _default_strength = 4
168 _default_number_zobrist_states = 1
177 number_zobrist_states: int,
206 if player_type == PlayerType.HUMAN:
207 algo = strength = key_size = num_zobrist_states =
None
210 algo = EvaluatorType.RANDOM
211 strength = key_size = num_zobrist_states =
None
214 algo = EvaluatorType.MINIMAX
218 player_type=player_type,
223 num_zobrist_states=num_zobrist_states,
230 Data container with all the info needed to instantiate a Game.
233 red_player_input: PlayerInput
234 black_player_input: PlayerInput
235 save_summary: bool = False
236 output_dir_suffix: str =
""
242 Converts dictionary output by XiangqiGameCommandLine into a
246 run_kwargs: dict[str, Any]
250 player_input=self.
run_kwargs[
"red_player_type"],
252 strength_input=self.
run_kwargs[
"red_strength"],
253 key_size_input=self.
run_kwargs[
"red_key_size"],
255 number_zobrist_states=self.
run_kwargs[
"red_number_zobrist_states"],
258 player_input=self.
run_kwargs[
"black_player_type"],
260 strength_input=self.
run_kwargs[
"black_strength"],
261 key_size_input=self.
run_kwargs[
"black_key_size"],
262 zkeys_seed=self.
run_kwargs[
"black_zkeys_seed"],
264 "black_number_zobrist_states"
269 red_player_input=red_interpreter.interpret_command(),
270 black_player_input=black_interpreter.interpret_command(),
272 output_dir_suffix=self.
run_kwargs[
"output_dir_suffix"],
278 Collects info from command line args out outputs
as a dictionary.
280 Includes default values
for any items
not specified
in command line args.
286 description=
"A Xiangqi (a.k.a. Chinese Chess) game that can be "
287 "played as Human vs. Human, AI vs. AI, or Human vs. AI",
288 epilog=
"Note: If all default parameters are used, both players will be AI and "
289 "use Minimax with search depth = 4, and 64 bit Zobrist keys.",
296 choices=[
"person",
"ai"],
297 help=
"Can be 'person', or 'ai'. Default is 'ai'.",
303 choices=[
"random",
"minimax"],
305 help=
"Search algorithm to use for red player (if player type is "
306 "'ai'). Can be 'random' or 'minimax'. Default is minimax.",
313 choices=range(1, 10),
315 help=
"Search depth to user for red AI player with minimax algo"
323 choices=[32, 64, 128],
325 help=
"Key size (in bits) used for red AI player Zobrist hashing",
330 "--red_number_zobrist_states",
334 help=
"Number of Zobrist state values to maintain for red.",
342 help=
"Seed for red player Zobrist Keys generator. "
343 "32-bit unsigned int.",
348 "--black_player_type",
349 choices=[
"person",
"ai"],
350 help=
"Can be 'person', or 'ai'. Default is 'ai'.",
356 choices=[
"random",
"minimax"],
358 help=
"Search depth to user for black AI player with minimax algo"
366 choices=range(1, 10),
368 help=
"Search depth to user for red player when red is 'ai' with "
369 "'minimax.' Default is 4.",
376 choices=[32, 64, 128],
378 help=
"Key size (in bits) used for black AI player Zobrist hashing",
383 "--black_number_zobrist_states",
387 help=
"Number of Zobrist state values to maintain for black.",
392 "--black_zkeys_seed",
395 help=
"Seed for black player Zobrist Keys generator. "
396 "32-bit unsigned int.",
403 help=
"Save GameSummary as .json",
408 "--output_dir_suffix",
411 help=
"String to append to end of output directory name. Output dir "
412 "relative to cwd will be "
413 "./data/game_summaries/<timestamp><optional-suffix>",
418 args_namespace = self.
_parser.parse_args()
419 return vars(args_namespace)
424 my_command = command_retriever.get_args()
428if __name__ ==
"__main__":
Enums that are only used on the Python side of the app.