graph-games-proto 0.3.2050__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 +269 -70
- {graph_games_proto-0.3.2050.dist-info → graph_games_proto-0.3.2077.dist-info}/METADATA +1 -1
- {graph_games_proto-0.3.2050.dist-info → graph_games_proto-0.3.2077.dist-info}/RECORD +5 -5
- {graph_games_proto-0.3.2050.dist-info → graph_games_proto-0.3.2077.dist-info}/WHEEL +0 -0
- {graph_games_proto-0.3.2050.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,
|
@@ -3525,18 +3674,19 @@ def handle_move_pieces_to_path_action(kernel, action):
|
|
3525
3674
|
return kernel
|
3526
3675
|
|
3527
3676
|
path_idx = move_pieces_to_path.path_idx
|
3528
|
-
|
3677
|
+
path_record = kernel.idx2pathrecord[path_idx]
|
3529
3678
|
|
3530
|
-
if
|
3679
|
+
if path_record is None or not path_record.segment_uuids:
|
3531
3680
|
return kernel
|
3532
3681
|
|
3533
|
-
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]
|
3534
3684
|
# Find the piece in the player's pieces
|
3535
3685
|
piece_idx = next((i for i, player_piece_uuid in enumerate(player.pieces) if player_piece_uuid == piece_uuid), None)
|
3536
3686
|
if piece_idx is not None:
|
3537
3687
|
# Remove the piece from player's pieces
|
3538
3688
|
piece = player.pieces.pop(piece_idx)
|
3539
|
-
|
3689
|
+
segment_record.piece_uuids.append(piece)
|
3540
3690
|
|
3541
3691
|
for card_uuid in default.card_uuids:
|
3542
3692
|
# Find the card in the player's cards
|
@@ -3550,7 +3700,7 @@ def handle_move_pieces_to_path_action(kernel, action):
|
|
3550
3700
|
kernel = recycle_decks_if_needed(kernel)
|
3551
3701
|
kernel = replenish_decks_if_needed(kernel)
|
3552
3702
|
kernel = kernel.set(players=kernel.players)
|
3553
|
-
kernel = kernel.set(
|
3703
|
+
kernel = kernel.set(idx2pathrecord=kernel.idx2pathrecord)
|
3554
3704
|
|
3555
3705
|
return kernel
|
3556
3706
|
|
@@ -3836,10 +3986,10 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3836
3986
|
player_idx = action.legal_action.player_idx
|
3837
3987
|
proposed_cards_uuids = action.move_pieces_to_path.card_uuids
|
3838
3988
|
path_idx = action.legal_action.move_pieces_to_path.path_idx
|
3839
|
-
|
3989
|
+
path_record = state.kernel.idx2pathrecord[path_idx]
|
3840
3990
|
proposed_cards = [card_uuid for card_uuid in state.kernel.players[player_idx].cards if card_uuid in proposed_cards_uuids]
|
3841
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]
|
3842
|
-
|
3992
|
+
remaining_segment_records = [state.kernel.uuid2segmentrecord[segment_uuid] for segment_uuid in path_record.segment_uuids]
|
3843
3993
|
|
3844
3994
|
# print("******************************1234 is_move_pieces_to_path_action_legal 1b: ", proposed_cards)
|
3845
3995
|
# print("******************************1234 is_move_pieces_to_path_action_legal 1c: ", proposed_pieces)
|
@@ -3849,7 +3999,7 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3849
3999
|
state.kernel,
|
3850
4000
|
proposed_cards,
|
3851
4001
|
proposed_pieces,
|
3852
|
-
|
4002
|
+
remaining_segment_records,
|
3853
4003
|
)
|
3854
4004
|
|
3855
4005
|
# print("******************************1234 is_move_pieces_to_path_action_legal 2a", card_fulfillment)
|
@@ -3870,7 +4020,7 @@ def is_move_pieces_to_path_action_legal(state, action):
|
|
3870
4020
|
|
3871
4021
|
@dispatch(StateKernel)
|
3872
4022
|
def get_total_path_count(kernel):
|
3873
|
-
return len(kernel.
|
4023
|
+
return len(kernel.idx2pathrecord)
|
3874
4024
|
|
3875
4025
|
|
3876
4026
|
@dispatch(StateKernel, int, int)
|
@@ -3917,16 +4067,18 @@ def get_legal_actions_for_paths(kernel, player_idx):
|
|
3917
4067
|
return legal_actions
|
3918
4068
|
|
3919
4069
|
|
3920
|
-
@dispatch(StateKernel,
|
3921
|
-
def get_player_idxs_on_edge(kernel,
|
4070
|
+
@dispatch(StateKernel, BiEdgeRecord)
|
4071
|
+
def get_player_idxs_on_edge(kernel, edge_record):
|
3922
4072
|
player_idxs = set()
|
3923
|
-
if not
|
4073
|
+
if not edge_record or not edge_record.path_idxs:
|
3924
4074
|
return list(player_idxs)
|
3925
4075
|
|
3926
|
-
for
|
3927
|
-
|
3928
|
-
|
3929
|
-
|
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]]
|
3930
4082
|
if piece:
|
3931
4083
|
player_idxs.add(piece.player_idx)
|
3932
4084
|
|
@@ -3938,11 +4090,10 @@ def is_path_open_to_player(state_kernel, path_idx, player_idx):
|
|
3938
4090
|
if not state_kernel or path_idx < 0 or get_total_path_count(state_kernel) <= path_idx:
|
3939
4091
|
return False
|
3940
4092
|
|
3941
|
-
|
3942
|
-
|
3943
|
-
edge = state_kernel.edges[edge_idx]
|
4093
|
+
path_record = state_kernel.idx2pathrecord[path_idx]
|
4094
|
+
edge_record = state_kernel.uuid2edgerecord[path_record.edge_uuid]
|
3944
4095
|
|
3945
|
-
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)
|
3946
4097
|
|
3947
4098
|
# Check if edge is too crowded for the number of players
|
3948
4099
|
if state_kernel.game_config.num_players <= 3:
|
@@ -3953,12 +4104,14 @@ def is_path_open_to_player(state_kernel, path_idx, player_idx):
|
|
3953
4104
|
return False
|
3954
4105
|
|
3955
4106
|
# Check if any segment of the path has pieces from any player
|
3956
|
-
|
3957
|
-
|
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
|
3958
4111
|
|
3959
4112
|
# Check if the player has enough pieces to claim the path
|
3960
4113
|
player_pieces = state_kernel.players[player_idx].pieces
|
3961
|
-
if len(player_pieces) < len(
|
4114
|
+
if len(player_pieces) < len(path_record.segment_uuids):
|
3962
4115
|
return False
|
3963
4116
|
|
3964
4117
|
return True
|
@@ -4010,68 +4163,68 @@ def get_wild_unit_uuids(state_kernel):
|
|
4010
4163
|
|
4011
4164
|
|
4012
4165
|
@dispatch(StateKernel, list, list, list)
|
4013
|
-
def match_strict_wild(state_kernel, fulfillment, cards,
|
4166
|
+
def match_strict_wild(state_kernel, fulfillment, cards, segment_records):
|
4014
4167
|
new_fulfillment = fulfillment.copy()
|
4015
4168
|
new_cards = cards.copy()
|
4016
4169
|
wild_unit_uuids = get_wild_unit_uuids(state_kernel)
|
4017
|
-
|
4170
|
+
new_segment_records = []
|
4018
4171
|
|
4019
|
-
for
|
4020
|
-
if
|
4021
|
-
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)
|
4022
4175
|
if first_matching_idx is not None:
|
4023
4176
|
new_fulfillment.append(new_cards.pop(first_matching_idx))
|
4024
4177
|
else:
|
4025
|
-
|
4178
|
+
new_segment_records.append(segment_record)
|
4026
4179
|
else:
|
4027
|
-
|
4180
|
+
new_segment_records.append(segment_record)
|
4028
4181
|
|
4029
|
-
return new_fulfillment, new_cards,
|
4182
|
+
return new_fulfillment, new_cards, new_segment_records
|
4030
4183
|
|
4031
4184
|
@dispatch(StateKernel, list, list, list)
|
4032
|
-
def match_non_wild_non_empty(state_kernel, fulfillment, cards,
|
4185
|
+
def match_non_wild_non_empty(state_kernel, fulfillment, cards, segment_records):
|
4033
4186
|
new_fulfillment = fulfillment.copy()
|
4034
4187
|
new_cards = cards.copy()
|
4035
4188
|
wild_unit_uuids = get_wild_unit_uuids(state_kernel)
|
4036
|
-
|
4189
|
+
new_segment_records = []
|
4037
4190
|
|
4038
|
-
for
|
4039
|
-
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)
|
4040
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)
|
4041
4194
|
first_matching_idx = first_strict_matching_idx if first_strict_matching_idx is not None else first_wild_matching_idx
|
4042
4195
|
if first_matching_idx is not None:
|
4043
4196
|
new_fulfillment.append(new_cards.pop(first_matching_idx))
|
4044
4197
|
else:
|
4045
|
-
|
4198
|
+
new_segment_records.append(segment_record)
|
4046
4199
|
|
4047
|
-
return new_fulfillment, new_cards,
|
4200
|
+
return new_fulfillment, new_cards, new_segment_records
|
4048
4201
|
|
4049
4202
|
|
4050
4203
|
@dispatch(StateKernel, list, list, list)
|
4051
|
-
def match_empty(state_kernel, fulfillment, cards,
|
4052
|
-
|
4053
|
-
if
|
4054
|
-
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
|
4055
4208
|
|
4056
|
-
tuples = get_uniform_sets(state_kernel, cards,
|
4209
|
+
tuples = get_uniform_sets(state_kernel, cards, num_empty_segment_records)
|
4057
4210
|
# print(f"****************************************** len(cards): {len(cards)}")
|
4058
4211
|
# print(f"****************************************** num_empty_segments: {num_empty_segments}")
|
4059
4212
|
# print(f"Found {len(tuples)} tuples for empty segments: {tuples}")
|
4060
4213
|
if len(tuples) == 0:
|
4061
|
-
return fulfillment, cards,
|
4214
|
+
return fulfillment, cards, segment_records
|
4062
4215
|
|
4063
4216
|
new_fulfillment = fulfillment.copy()
|
4064
4217
|
|
4065
|
-
|
4066
|
-
for
|
4067
|
-
if
|
4068
|
-
|
4218
|
+
new_segment_records = []
|
4219
|
+
for segment_record in segment_records:
|
4220
|
+
if segment_record.unit_uuid:
|
4221
|
+
new_segment_records.append(segment_record)
|
4069
4222
|
|
4070
|
-
first_tuple = tuples[0][:
|
4223
|
+
first_tuple = tuples[0][:num_empty_segment_records]
|
4071
4224
|
# print(f"Using first tuple for empty segments: {first_tuple}")
|
4072
4225
|
new_cards = list(set(cards) - set(first_tuple))
|
4073
4226
|
new_fulfillment.extend(first_tuple)
|
4074
|
-
return new_fulfillment, new_cards,
|
4227
|
+
return new_fulfillment, new_cards, new_segment_records
|
4075
4228
|
|
4076
4229
|
|
4077
4230
|
@dispatch(StateKernel, list, int)
|
@@ -4131,48 +4284,48 @@ def get_sample_actionclaimpath(game, player_idx, path_idx):
|
|
4131
4284
|
|
4132
4285
|
@dispatch(StateKernel, int, int)
|
4133
4286
|
def get_sample_path_fulfillment(kernel, player_idx, path_idx):
|
4134
|
-
|
4287
|
+
path_record = kernel.idx2pathrecord[path_idx]
|
4135
4288
|
remaining_card_uuids = [card_uuid for card_uuid in kernel.players[player_idx].cards if kernel.carduuid2card[card_uuid].deck_idx == 0]
|
4136
4289
|
remaining_pieces = [
|
4137
4290
|
piece_uuid
|
4138
4291
|
for piece_uuid in kernel.players[player_idx].pieces
|
4139
4292
|
if kernel.pieceuuid2piece[piece_uuid].piece_template_idx == 0
|
4140
4293
|
]
|
4141
|
-
|
4294
|
+
remaining_segment_records = [kernel.uuid2segmentrecord[segment_uuid] for segment_uuid in path_record.segment_uuids]
|
4142
4295
|
return get_path_fulfillment_from_resources(
|
4143
4296
|
kernel,
|
4144
4297
|
remaining_card_uuids,
|
4145
4298
|
remaining_pieces,
|
4146
|
-
|
4299
|
+
remaining_segment_records,
|
4147
4300
|
)
|
4148
4301
|
|
4149
4302
|
@dispatch(StateKernel, list, list, list)
|
4150
|
-
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):
|
4151
4304
|
|
4152
|
-
if len(remaining_pieces) < len(
|
4305
|
+
if len(remaining_pieces) < len(remaining_segment_records):
|
4153
4306
|
print("Not enough pieces to fulfill the path segments")
|
4154
4307
|
return None, None
|
4155
4308
|
|
4156
|
-
piece_fulfillment = remaining_pieces[:len(
|
4309
|
+
piece_fulfillment = remaining_pieces[:len(remaining_segment_records)]
|
4157
4310
|
|
4158
4311
|
card_fulfillment = []
|
4159
|
-
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)
|
4160
4313
|
|
4161
|
-
if len(
|
4314
|
+
if len(remaining_segment_records) == 0:
|
4162
4315
|
return card_fulfillment, piece_fulfillment
|
4163
4316
|
# Probably don't need this check, but we should unit test
|
4164
4317
|
# elif len(get_wild_segments(remaining_segments)) > 0:
|
4165
4318
|
# return None
|
4166
4319
|
|
4167
|
-
card_fulfillment, remaining_card_uuids,
|
4168
|
-
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:
|
4169
4322
|
return card_fulfillment, piece_fulfillment
|
4170
4323
|
# Probably don't need this check, but we should unit test
|
4171
4324
|
# elif len(get_non_wild_non_empty_segments(remaining_segments)) > 0:
|
4172
4325
|
# return None
|
4173
4326
|
|
4174
|
-
card_fulfillment, remaining_card_uuids,
|
4175
|
-
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:
|
4176
4329
|
return card_fulfillment, piece_fulfillment
|
4177
4330
|
|
4178
4331
|
# print("get_path_fulfillment_from_resources (None, None) because remaining_segments is not empty: ", remaining_segments)
|
@@ -4549,6 +4702,52 @@ def isterminal(s):
|
|
4549
4702
|
|
4550
4703
|
@dispatch(State)
|
4551
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
|
+
|
4552
4751
|
return PublicState(
|
4553
4752
|
deadlines=get_deadlines(s),
|
4554
4753
|
game_started_at=s.kernel.game_config.started_at,
|
@@ -4563,7 +4762,7 @@ def getpublicstate(s):
|
|
4563
4762
|
player_graphs=s.kernel.player_graphs_3,
|
4564
4763
|
goals=s.kernel.goals,
|
4565
4764
|
nodes=s.kernel.nodes,
|
4566
|
-
edges=
|
4765
|
+
edges=edges,
|
4567
4766
|
regions=s.kernel.regions,
|
4568
4767
|
decks=[getpublicdeck(s, deck) for deck in s.kernel.decks],
|
4569
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
|