graph-games-proto 0.3.2049__py3-none-any.whl → 0.3.2077__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 +272 -72
- {graph_games_proto-0.3.2049.dist-info → graph_games_proto-0.3.2077.dist-info}/METADATA +1 -1
- {graph_games_proto-0.3.2049.dist-info → graph_games_proto-0.3.2077.dist-info}/RECORD +5 -5
- {graph_games_proto-0.3.2049.dist-info → graph_games_proto-0.3.2077.dist-info}/WHEEL +0 -0
- {graph_games_proto-0.3.2049.dist-info → graph_games_proto-0.3.2077.dist-info}/top_level.txt +0 -0
graph_games_proto/fns.py
CHANGED
@@ -1104,7 +1104,7 @@ class PrivateState(PClass):
|
|
1104
1104
|
player_score = field(type=PrivatePlayerScore)
|
1105
1105
|
player = field(type=Player)
|
1106
1106
|
legal_actions_3 = field(type=list) # List[LegalAction]
|
1107
|
-
goal_completions = field(type=list
|
1107
|
+
goal_completions = field(type=list) # List[GoalCompletion]
|
1108
1108
|
def __todict__(self):
|
1109
1109
|
return {
|
1110
1110
|
"my_history": [x.__todict__() for x in self.my_history],
|
@@ -1779,6 +1779,33 @@ class Segment2(PClass):
|
|
1779
1779
|
unit_uuid=d["unit_uuid"],
|
1780
1780
|
pieces=d["pieces"],
|
1781
1781
|
)
|
1782
|
+
|
1783
|
+
|
1784
|
+
class SegmentRecord(PClass):
|
1785
|
+
uuid = field(type=str)
|
1786
|
+
unit_uuid = field(type=(str, type(None)), initial=None) # Optional[str]
|
1787
|
+
piece_uuids = field(type=list) # List[str]
|
1788
|
+
def __todict__(self):
|
1789
|
+
return {
|
1790
|
+
"uuid": self.uuid,
|
1791
|
+
"unit_uuid": self.unit_uuid,
|
1792
|
+
"piece_uuids": self.piece_uuids,
|
1793
|
+
}
|
1794
|
+
@staticmethod
|
1795
|
+
def __fromdict__(d):
|
1796
|
+
return SegmentRecord(
|
1797
|
+
uuid=d["uuid"],
|
1798
|
+
unit_uuid=d["unit_uuid"],
|
1799
|
+
piece_uuids=d["piece_uuids"],
|
1800
|
+
)
|
1801
|
+
|
1802
|
+
|
1803
|
+
def init_segment_record(segment: Segment2) -> SegmentRecord:
|
1804
|
+
return SegmentRecord(
|
1805
|
+
uuid=segment.uuid,
|
1806
|
+
unit_uuid=segment.unit_uuid,
|
1807
|
+
piece_uuids=[piece.uuid for piece in segment.pieces],
|
1808
|
+
)
|
1782
1809
|
|
1783
1810
|
|
1784
1811
|
class Path2(PClass):
|
@@ -1803,6 +1830,38 @@ class Path2(PClass):
|
|
1803
1830
|
)
|
1804
1831
|
|
1805
1832
|
|
1833
|
+
class PathRecord(PClass):
|
1834
|
+
uuid = field(type=str)
|
1835
|
+
idx = field(type=int)
|
1836
|
+
edge_uuid = field(type=str)
|
1837
|
+
segment_uuids = field(type=list) # List[str]
|
1838
|
+
def __todict__(self):
|
1839
|
+
return {
|
1840
|
+
"uuid": self.uuid,
|
1841
|
+
"idx": self.idx,
|
1842
|
+
"edge_uuid": self.edge_uuid,
|
1843
|
+
"segment_uuids": self.segment_uuids,
|
1844
|
+
}
|
1845
|
+
@staticmethod
|
1846
|
+
def __fromdict__(d):
|
1847
|
+
return PathRecord(
|
1848
|
+
uuid=d["uuid"],
|
1849
|
+
idx=d["idx"],
|
1850
|
+
edge_uuid=d["edge_uuid"],
|
1851
|
+
segment_uuids=d["segment_uuids"],
|
1852
|
+
)
|
1853
|
+
|
1854
|
+
|
1855
|
+
def init_path_record(path: Path2) -> PathRecord:
|
1856
|
+
return PathRecord(
|
1857
|
+
uuid=path.uuid,
|
1858
|
+
idx=path.idx,
|
1859
|
+
edge_uuid=path.edge_uuid,
|
1860
|
+
segment_uuids=[segment.uuid for segment in path.segments],
|
1861
|
+
)
|
1862
|
+
|
1863
|
+
|
1864
|
+
|
1806
1865
|
class BiEdge(PClass):
|
1807
1866
|
uuid = field(type=str)
|
1808
1867
|
start_point_uuid = field(type=str)
|
@@ -1840,6 +1899,57 @@ class BiEdge(PClass):
|
|
1840
1899
|
)
|
1841
1900
|
|
1842
1901
|
|
1902
|
+
class BiEdgeRecord(PClass):
|
1903
|
+
uuid = field(type=str)
|
1904
|
+
start_point_uuid = field(type=str)
|
1905
|
+
end_point_uuid = field(type=str)
|
1906
|
+
node_1_uuid = field(type=str)
|
1907
|
+
node_2_uuid = field(type=str)
|
1908
|
+
node_1_idx = field(type=int)
|
1909
|
+
node_2_idx = field(type=int)
|
1910
|
+
path_idxs = field(type=list) # List[str]
|
1911
|
+
score = field(type=int)
|
1912
|
+
def __todict__(self):
|
1913
|
+
return {
|
1914
|
+
"uuid": self.uuid,
|
1915
|
+
"start_point_uuid": self.start_point_uuid,
|
1916
|
+
"end_point_uuid": self.end_point_uuid,
|
1917
|
+
"node_1_uuid": self.node_1_uuid,
|
1918
|
+
"node_2_uuid": self.node_2_uuid,
|
1919
|
+
"node_1_idx": self.node_1_idx,
|
1920
|
+
"node_2_idx": self.node_2_idx,
|
1921
|
+
"path_idxs": self.path_idxs,
|
1922
|
+
"score": self.score,
|
1923
|
+
}
|
1924
|
+
@staticmethod
|
1925
|
+
def __fromdict__(d):
|
1926
|
+
return BiEdgeRecord(
|
1927
|
+
uuid=d["uuid"],
|
1928
|
+
start_point_uuid=d["start_point_uuid"],
|
1929
|
+
end_point_uuid=d["end_point_uuid"],
|
1930
|
+
node_1_uuid=d["node_1_uuid"],
|
1931
|
+
node_2_uuid=d["node_2_uuid"],
|
1932
|
+
node_1_idx=d["node_1_idx"],
|
1933
|
+
node_2_idx=d["node_2_idx"],
|
1934
|
+
path_idxs=d["path_idxs"],
|
1935
|
+
score=d["score"],
|
1936
|
+
)
|
1937
|
+
|
1938
|
+
|
1939
|
+
def init_biedge_record(biedge: BiEdge) -> BiEdgeRecord:
|
1940
|
+
return BiEdgeRecord(
|
1941
|
+
uuid=biedge.uuid,
|
1942
|
+
start_point_uuid=biedge.start_point_uuid,
|
1943
|
+
end_point_uuid=biedge.end_point_uuid,
|
1944
|
+
node_1_uuid=biedge.node_1_uuid,
|
1945
|
+
node_2_uuid=biedge.node_2_uuid,
|
1946
|
+
node_1_idx=biedge.node_1_idx,
|
1947
|
+
node_2_idx=biedge.node_2_idx,
|
1948
|
+
path_idxs=[path.idx for path in biedge.paths],
|
1949
|
+
score=biedge.score,
|
1950
|
+
)
|
1951
|
+
|
1952
|
+
|
1843
1953
|
class Node(PClass):
|
1844
1954
|
idx = field(type=int)
|
1845
1955
|
uuid = field(type=str)
|
@@ -1932,9 +2042,23 @@ class BonusStatus(PClass):
|
|
1932
2042
|
)
|
1933
2043
|
|
1934
2044
|
|
2045
|
+
#==
|
2046
|
+
# uuid2edgerecord
|
2047
|
+
# uuid2segmentrecord
|
2048
|
+
# idx2pathrecord
|
2049
|
+
# uuid2piece
|
2050
|
+
#==#
|
2051
|
+
|
2052
|
+
|
2053
|
+
|
1935
2054
|
class StateKernel(PClass):
|
1936
2055
|
rng = field(type=random.Random)
|
1937
2056
|
game_config = field(type=GameConfig)
|
2057
|
+
|
2058
|
+
uuid2edgerecord = field(type=dict) # Dict[str, BiEdgeRecord]
|
2059
|
+
uuid2segmentrecord = field(type=dict) # Dict[str, SegmentRecord]
|
2060
|
+
idx2pathrecord = field(type=list) # List[PathRecord]
|
2061
|
+
|
1938
2062
|
edges = field(type=list) # List[BiEdge]
|
1939
2063
|
nodes = field(type=list) # List[Node]
|
1940
2064
|
regions = field(type=list) # List[Region]
|
@@ -1943,7 +2067,6 @@ class StateKernel(PClass):
|
|
1943
2067
|
players = field(type=list) # List[Player]
|
1944
2068
|
player_idxs = field(type=list) # List[int]
|
1945
2069
|
history = field(type=list) # List[PublicAction]
|
1946
|
-
idx2path = field(type=list) # List[Path2]
|
1947
2070
|
pieceuuid2piece = field(type=dict) # Dict[str, Piece]
|
1948
2071
|
edgeuuid2idx = field(type=dict) # Dict[str, int]
|
1949
2072
|
carduuid2card = field(type=dict) # Dict[str, Card]
|
@@ -1968,7 +2091,9 @@ class StateKernel(PClass):
|
|
1968
2091
|
"players": [player.__todict__() for player in self.players],
|
1969
2092
|
"player_idxs": self.player_idxs,
|
1970
2093
|
"history": [action.__todict__() for action in self.history],
|
1971
|
-
"
|
2094
|
+
"uuid2edgerecord": {k: v.__todict__() for k, v in self.uuid2edgerecord.items()},
|
2095
|
+
"uuid2segmentrecord": {k: v.__todict__() for k, v in self.uuid2segmentrecord.items()},
|
2096
|
+
"idx2pathrecord": [v.__todict__() for v in self.idx2pathrecord],
|
1972
2097
|
"pieceuuid2piece": {k: v.__todict__() for k, v in self.pieceuuid2piece.items()},
|
1973
2098
|
"edgeuuid2idx": self.edgeuuid2idx,
|
1974
2099
|
"carduuid2card": {k: v.__todict__() for k, v in self.carduuid2card.items()},
|
@@ -1995,7 +2120,9 @@ class StateKernel(PClass):
|
|
1995
2120
|
players=[Player.__fromdict__(player) for player in d["players"]],
|
1996
2121
|
player_idxs=d["player_idxs"],
|
1997
2122
|
history=[PublicAction.__fromdict__(action) for action in d["history"]],
|
1998
|
-
|
2123
|
+
uuid2edgerecord={k: BiEdgeRecord.__fromdict__(v) for k, v in d["uuid2edgerecord"].items()},
|
2124
|
+
uuid2segmentrecord={k: Segment2.__fromdict__(v) for k, v in d["uuid2segmentrecord"].items()},
|
2125
|
+
idx2pathrecord=[Path2.__fromdict(v) for v in d["idx2pathrecord"]],
|
1999
2126
|
pieceuuid2piece={k: Piece.__fromdict(v) for k, v in d["pieceuuid2piece"].items()},
|
2000
2127
|
edgeuuid2idx=d["edgeuuid2idx"],
|
2001
2128
|
carduuid2card={k: Card.__fromdict(v) for k, v in d["carduuid2card"].items()},
|
@@ -2018,11 +2145,11 @@ def init_state_kernel(**kwargs):
|
|
2018
2145
|
board_config = fig.board_config
|
2019
2146
|
nodes = kwargs.get('nodes', [])
|
2020
2147
|
edges = kwargs.get('edges', [])
|
2021
|
-
|
2148
|
+
idx2pathrecord = []
|
2022
2149
|
edgeuuid2idx = {edge.uuid: idx for idx, edge in enumerate(edges)}
|
2023
2150
|
for edge in edges:
|
2024
2151
|
for path in edge.paths:
|
2025
|
-
|
2152
|
+
idx2pathrecord.append(init_path_record(path))
|
2026
2153
|
pieceuuid2piece = {}
|
2027
2154
|
for piece_template in board_config.piece_templates:
|
2028
2155
|
if piece_template.has_player:
|
@@ -2053,6 +2180,11 @@ def init_state_kernel(**kwargs):
|
|
2053
2180
|
|
2054
2181
|
player_graphs_3 = calc_player_graphs3(nodes, edges, pieceuuid2piece, game_config)
|
2055
2182
|
|
2183
|
+
segments = kwargs.get('segments', [])
|
2184
|
+
|
2185
|
+
uuid2segmentrecord = {segment.uuid: init_segment_record(segment) for segment in segments}
|
2186
|
+
uuid2edgerecord = {edge.uuid: init_biedge_record(edge) for edge in edges}
|
2187
|
+
|
2056
2188
|
return StateKernel(
|
2057
2189
|
rng=rng,
|
2058
2190
|
game_config=game_config,
|
@@ -2064,7 +2196,9 @@ def init_state_kernel(**kwargs):
|
|
2064
2196
|
players=kwargs.get('players'),
|
2065
2197
|
player_idxs=kwargs.get('player_idxs'),
|
2066
2198
|
history=kwargs.get('history', []),
|
2067
|
-
|
2199
|
+
uuid2edgerecord=uuid2edgerecord,
|
2200
|
+
uuid2segmentrecord=uuid2segmentrecord,
|
2201
|
+
idx2pathrecord=idx2pathrecord,
|
2068
2202
|
edgeuuid2idx=edgeuuid2idx,
|
2069
2203
|
carduuid2card=carduuid2card,
|
2070
2204
|
pieceuuid2piece=pieceuuid2piece,
|
@@ -2083,7 +2217,7 @@ class State(PClass):
|
|
2083
2217
|
kernel = field(type=StateKernel)
|
2084
2218
|
|
2085
2219
|
# Identity - these fields should be in the kernel (can only be changed in "get_initial_state" and "get_next_state")
|
2086
|
-
# The struture should be this:
|
2220
|
+
# The struture should be this: uuid2segmentrecord, uuid2edge, uuid2path, uuid2region, uuid2node
|
2087
2221
|
|
2088
2222
|
# Memoized
|
2089
2223
|
legal_actions_3 = field(type=list) # List[LegalAction]
|
@@ -2466,6 +2600,20 @@ def get_nodes(board_config):
|
|
2466
2600
|
return []
|
2467
2601
|
|
2468
2602
|
|
2603
|
+
def get_segments(board_config):
|
2604
|
+
segments = []
|
2605
|
+
for board_path in board_config.board_paths:
|
2606
|
+
for segment in board_path.path.segments:
|
2607
|
+
segments.append(
|
2608
|
+
Segment2(
|
2609
|
+
uuid=segment.uuid,
|
2610
|
+
unit_uuid=segment.unit_uuid,
|
2611
|
+
pieces=[]
|
2612
|
+
)
|
2613
|
+
)
|
2614
|
+
return segments
|
2615
|
+
|
2616
|
+
|
2469
2617
|
def get_edges(rng, board_config, nodeuuid2idx):
|
2470
2618
|
edges = []
|
2471
2619
|
|
@@ -2634,6 +2782,7 @@ def getinitialstate(game_config):
|
|
2634
2782
|
kernel = init_state_kernel(
|
2635
2783
|
rng=rng,
|
2636
2784
|
game_config=game_config,
|
2785
|
+
segments=get_segments(board_config),
|
2637
2786
|
edges=edges,
|
2638
2787
|
nodes=nodes,
|
2639
2788
|
decks=decks,
|
@@ -3288,8 +3437,9 @@ def handle_move_bonus_cards(kernel, action):
|
|
3288
3437
|
|
3289
3438
|
# Take a random walk on the player's graph. A node can be visiting more than once, but an edge cannot be visited more than once.
|
3290
3439
|
# Example graph: PlayerGraph(player_idx=0, neighbors=[[], [], [], [], [], [], [], [], [], [], [30]
|
3291
|
-
|
3292
|
-
|
3440
|
+
@dispatch(StateKernel, int)
|
3441
|
+
def random_player_graph_walk(kernel, player_idx):
|
3442
|
+
player_graph = kernel.player_graphs_3[player_idx]
|
3293
3443
|
nodes_indices_with_neighbors = [i for i, neighbors in enumerate(player_graph.neighbors) if neighbors]
|
3294
3444
|
|
3295
3445
|
if not nodes_indices_with_neighbors:
|
@@ -3524,18 +3674,19 @@ def handle_move_pieces_to_path_action(kernel, action):
|
|
3524
3674
|
return kernel
|
3525
3675
|
|
3526
3676
|
path_idx = move_pieces_to_path.path_idx
|
3527
|
-
|
3677
|
+
path_record = kernel.idx2pathrecord[path_idx]
|
3528
3678
|
|
3529
|
-
if
|
3679
|
+
if path_record is None or not path_record.segment_uuids:
|
3530
3680
|
return kernel
|
3531
3681
|
|
3532
|
-
for piece_uuid,
|
3682
|
+
for piece_uuid, segment_uuid in zip(default.piece_uuids, path_record.segment_uuids):
|
3683
|
+
segment_record = kernel.uuid2segmentrecord[segment_uuid]
|
3533
3684
|
# Find the piece in the player's pieces
|
3534
3685
|
piece_idx = next((i for i, player_piece_uuid in enumerate(player.pieces) if player_piece_uuid == piece_uuid), None)
|
3535
3686
|
if piece_idx is not None:
|
3536
3687
|
# Remove the piece from player's pieces
|
3537
3688
|
piece = player.pieces.pop(piece_idx)
|
3538
|
-
|
3689
|
+
segment_record.piece_uuids.append(piece)
|
3539
3690
|
|
3540
3691
|
for card_uuid in default.card_uuids:
|
3541
3692
|
# Find the card in the player's cards
|
@@ -3549,7 +3700,7 @@ def handle_move_pieces_to_path_action(kernel, action):
|
|
3549
3700
|
kernel = recycle_decks_if_needed(kernel)
|
3550
3701
|
kernel = replenish_decks_if_needed(kernel)
|
3551
3702
|
kernel = kernel.set(players=kernel.players)
|
3552
|
-
kernel = kernel.set(
|
3703
|
+
kernel = kernel.set(idx2pathrecord=kernel.idx2pathrecord)
|
3553
3704
|
|
3554
3705
|
return kernel
|
3555
3706
|
|
@@ -3835,10 +3986,10 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3835
3986
|
player_idx = action.legal_action.player_idx
|
3836
3987
|
proposed_cards_uuids = action.move_pieces_to_path.card_uuids
|
3837
3988
|
path_idx = action.legal_action.move_pieces_to_path.path_idx
|
3838
|
-
|
3989
|
+
path_record = state.kernel.idx2pathrecord[path_idx]
|
3839
3990
|
proposed_cards = [card_uuid for card_uuid in state.kernel.players[player_idx].cards if card_uuid in proposed_cards_uuids]
|
3840
3991
|
proposed_pieces = [piece_uuid for piece_uuid in state.kernel.players[player_idx].pieces if piece_uuid in action.move_pieces_to_path.piece_uuids]
|
3841
|
-
|
3992
|
+
remaining_segment_records = [state.kernel.uuid2segmentrecord[segment_uuid] for segment_uuid in path_record.segment_uuids]
|
3842
3993
|
|
3843
3994
|
# print("******************************1234 is_move_pieces_to_path_action_legal 1b: ", proposed_cards)
|
3844
3995
|
# print("******************************1234 is_move_pieces_to_path_action_legal 1c: ", proposed_pieces)
|
@@ -3848,7 +3999,7 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3848
3999
|
state.kernel,
|
3849
4000
|
proposed_cards,
|
3850
4001
|
proposed_pieces,
|
3851
|
-
|
4002
|
+
remaining_segment_records,
|
3852
4003
|
)
|
3853
4004
|
|
3854
4005
|
# print("******************************1234 is_move_pieces_to_path_action_legal 2a", card_fulfillment)
|
@@ -3869,7 +4020,7 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3869
4020
|
|
3870
4021
|
@dispatch(StateKernel)
|
3871
4022
|
def get_total_path_count(kernel):
|
3872
|
-
return len(kernel.
|
4023
|
+
return len(kernel.idx2pathrecord)
|
3873
4024
|
|
3874
4025
|
|
3875
4026
|
@dispatch(StateKernel, int, int)
|
@@ -3916,16 +4067,18 @@ def get_legal_actions_for_paths(kernel, player_idx):
|
|
3916
4067
|
return legal_actions
|
3917
4068
|
|
3918
4069
|
|
3919
|
-
@dispatch(StateKernel,
|
3920
|
-
def get_player_idxs_on_edge(kernel,
|
4070
|
+
@dispatch(StateKernel, BiEdgeRecord)
|
4071
|
+
def get_player_idxs_on_edge(kernel, edge_record):
|
3921
4072
|
player_idxs = set()
|
3922
|
-
if not
|
4073
|
+
if not edge_record or not edge_record.path_idxs:
|
3923
4074
|
return list(player_idxs)
|
3924
4075
|
|
3925
|
-
for
|
3926
|
-
|
3927
|
-
|
3928
|
-
|
4076
|
+
for path_idx in edge_record.path_idxs:
|
4077
|
+
path_record = kernel.idx2pathrecord[path_idx]
|
4078
|
+
for segment_uuid in path_record.segment_uuids:
|
4079
|
+
segment = kernel.uuid2segmentrecord[segment_uuid]
|
4080
|
+
if segment.piece_uuids and segment.piece_uuids[0]:
|
4081
|
+
piece = kernel.pieceuuid2piece[segment.piece_uuids[0]]
|
3929
4082
|
if piece:
|
3930
4083
|
player_idxs.add(piece.player_idx)
|
3931
4084
|
|
@@ -3937,11 +4090,10 @@ def is_path_open_to_player(state_kernel, path_idx, player_idx):
|
|
3937
4090
|
if not state_kernel or path_idx < 0 or get_total_path_count(state_kernel) <= path_idx:
|
3938
4091
|
return False
|
3939
4092
|
|
3940
|
-
|
3941
|
-
|
3942
|
-
edge = state_kernel.edges[edge_idx]
|
4093
|
+
path_record = state_kernel.idx2pathrecord[path_idx]
|
4094
|
+
edge_record = state_kernel.uuid2edgerecord[path_record.edge_uuid]
|
3943
4095
|
|
3944
|
-
player_idxs_on_edge = get_player_idxs_on_edge(state_kernel,
|
4096
|
+
player_idxs_on_edge = get_player_idxs_on_edge(state_kernel, edge_record)
|
3945
4097
|
|
3946
4098
|
# Check if edge is too crowded for the number of players
|
3947
4099
|
if state_kernel.game_config.num_players <= 3:
|
@@ -3952,12 +4104,14 @@ def is_path_open_to_player(state_kernel, path_idx, player_idx):
|
|
3952
4104
|
return False
|
3953
4105
|
|
3954
4106
|
# Check if any segment of the path has pieces from any player
|
3955
|
-
|
3956
|
-
|
4107
|
+
for segment_uuid in path_record.segment_uuids:
|
4108
|
+
segment_record = state_kernel.uuid2segmentrecord[segment_uuid]
|
4109
|
+
if segment_record.piece_uuids:
|
4110
|
+
return False
|
3957
4111
|
|
3958
4112
|
# Check if the player has enough pieces to claim the path
|
3959
4113
|
player_pieces = state_kernel.players[player_idx].pieces
|
3960
|
-
if len(player_pieces) < len(
|
4114
|
+
if len(player_pieces) < len(path_record.segment_uuids):
|
3961
4115
|
return False
|
3962
4116
|
|
3963
4117
|
return True
|
@@ -4009,68 +4163,68 @@ def get_wild_unit_uuids(state_kernel):
|
|
4009
4163
|
|
4010
4164
|
|
4011
4165
|
@dispatch(StateKernel, list, list, list)
|
4012
|
-
def match_strict_wild(state_kernel, fulfillment, cards,
|
4166
|
+
def match_strict_wild(state_kernel, fulfillment, cards, segment_records):
|
4013
4167
|
new_fulfillment = fulfillment.copy()
|
4014
4168
|
new_cards = cards.copy()
|
4015
4169
|
wild_unit_uuids = get_wild_unit_uuids(state_kernel)
|
4016
|
-
|
4170
|
+
new_segment_records = []
|
4017
4171
|
|
4018
|
-
for
|
4019
|
-
if
|
4020
|
-
first_matching_idx = next((i for i, card_uuid in enumerate(new_cards) if state_kernel.carduuid2card[card_uuid].resource_uuid ==
|
4172
|
+
for segment_record in segment_records:
|
4173
|
+
if segment_record.unit_uuid and segment_record.unit_uuid in wild_unit_uuids:
|
4174
|
+
first_matching_idx = next((i for i, card_uuid in enumerate(new_cards) if state_kernel.carduuid2card[card_uuid].resource_uuid == segment_record.unit_uuid), None)
|
4021
4175
|
if first_matching_idx is not None:
|
4022
4176
|
new_fulfillment.append(new_cards.pop(first_matching_idx))
|
4023
4177
|
else:
|
4024
|
-
|
4178
|
+
new_segment_records.append(segment_record)
|
4025
4179
|
else:
|
4026
|
-
|
4180
|
+
new_segment_records.append(segment_record)
|
4027
4181
|
|
4028
|
-
return new_fulfillment, new_cards,
|
4182
|
+
return new_fulfillment, new_cards, new_segment_records
|
4029
4183
|
|
4030
4184
|
@dispatch(StateKernel, list, list, list)
|
4031
|
-
def match_non_wild_non_empty(state_kernel, fulfillment, cards,
|
4185
|
+
def match_non_wild_non_empty(state_kernel, fulfillment, cards, segment_records):
|
4032
4186
|
new_fulfillment = fulfillment.copy()
|
4033
4187
|
new_cards = cards.copy()
|
4034
4188
|
wild_unit_uuids = get_wild_unit_uuids(state_kernel)
|
4035
|
-
|
4189
|
+
new_segment_records = []
|
4036
4190
|
|
4037
|
-
for
|
4038
|
-
first_strict_matching_idx = next((i for i, card_uuid in enumerate(new_cards) if state_kernel.carduuid2card[card_uuid].resource_uuid ==
|
4191
|
+
for segment_record in segment_records:
|
4192
|
+
first_strict_matching_idx = next((i for i, card_uuid in enumerate(new_cards) if state_kernel.carduuid2card[card_uuid].resource_uuid == segment_record.unit_uuid), None)
|
4039
4193
|
first_wild_matching_idx = next((i for i, card_uuid in enumerate(new_cards) if state_kernel.carduuid2card[card_uuid].resource_uuid in wild_unit_uuids), None)
|
4040
4194
|
first_matching_idx = first_strict_matching_idx if first_strict_matching_idx is not None else first_wild_matching_idx
|
4041
4195
|
if first_matching_idx is not None:
|
4042
4196
|
new_fulfillment.append(new_cards.pop(first_matching_idx))
|
4043
4197
|
else:
|
4044
|
-
|
4198
|
+
new_segment_records.append(segment_record)
|
4045
4199
|
|
4046
|
-
return new_fulfillment, new_cards,
|
4200
|
+
return new_fulfillment, new_cards, new_segment_records
|
4047
4201
|
|
4048
4202
|
|
4049
4203
|
@dispatch(StateKernel, list, list, list)
|
4050
|
-
def match_empty(state_kernel, fulfillment, cards,
|
4051
|
-
|
4052
|
-
if
|
4053
|
-
return fulfillment, cards,
|
4204
|
+
def match_empty(state_kernel, fulfillment, cards, segment_records):
|
4205
|
+
num_empty_segment_records = sum(1 for segment_record in segment_records if segment_record.unit_uuid is None)
|
4206
|
+
if num_empty_segment_records == 0:
|
4207
|
+
return fulfillment, cards, segment_records
|
4054
4208
|
|
4055
|
-
tuples = get_uniform_sets(state_kernel, cards,
|
4209
|
+
tuples = get_uniform_sets(state_kernel, cards, num_empty_segment_records)
|
4056
4210
|
# print(f"****************************************** len(cards): {len(cards)}")
|
4057
4211
|
# print(f"****************************************** num_empty_segments: {num_empty_segments}")
|
4058
4212
|
# print(f"Found {len(tuples)} tuples for empty segments: {tuples}")
|
4059
4213
|
if len(tuples) == 0:
|
4060
|
-
return fulfillment, cards,
|
4214
|
+
return fulfillment, cards, segment_records
|
4061
4215
|
|
4062
4216
|
new_fulfillment = fulfillment.copy()
|
4063
4217
|
|
4064
|
-
|
4065
|
-
for
|
4066
|
-
if
|
4067
|
-
|
4218
|
+
new_segment_records = []
|
4219
|
+
for segment_record in segment_records:
|
4220
|
+
if segment_record.unit_uuid:
|
4221
|
+
new_segment_records.append(segment_record)
|
4068
4222
|
|
4069
|
-
first_tuple = tuples[0][:
|
4223
|
+
first_tuple = tuples[0][:num_empty_segment_records]
|
4070
4224
|
# print(f"Using first tuple for empty segments: {first_tuple}")
|
4071
4225
|
new_cards = list(set(cards) - set(first_tuple))
|
4072
4226
|
new_fulfillment.extend(first_tuple)
|
4073
|
-
return new_fulfillment, new_cards,
|
4227
|
+
return new_fulfillment, new_cards, new_segment_records
|
4074
4228
|
|
4075
4229
|
|
4076
4230
|
@dispatch(StateKernel, list, int)
|
@@ -4130,48 +4284,48 @@ def get_sample_actionclaimpath(game, player_idx, path_idx):
|
|
4130
4284
|
|
4131
4285
|
@dispatch(StateKernel, int, int)
|
4132
4286
|
def get_sample_path_fulfillment(kernel, player_idx, path_idx):
|
4133
|
-
|
4287
|
+
path_record = kernel.idx2pathrecord[path_idx]
|
4134
4288
|
remaining_card_uuids = [card_uuid for card_uuid in kernel.players[player_idx].cards if kernel.carduuid2card[card_uuid].deck_idx == 0]
|
4135
4289
|
remaining_pieces = [
|
4136
4290
|
piece_uuid
|
4137
4291
|
for piece_uuid in kernel.players[player_idx].pieces
|
4138
4292
|
if kernel.pieceuuid2piece[piece_uuid].piece_template_idx == 0
|
4139
4293
|
]
|
4140
|
-
|
4294
|
+
remaining_segment_records = [kernel.uuid2segmentrecord[segment_uuid] for segment_uuid in path_record.segment_uuids]
|
4141
4295
|
return get_path_fulfillment_from_resources(
|
4142
4296
|
kernel,
|
4143
4297
|
remaining_card_uuids,
|
4144
4298
|
remaining_pieces,
|
4145
|
-
|
4299
|
+
remaining_segment_records,
|
4146
4300
|
)
|
4147
4301
|
|
4148
4302
|
@dispatch(StateKernel, list, list, list)
|
4149
|
-
def get_path_fulfillment_from_resources(state_kernel, remaining_card_uuids, remaining_pieces,
|
4303
|
+
def get_path_fulfillment_from_resources(state_kernel, remaining_card_uuids, remaining_pieces, remaining_segment_records, log=False):
|
4150
4304
|
|
4151
|
-
if len(remaining_pieces) < len(
|
4305
|
+
if len(remaining_pieces) < len(remaining_segment_records):
|
4152
4306
|
print("Not enough pieces to fulfill the path segments")
|
4153
4307
|
return None, None
|
4154
4308
|
|
4155
|
-
piece_fulfillment = remaining_pieces[:len(
|
4309
|
+
piece_fulfillment = remaining_pieces[:len(remaining_segment_records)]
|
4156
4310
|
|
4157
4311
|
card_fulfillment = []
|
4158
|
-
card_fulfillment, remaining_card_uuids,
|
4312
|
+
card_fulfillment, remaining_card_uuids, remaining_segment_records = match_strict_wild(state_kernel, card_fulfillment, remaining_card_uuids, remaining_segment_records)
|
4159
4313
|
|
4160
|
-
if len(
|
4314
|
+
if len(remaining_segment_records) == 0:
|
4161
4315
|
return card_fulfillment, piece_fulfillment
|
4162
4316
|
# Probably don't need this check, but we should unit test
|
4163
4317
|
# elif len(get_wild_segments(remaining_segments)) > 0:
|
4164
4318
|
# return None
|
4165
4319
|
|
4166
|
-
card_fulfillment, remaining_card_uuids,
|
4167
|
-
if len(
|
4320
|
+
card_fulfillment, remaining_card_uuids, remaining_segment_records = match_non_wild_non_empty(state_kernel, card_fulfillment, remaining_card_uuids, remaining_segment_records)
|
4321
|
+
if len(remaining_segment_records) == 0:
|
4168
4322
|
return card_fulfillment, piece_fulfillment
|
4169
4323
|
# Probably don't need this check, but we should unit test
|
4170
4324
|
# elif len(get_non_wild_non_empty_segments(remaining_segments)) > 0:
|
4171
4325
|
# return None
|
4172
4326
|
|
4173
|
-
card_fulfillment, remaining_card_uuids,
|
4174
|
-
if len(
|
4327
|
+
card_fulfillment, remaining_card_uuids, remaining_segment_records = match_empty(state_kernel, card_fulfillment, remaining_card_uuids, remaining_segment_records)
|
4328
|
+
if len(remaining_segment_records) == 0:
|
4175
4329
|
return card_fulfillment, piece_fulfillment
|
4176
4330
|
|
4177
4331
|
# print("get_path_fulfillment_from_resources (None, None) because remaining_segments is not empty: ", remaining_segments)
|
@@ -4548,6 +4702,52 @@ def isterminal(s):
|
|
4548
4702
|
|
4549
4703
|
@dispatch(State)
|
4550
4704
|
def getpublicstate(s):
|
4705
|
+
k = s.kernel
|
4706
|
+
edges = []
|
4707
|
+
for edge_record in s.kernel.uuid2edgerecord.values():
|
4708
|
+
paths = []
|
4709
|
+
for path_idx in edge_record.path_idxs:
|
4710
|
+
path_record = k.idx2pathrecord[path_idx]
|
4711
|
+
segments = []
|
4712
|
+
for segment_uuid in path_record.segment_uuids:
|
4713
|
+
segment_record = k.uuid2segmentrecord[segment_uuid]
|
4714
|
+
pieces = []
|
4715
|
+
for piece_uuid in segment_record.piece_uuids:
|
4716
|
+
piece = k.pieceuuid2piece[piece_uuid]
|
4717
|
+
pieces.append(piece)
|
4718
|
+
segments.append(
|
4719
|
+
Segment2(
|
4720
|
+
uuid=segment_record.uuid,
|
4721
|
+
unit_uuid=segment_record.unit_uuid,
|
4722
|
+
pieces=pieces,
|
4723
|
+
)
|
4724
|
+
)
|
4725
|
+
paths.append(
|
4726
|
+
Path2(
|
4727
|
+
uuid=path_record.uuid,
|
4728
|
+
edge_uuid=path_record.edge_uuid,
|
4729
|
+
segments=segments,
|
4730
|
+
idx=path_record.idx
|
4731
|
+
)
|
4732
|
+
)
|
4733
|
+
|
4734
|
+
edge = BiEdge(
|
4735
|
+
uuid=edge_record.uuid,
|
4736
|
+
start_point_uuid=edge_record.start_point_uuid,
|
4737
|
+
end_point_uuid=edge_record.end_point_uuid,
|
4738
|
+
node_1_uuid=edge_record.node_1_uuid,
|
4739
|
+
node_2_uuid=edge_record.node_2_uuid,
|
4740
|
+
node_1_idx=edge_record.node_1_idx,
|
4741
|
+
node_2_idx=edge_record.node_2_idx,
|
4742
|
+
paths=paths,
|
4743
|
+
score=edge_record.score,
|
4744
|
+
)
|
4745
|
+
edges.append(edge)
|
4746
|
+
|
4747
|
+
# stopped here
|
4748
|
+
|
4749
|
+
|
4750
|
+
|
4551
4751
|
return PublicState(
|
4552
4752
|
deadlines=get_deadlines(s),
|
4553
4753
|
game_started_at=s.kernel.game_config.started_at,
|
@@ -4562,7 +4762,7 @@ def getpublicstate(s):
|
|
4562
4762
|
player_graphs=s.kernel.player_graphs_3,
|
4563
4763
|
goals=s.kernel.goals,
|
4564
4764
|
nodes=s.kernel.nodes,
|
4565
|
-
edges=
|
4765
|
+
edges=edges,
|
4566
4766
|
regions=s.kernel.regions,
|
4567
4767
|
decks=[getpublicdeck(s, deck) for deck in s.kernel.decks],
|
4568
4768
|
piles=s.kernel.piles,
|
@@ -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=
|
3
|
+
graph_games_proto/fns.py,sha256=vKVTt-EYziaIHajv8gxt5FMGTvQXW1eWh851DyxDyyY,201209
|
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.
|
7
|
-
graph_games_proto-0.3.
|
8
|
-
graph_games_proto-0.3.
|
9
|
-
graph_games_proto-0.3.
|
6
|
+
graph_games_proto-0.3.2077.dist-info/METADATA,sha256=o6EAHn38ZoToH0VTgQsZhG0xMVK6Zh3tFN7rbL20Y8o,188
|
7
|
+
graph_games_proto-0.3.2077.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
8
|
+
graph_games_proto-0.3.2077.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
|
9
|
+
graph_games_proto-0.3.2077.dist-info/RECORD,,
|
File without changes
|
File without changes
|