graph-games-proto 0.3.1966__py3-none-any.whl → 0.3.1981__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.
graph_games_proto/fns.py CHANGED
@@ -1190,7 +1190,7 @@ class LegalActionKeep(PClass):
1190
1190
  deck_idx = legal_action.keep.deck_idx
1191
1191
  card_uuids_matching_deck = [
1192
1192
  card_uuid for card_uuid in discard_tray
1193
- if state.carduuid2deckidx[card_uuid] == deck_idx
1193
+ if state.kernel.carduuid2deckidx[card_uuid] == deck_idx
1194
1194
  ]
1195
1195
  num_cards = len(card_uuids_matching_deck)
1196
1196
  actual_min = 0 if legal_action.keep.min is None else legal_action.keep.min
@@ -1231,7 +1231,7 @@ class LegalActionDiscard(PClass):
1231
1231
  deck_idx = legal_action.discard.deck_idx
1232
1232
  card_uuids_matching_deck = [
1233
1233
  card_uuid for card_uuid in discard_tray
1234
- if state.carduuid2deckidx[card_uuid] == deck_idx
1234
+ if state.kernel.carduuid2deckidx[card_uuid] == deck_idx
1235
1235
  ]
1236
1236
  num_cards = len(card_uuids_matching_deck)
1237
1237
  actual_min = 0 if legal_action.discard.min is None else legal_action.discard.min
@@ -1535,7 +1535,7 @@ class ActionDiscard(PClass):
1535
1535
  card_uuids = field(type=list) # List[int]
1536
1536
  def get_public(self, state):
1537
1537
  return PublicActionDiscard(
1538
- deck_idxs=[state.carduuid2deckidx[card_uuid] for card_uuid in self.card_uuids]
1538
+ deck_idxs=[state.kernel.carduuid2deckidx[card_uuid] for card_uuid in self.card_uuids]
1539
1539
  )
1540
1540
  def __todict__(self):
1541
1541
  return {
@@ -1565,7 +1565,7 @@ class ActionKeep(PClass):
1565
1565
  card_uuids = field(type=list) # List[int])
1566
1566
  def get_public(self, state):
1567
1567
  return PublicActionKeep(
1568
- deck_idxs=[state.carduuid2deckidx[card_uuid] for card_uuid in self.card_uuids]
1568
+ deck_idxs=[state.kernel.carduuid2deckidx[card_uuid] for card_uuid in self.card_uuids]
1569
1569
  )
1570
1570
  def __todict__(self):
1571
1571
  return {
@@ -1948,6 +1948,7 @@ class StateKernel(PClass):
1948
1948
  carduuid2card = field(type=dict) # Dict[str, Card]
1949
1949
  edgetuple2uuid = field(type=dict) # Dict[Tuple[int, int], str]
1950
1950
  nodeuuid2idx = field(type=dict) # Dict[str, int]
1951
+ carduuid2deckidx = field(type=dict) # Dict[str, int]
1951
1952
  def __todict__(self):
1952
1953
  return {
1953
1954
  "rng": rng2json(self.rng),
@@ -1965,6 +1966,7 @@ class StateKernel(PClass):
1965
1966
  "carduuid2card": {k: v.__todict__() for k, v in self.carduuid2card.items()},
1966
1967
  "edgetuple2uuid": [{"k": list(k), "v": v} for k, v in self.edgetuple2uuid.items()],
1967
1968
  "nodeuuid2idx": self.nodeuuid2idx,
1969
+ "carduuid2deckidx": self.carduuid2deckidx,
1968
1970
  }
1969
1971
  @staticmethod
1970
1972
  def __fromdict__(d):
@@ -1984,6 +1986,7 @@ class StateKernel(PClass):
1984
1986
  carduuid2card={k: Card.__fromdict(v) for k, v in d["carduuid2card"].items()},
1985
1987
  edgetuple2uuid={tuple(item["k"]): item["v"] for item in d["edgetuple2uuid"]},
1986
1988
  nodeuuid2idx=d["nodeuuid2idx"],
1989
+ carduuid2deckidx=d["carduuid2deckidx"],
1987
1990
  )
1988
1991
 
1989
1992
 
@@ -2005,11 +2008,14 @@ def init_state_kernel(**kwargs):
2005
2008
  pieces = generate_pieces(piece_template, player_idx)
2006
2009
  for piece in pieces:
2007
2010
  pieceuuid2piece[piece.uuid] = piece
2011
+
2012
+ carduuid2deckidx = {}
2008
2013
  carduuid2card = {}
2009
2014
  for dek in board_config.deks:
2010
2015
  cards = generate_cards(dek)
2011
2016
  for card in cards:
2012
2017
  carduuid2card[card.uuid] = card
2018
+ carduuid2deckidx[card.uuid] = dek.idx
2013
2019
 
2014
2020
  nodeuuid2idx = {node.uuid: idx for idx, node in enumerate(board_config.points)}
2015
2021
  edges = get_edges(rng, board_config, nodeuuid2idx)
@@ -2036,16 +2042,15 @@ def init_state_kernel(**kwargs):
2036
2042
  pieceuuid2piece=pieceuuid2piece,
2037
2043
  edgetuple2uuid=edgetuple2uuid,
2038
2044
  nodeuuid2idx=nodeuuid2idx,
2045
+ carduuid2deckidx=carduuid2deckidx,
2039
2046
  )
2040
2047
 
2041
2048
 
2042
2049
  class State(PClass):
2043
2050
  kernel = field(type=StateKernel)
2044
2051
  idx2path = field(type=list) # List[Path2]
2045
- pieceuuid2piece = field(type=dict) # Dict[str, Piece]
2046
2052
  bonus_statuses = field(type=list) # List[BonusStatus]
2047
2053
  bonusuuid2bonusidx = field(type=dict) # Dict[str, int]
2048
- carduuid2deckidx = field(type=dict) # Dict[str, int]
2049
2054
  starting_decks = field(type=list) # List[Deck]
2050
2055
  starting_piles = field(type=list)
2051
2056
  history = field(type=list) # List[Action2]
@@ -2067,10 +2072,8 @@ class State(PClass):
2067
2072
  return {
2068
2073
  "kernel": self.kernel.__todict__(),
2069
2074
  "idx2path": [v.__todict__() for v in self.idx2path],
2070
- "pieceuuid2piece": {k: v.__todict__() for k, v in self.pieceuuid2piece.items()},
2071
2075
  "bonus_statuses": [status.__todict__() for status in self.bonus_statuses],
2072
2076
  "bonusuuid2bonusidx": self.bonusuuid2bonusidx,
2073
- "carduuid2deckidx": self.carduuid2deckidx,
2074
2077
  "starting_decks": [deck.__todict__() for deck in self.starting_decks],
2075
2078
  "starting_piles": [pile.__todict__() for pile in self.starting_piles],
2076
2079
  "history": [x.__todict__() for x in self.history],
@@ -2094,10 +2097,8 @@ class State(PClass):
2094
2097
  return State(
2095
2098
  kernel=StateKernel.__fromdict__(d["kernel"]),
2096
2099
  idx2path=[Path2.__fromdict__(v) for v in d["idx2path"]],
2097
- pieceuuid2piece={k: Piece.__fromdict__(v) for k, v in d["pieceuuid2piece"].items()},
2098
2100
  bonus_statuses=[BonusStatus.__fromdict__(x) for x in d["bonus_statuses"]],
2099
2101
  bonusuuid2bonusidx=d["bonusuuid2bonusidx"],
2100
- carduuid2deckidx=d["carduuid2deckidx"],
2101
2102
  starting_decks=[Deck.__fromdict__(x) for x in d["starting_decks"]],
2102
2103
  starting_piles=[Pile.__fromdict__(x) for x in d["starting_piles"]],
2103
2104
  history=[Action2.__fromdict__(x) for x in d["history"]],
@@ -2594,12 +2595,9 @@ def getinitialstate(game_config):
2594
2595
  )
2595
2596
  piles.append(pile)
2596
2597
 
2597
- carduuid2deckidx = {}
2598
2598
  decks = []
2599
2599
  for dek in board_config.deks:
2600
2600
  cards = generate_cards(dek)
2601
- for card in cards:
2602
- carduuid2deckidx[card.uuid] = dek.idx
2603
2601
  deck_obj = Deck(
2604
2602
  uuid=dek.uuid,
2605
2603
  idx=dek.idx,
@@ -2639,10 +2637,8 @@ def getinitialstate(game_config):
2639
2637
 
2640
2638
  state = State(
2641
2639
  idx2path=idx2path,
2642
- pieceuuid2piece=pieceuuid2piece,
2643
2640
  bonus_statuses=bonus_statuses,
2644
2641
  bonusuuid2bonusidx=bonusuuid2bonusidx,
2645
- carduuid2deckidx=carduuid2deckidx,
2646
2642
  starting_decks=[
2647
2643
  Deck.__fromdict__(x.__todict__()) for x in decks
2648
2644
  ],
@@ -2718,6 +2714,7 @@ def run_state_action_hooks(state, action, hooks, log=False):
2718
2714
  )
2719
2715
 
2720
2716
 
2717
+ @dispatch(State, int)
2721
2718
  def score_public_items(state, player_idx):
2722
2719
  items = []
2723
2720
  for edge in state.edges:
@@ -2725,7 +2722,7 @@ def score_public_items(state, player_idx):
2725
2722
  if len(path.segments) > 0:
2726
2723
  first_segment = path.segments[0]
2727
2724
  if first_segment.pieces and len(first_segment.pieces) > 0:
2728
- first_piece = state.pieceuuid2piece[first_segment.pieces[0]]
2725
+ first_piece = state.kernel.pieceuuid2piece[first_segment.pieces[0]]
2729
2726
  if first_piece.player_idx == player_idx:
2730
2727
  items.append(
2731
2728
  ScoreItem2(
@@ -3315,14 +3312,15 @@ def handle_move_pieces_to_path_action(game, action):
3315
3312
  return game
3316
3313
 
3317
3314
 
3318
- def calc_player_graph(game, player_idx):
3319
- nodes = game.nodes
3315
+ @dispatch(State, int)
3316
+ def calc_player_graph(state, player_idx):
3317
+ nodes = state.nodes
3320
3318
  node2neighbors = {node.idx: set() for node in nodes}
3321
3319
 
3322
- for edge in game.edges:
3320
+ for edge in state.edges:
3323
3321
  for path in edge.paths:
3324
3322
  for segment in path.segments:
3325
- if segment.pieces and segment.pieces[0] and game.pieceuuid2piece[segment.pieces[0]].player_idx == player_idx:
3323
+ if segment.pieces and segment.pieces[0] and state.kernel.pieceuuid2piece[segment.pieces[0]].player_idx == player_idx:
3326
3324
  # print(f"[path_idx {path.idx}] edge.start_point_uuid {edge.start_point_uuid} ({edge.node_1_idx}) connected to edge.end_point_uuid {edge.end_point_uuid} ({edge.node_2_idx}) player_idx: {player_idx}")
3327
3325
  node2neighbors[edge.node_1_idx].add(edge.node_2_idx)
3328
3326
  node2neighbors[edge.node_2_idx].add(edge.node_1_idx)
@@ -3587,19 +3585,21 @@ def is_move_pieces_to_path_action_legal(game, action):
3587
3585
  )
3588
3586
 
3589
3587
 
3590
- def get_total_path_count(game):
3591
- return len(game.idx2path)
3588
+ @dispatch(StateKernel)
3589
+ def get_total_path_count(kernel):
3590
+ return len(kernel.idx2path)
3592
3591
 
3593
3592
 
3594
- def get_legal_actions_for_path(game, player_idx, path_idx):
3595
- if path_idx < 0 or get_total_path_count(game) <= path_idx:
3593
+ @dispatch(StateKernel, int, int)
3594
+ def get_legal_actions_for_path(state_kernel, player_idx, path_idx):
3595
+ if path_idx < 0 or get_total_path_count(state_kernel) <= path_idx:
3596
3596
  return []
3597
3597
 
3598
- if not is_path_open_to_player(game, path_idx, player_idx):
3598
+ if not is_path_open_to_player(state_kernel, path_idx, player_idx):
3599
3599
  return []
3600
3600
 
3601
3601
  legal_actions = []
3602
- default = get_sample_actionclaimpath(game, player_idx, path_idx)
3602
+ default = get_sample_actionclaimpath(state_kernel, player_idx, path_idx)
3603
3603
  if default:
3604
3604
  legal_actions.append(
3605
3605
  LegalAction(
@@ -3608,7 +3608,7 @@ def get_legal_actions_for_path(game, player_idx, path_idx):
3608
3608
  title="Select resources to claim path",
3609
3609
  instruction="claim a path",
3610
3610
  allotted_seconds=DEFAULT_ALLOTTED_SECONDS,
3611
- allotted_since_action_idx=(len(game.history) - 1),
3611
+ allotted_since_action_idx=(len(state_kernel.history) - 1),
3612
3612
  btn_text="Claim path",
3613
3613
  move_pieces_to_path=LegalActionMovePiecesToPath(
3614
3614
  path_idx=int(path_idx),
@@ -3620,11 +3620,12 @@ def get_legal_actions_for_path(game, player_idx, path_idx):
3620
3620
  return []
3621
3621
 
3622
3622
 
3623
- def get_legal_actions_for_paths(game, player_idx):
3623
+ @dispatch(StateKernel, int)
3624
+ def get_legal_actions_for_paths(kernel, player_idx):
3624
3625
  legal_actions = []
3625
3626
 
3626
- for path_idx in range(get_total_path_count(game)):
3627
- legal_actions_for_path = get_legal_actions_for_path(game, player_idx, path_idx)
3627
+ for path_idx in range(get_total_path_count(kernel)):
3628
+ legal_actions_for_path = get_legal_actions_for_path(kernel, player_idx, path_idx)
3628
3629
  if legal_actions_for_path:
3629
3630
  legal_actions.extend(legal_actions_for_path)
3630
3631
  # else:
@@ -3633,7 +3634,8 @@ def get_legal_actions_for_paths(game, player_idx):
3633
3634
  return legal_actions
3634
3635
 
3635
3636
 
3636
- def get_player_idxs_on_edge(game, edge):
3637
+ @dispatch(StateKernel, BiEdge)
3638
+ def get_player_idxs_on_edge(kernel, edge):
3637
3639
  player_idxs = set()
3638
3640
  if not edge or not edge.paths:
3639
3641
  return list(player_idxs)
@@ -3641,26 +3643,26 @@ def get_player_idxs_on_edge(game, edge):
3641
3643
  for path in edge.paths:
3642
3644
  for segment in path.segments:
3643
3645
  if segment.pieces and segment.pieces[0]:
3644
- piece = game.pieceuuid2piece.get(segment.pieces[0])
3646
+ piece = kernel.pieceuuid2piece.get(segment.pieces[0])
3645
3647
  if piece:
3646
3648
  player_idxs.add(piece.player_idx)
3647
3649
 
3648
3650
  return list(player_idxs)
3649
3651
 
3652
+ @dispatch(StateKernel, int, int)
3653
+ def is_path_open_to_player(state_kernel, path_idx, player_idx):
3650
3654
 
3651
- def is_path_open_to_player(game, path_idx, player_idx):
3652
-
3653
- if not game or path_idx < 0 or get_total_path_count(game) <= path_idx:
3655
+ if not state_kernel or path_idx < 0 or get_total_path_count(state_kernel) <= path_idx:
3654
3656
  return False
3655
3657
 
3656
- path = game.idx2path[path_idx]
3657
- edge_idx = game.edgeuuid2idx[path.edge_uuid]
3658
- edge = game.edges[edge_idx]
3658
+ path = state_kernel.idx2path[path_idx]
3659
+ edge_idx = state_kernel.edgeuuid2idx[path.edge_uuid]
3660
+ edge = state_kernel.edges[edge_idx]
3659
3661
 
3660
- player_idxs_on_edge = get_player_idxs_on_edge(game, edge)
3662
+ player_idxs_on_edge = get_player_idxs_on_edge(state_kernel, edge)
3661
3663
 
3662
3664
  # Check if edge is too crowded for the number of players
3663
- if game.game_config.num_players <= 3:
3665
+ if state_kernel.game_config.num_players <= 3:
3664
3666
  if len(player_idxs_on_edge) > 0:
3665
3667
  return False
3666
3668
 
@@ -3672,7 +3674,7 @@ def is_path_open_to_player(game, path_idx, player_idx):
3672
3674
  return False
3673
3675
 
3674
3676
  # Check if the player has enough pieces to claim the path
3675
- player_pieces = game.players[player_idx].pieces
3677
+ player_pieces = state_kernel.players[player_idx].pieces
3676
3678
  if len(player_pieces) < len(path.segments):
3677
3679
  return False
3678
3680
 
@@ -3844,18 +3846,18 @@ def get_sample_actionclaimpath(game, player_idx, path_idx):
3844
3846
  card_uuids=card_fulfillment,
3845
3847
  )
3846
3848
 
3847
-
3848
- def get_sample_path_fulfillment(game, player_idx, path_idx):
3849
- path = game.idx2path[path_idx]
3850
- remaining_card_uuids = [card_uuid for card_uuid in game.players[player_idx].cards if game.carduuid2card[card_uuid].deck_idx == 0]
3849
+ @dispatch(StateKernel, int, int)
3850
+ def get_sample_path_fulfillment(kernel, player_idx, path_idx):
3851
+ path = kernel.idx2path[path_idx]
3852
+ remaining_card_uuids = [card_uuid for card_uuid in kernel.players[player_idx].cards if kernel.carduuid2card[card_uuid].deck_idx == 0]
3851
3853
  remaining_pieces = [
3852
3854
  piece_uuid
3853
- for piece_uuid in game.players[player_idx].pieces
3854
- if game.pieceuuid2piece[piece_uuid].piece_template_idx == 0
3855
+ for piece_uuid in kernel.players[player_idx].pieces
3856
+ if kernel.pieceuuid2piece[piece_uuid].piece_template_idx == 0
3855
3857
  ]
3856
3858
  remaining_segments = path.segments
3857
3859
  return get_path_fulfillment_from_resources(
3858
- game,
3860
+ kernel,
3859
3861
  remaining_card_uuids,
3860
3862
  remaining_pieces,
3861
3863
  remaining_segments,
@@ -4072,7 +4074,6 @@ def init_state(kernel):
4072
4074
  legal_actions_3=[],
4073
4075
  is_terminal=False,
4074
4076
  idx2path=kernel.idx2path,
4075
- pieceuuid2piece=kernel.pieceuuid2piece,
4076
4077
  carduuid2card=kernel.carduuid2card,
4077
4078
  )
4078
4079
  state = state.set(legal_actions_3=calc_legal_actions3(kernel))
@@ -4266,7 +4267,7 @@ def getpublicstate(s):
4266
4267
  deadlines=get_deadlines(s),
4267
4268
  game_started_at=s.kernel.game_config.started_at,
4268
4269
  allotted_times=get_max_allotted_times(s),
4269
- all_pieces=list(s.pieceuuid2piece.values()),
4270
+ all_pieces=list(s.kernel.pieceuuid2piece.values()),
4270
4271
  to_play_2=getpublictoplay(s),
4271
4272
  bonus_statuses=s.bonus_statuses,
4272
4273
  starting_decks=s.starting_decks,
@@ -4307,7 +4308,7 @@ def getpublicplayer(s, p):
4307
4308
  deck_counts[s.kernel.carduuid2card[card].deck_idx] += 1
4308
4309
  piece_template_counts = [0 for _ in s.kernel.game_config.fig.board_config.piece_templates]
4309
4310
  for piece_uuid in p.pieces:
4310
- piece_template_counts[s.pieceuuid2piece[piece_uuid].piece_template_idx] += 1
4311
+ piece_template_counts[s.kernel.pieceuuid2piece[piece_uuid].piece_template_idx] += 1
4311
4312
  return PublicPlayer(
4312
4313
  idx=p.idx,
4313
4314
  pieces=p.pieces,
@@ -5293,6 +5294,7 @@ HANDLE_TERMINAL_HOOKS = [
5293
5294
  ),
5294
5295
  ]
5295
5296
 
5297
+ @dispatch(StateKernel, int)
5296
5298
  def get_default_legal_actions(state_kernel, player_idx):
5297
5299
  allotted_seconds = DEFAULT_ALLOTTED_SECONDS
5298
5300
  allotted_since_action_idx = len(state_kernel.history) - 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graph_games_proto
3
- Version: 0.3.1966
3
+ Version: 0.3.1981
4
4
  Requires-Dist: multipledispatch==1.0.0
5
5
  Requires-Dist: pyrsistent==0.20.0
6
6
  Requires-Dist: numpy==2.2.4
@@ -1,9 +1,9 @@
1
1
  graph_games_proto/__init__.py,sha256=_EVQR-51XehfH45XZlba1WPdx3omS3Gm1nTwrgGyn2Q,667
2
2
  graph_games_proto/all_types.py,sha256=IpbwftEcHS5Ewz-saFNk0lO9FvcbuHG36odRTayCXUk,54911
3
- graph_games_proto/fns.py,sha256=XaDJPmMLioflSj00zzPXjdF1JfBh-hZB5dLO1OTn7lQ,182090
3
+ graph_games_proto/fns.py,sha256=jK1eZUO8OtrzJUpRs2uNOtelhaZZwGphkw59CpbTSUE,182177
4
4
  graph_games_proto/main.py,sha256=fj2U7KcwrpZtuUhjOX5yVxY18LZvvsxDFYZ_S5mxe04,145
5
5
  graph_games_proto/state.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- graph_games_proto-0.3.1966.dist-info/METADATA,sha256=4JWfsAdg8cjBPgPN1tFc6UuRWIMKSvKtceQmO5iRN4s,188
7
- graph_games_proto-0.3.1966.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
- graph_games_proto-0.3.1966.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
- graph_games_proto-0.3.1966.dist-info/RECORD,,
6
+ graph_games_proto-0.3.1981.dist-info/METADATA,sha256=CD2Hb9yHEm9IyX0_vrROdZ9iqn6TSZuBJeaDqo3HZ18,188
7
+ graph_games_proto-0.3.1981.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
+ graph_games_proto-0.3.1981.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
+ graph_games_proto-0.3.1981.dist-info/RECORD,,