graph-games-proto 0.3.1739__py3-none-any.whl → 0.3.1741__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
@@ -2678,7 +2678,7 @@ def autoplay(seed, fig, num_players, policy, log=False):
2678
2678
  a = getnextaction(s, policy)
2679
2679
  if log:
2680
2680
  printaction(a, getstateidx(s))
2681
- s = getnextstate(s, a)
2681
+ s = getnextstate2(s, a)
2682
2682
  actions.append(a)
2683
2683
 
2684
2684
  if (log):
@@ -4236,16 +4236,6 @@ def getfaceupspots(f, unit_deck, unit_deck_idx):
4236
4236
  return unit_deck[unit_deck_idx:(unit_deck_idx + num_faceup_spots)] if unit_deck_idx < len(unit_deck) else []
4237
4237
 
4238
4238
 
4239
- @dispatch(GameConfig, list, bool)
4240
- def getstate(game_config, actions, log):
4241
- return reduce(lambda state, action: getnextstate(state, action, log), actions, getinitialstate(game_config))
4242
-
4243
-
4244
- @dispatch(State, AltAction, NoAction)
4245
- def getnextstate(s, action, action_type):
4246
- return s
4247
-
4248
-
4249
4239
  # Implementing the following Julia function:
4250
4240
  # getpath(f::Fig, num::Int) = f.board_config.board_paths[num]
4251
4241
  def getpath(f, num):
@@ -4254,484 +4244,15 @@ def getpath(f, num):
4254
4244
  raise ValueError(f"Path number {num} not found in board config.")
4255
4245
 
4256
4246
 
4257
- # Implementing the following Julia function:
4258
- # function getnextstate(s::State, a::Action, ::Val{:CLAIM_PATH})
4259
- # player_hand_idx = findfirst(p -> p.player_idx == a.player_idx, s.player_hands)
4260
- # player_hand = s.player_hands[player_hand_idx]
4261
- # num_path_pieces = getpath(s.fig, a.path_idx).path.segments |> length
4262
- # @reset player_hand.num_pieces = player_hand.num_pieces - num_path_pieces
4263
- # new_unit_cards, new_discards = removecombo(player_hand, a.unit_combo)
4264
- # @reset s.unit_discards = [s.unit_discards..., new_discards...]
4265
- # @reset player_hand.unit_cards = new_unit_cards
4266
- # @reset player_hand.paths = [player_hand.paths..., a.path_idx]
4267
- # @reset player_hand.completed_routes = getcompletedroutes(s.fig, player_hand)
4268
- # longest_trail, longest_trail_len = getlongesttrail(s.fig, player_hand)
4269
- # @reset player_hand.longest_trail = longest_trail
4270
- # @reset player_hand.longest_trail_len = longest_trail_len
4271
- # @reset s.player_hands = [p.player_idx == a.player_idx ? player_hand : p for p in s.player_hands]
4272
- # @reset s.longest_trail_player_idxs = getlongesttrailplayeridxs(s.player_hands)
4273
- # @reset s.most_clusters_player_idxs = getmostclustersplayeridxs(s.player_hands)
4274
- # s
4275
- # end
4276
- @dispatch(State, AltAction, MovePiecesToPathAction)
4277
- def getnextstate(s, action, action_type):
4278
- player_hand_idx = next((i for i, p in enumerate(s.player_hands) if p.player_idx == action.player_idx), None)
4279
- if player_hand_idx is None:
4280
- raise ValueError(f"Player index {action.player_idx} not found in player hands.")
4281
-
4282
- player_hand = s.player_hands[player_hand_idx]
4283
- num_path_pieces = len(getpath(s.game_config.fig, action.path_idx).path.segments)
4284
- # @reset player_hand.num_pieces = player_hand.num_pieces - num_path_pieces
4285
- player_hand = player_hand.set(num_pieces=player_hand.num_pieces - num_path_pieces)
4286
-
4287
- # new_unit_cards, new_discards = removecombo(player_hand, a.unit_combo)
4288
- new_unit_cards, new_discards = pvector([]), pvector([])
4289
- if action.unit_combo:
4290
- new_unit_cards, new_discards = removecombo(player_hand, action.unit_combo)
4291
- # @reset s.unit_discards = [s.unit_discards..., new_discards...]
4292
- s = s.set(unit_discards=s.unit_discards.extend(new_discards))
4293
- # @reset player_hand.unit_cards = new_unit_cards
4294
- player_hand = player_hand.set(unit_cards=new_unit_cards)
4295
- # @reset player_hand.paths = [player_hand.paths..., a.path_idx]
4296
- player_hand = player_hand.set(paths=player_hand.paths + [action.path_idx])
4297
- # @reset player_hand.completed_routes = getcompletedroutes(s.fig, player_hand)
4298
-
4299
- if len(s.game_config.fig.board_config.routes) > 0:
4300
- player_hand = player_hand.set(completed_routes=getcompletedroutes(s.game_config.fig, player_hand))
4301
-
4302
- ###longest_trail, longest_trail_len = getlongesttrail(s.game_config.fig, player_hand)
4303
- # @reset player_hand.longest_trail = longest_trail
4304
- ###player_hand = player_hand.set(longest_trail=longest_trail)
4305
- # @reset player_hand.longest_trail_len = longest_trail_len
4306
- ###player_hand = player_hand.set(longest_trail_len=longest_trail_len)
4307
-
4308
- # Implementing the following Julia function:
4309
- # @reset s.player_hands = [p.player_idx == a.player_idx ? player_hand : p for p in s.player_hands]
4310
- s = s.transform(
4311
- ('player_hands', player_hand_idx),
4312
- player_hand.set(player_idx=player_hand.player_idx),
4313
- )
4314
-
4315
- # @reset s.longest_trail_player_idxs = getlongesttrailplayeridxs(s.player_hands)
4316
- ###s = s.set(longest_trail_player_idxs=getlongesttrailplayeridxs(s.player_hands))
4317
- # @reset s.most_clusters_player_idxs = getmostclustersplayeridxs(s.player_hands)
4318
- s = s.set(most_clusters_player_idxs=getmostclustersplayeridxs(s.player_hands))
4319
- return s
4320
-
4321
-
4322
- def getlinkadjmat(fig, paths):
4323
- path2edgeidx = {}
4324
- edgeidx2edge = {}
4325
- for frozen_path in fig.board_config.board_paths:
4326
- edge_num = frozen_path.link_num
4327
- path_num = frozen_path.num
4328
- path2edgeidx[path_num - 1] = edge_num - 1
4329
- edgeidx2edge[edge_num - 1] = (frozen_path.start_point_num-1, frozen_path.end_point_num-1)
4330
-
4331
- num_nodes = len(fig.board_config.points)
4332
- adj_mat = np.eye(num_nodes, dtype=int)
4333
-
4334
- # print("path2edgeidx: ", path2edgeidx)
4335
- # print("\nedgeidx2edge: ", edgeidx2edge)
4336
-
4337
- for path_idx in paths:
4338
- edge_idx = path2edgeidx[path_idx]
4339
- src, dst = edgeidx2edge[edge_idx]
4340
- adj_mat[src, dst] = 1
4341
- adj_mat[dst, src] = 1
4342
-
4343
- return adj_mat
4344
-
4345
-
4346
- def getcompletedroutes(fig, player_hand, log=False):
4347
- adj_mat = getlinkadjmat(fig, player_hand.paths)
4348
-
4349
- if False:
4350
- print("\nadj_mat:")
4351
- print(adj_mat)
4352
-
4353
- route_nums = player_hand.route_cards
4354
- routes = fig.board_config.routes
4355
- num_points = len(fig.board_config.points)
4356
-
4357
- # print("route_nums: ", route_nums)
4358
-
4359
- visited_nodes = np.column_stack([
4360
- np.eye(1, num_points, routes[route_num - 1].start_num, dtype=int).flatten()
4361
- for route_num in route_nums
4362
- ])
4363
-
4364
- target_nodes = np.column_stack([
4365
- np.eye(1, num_points, routes[route_num - 1].end_num, dtype=int).flatten()
4366
- for route_num in route_nums
4367
- ])
4368
-
4369
- if False:
4370
- print("\nvisited_nodes:")
4371
- print(visited_nodes)
4372
- print("\ntarget_nodes:")
4373
- print(target_nodes)
4374
-
4375
- for _ in range(len(player_hand.paths)):
4376
- visited_nodes = (adj_mat @ visited_nodes) > 0
4377
-
4378
- res = visited_nodes & target_nodes
4379
-
4380
- if log:
4381
- print("\nres:")
4382
- print(res)
4383
-
4384
- bools = np.any(res, axis=0)
4385
- completed = [route_num for route_num, completed_bool in zip(route_nums, bools) if completed_bool]
4386
-
4387
- return completed
4388
-
4389
-
4390
-
4391
- # Implementing the following Julia function:
4392
- # function getnextstate(s::State, a::Action, ::Val{:CLAIM_POINT})
4393
- # player_hand_idx = findfirst(p -> p.player_idx == a.player_idx, s.player_hands)
4394
- # player_hand = s.player_hands[player_hand_idx]
4395
- # @reset player_hand.num_point_pieces = player_hand.num_point_pieces - 1
4396
- # new_unit_cards, new_discards = removecombo(player_hand, a.unit_combo)
4397
- # @reset s.unit_discards = [s.unit_discards..., new_discards...]
4398
- # @reset player_hand.unit_cards = new_unit_cards
4399
- # @reset player_hand.points = [player_hand.points..., a.point_uuid]
4400
- # @reset player_hand.completed_clusters = getcompletedclusters(s.fig, player_hand)
4401
- # @reset s.player_hands = [p.player_idx == a.player_idx ? player_hand : p for p in s.player_hands]
4402
- # @reset s.most_clusters_player_idxs = getmostclustersplayeridxs(s.player_hands)
4403
- # s
4404
- # end
4405
- @dispatch(State, AltAction, ClaimPointAction)
4406
- def getnextstate(s, action, action_type):
4407
- player_hand_idx = next((i for i, p in enumerate(s.player_hands) if p.player_idx == action.player_idx), None)
4408
- if player_hand_idx is None:
4409
- raise ValueError(f"Player index {action.player_idx} not found in player hands.")
4410
-
4411
- player_hand = s.player_hands[player_hand_idx]
4412
- # @reset player_hand.num_point_pieces = player_hand.num_point_pieces - 1
4413
- player_hand = player_hand.set(num_point_pieces=player_hand.num_point_pieces - 1)
4414
-
4415
- # new_unit_cards, new_discards = removecombo(player_hand, a.unit_combo)
4416
- new_unit_cards, new_discards = pvector([]), pvector([])
4417
- if action.unit_combo:
4418
- new_unit_cards, new_discards = removecombo(player_hand, action.unit_combo)
4419
- # @reset s.unit_discards = [s.unit_discards..., new_discards...]
4420
- s = s.set(unit_discards=s.unit_discards.extend(new_discards))
4421
- # @reset player_hand.unit_cards = new_unit_cards
4422
- player_hand = player_hand.set(unit_cards=new_unit_cards)
4423
- # @reset player_hand.points = [player_hand.points..., a.point_uuid]
4424
- player_hand = player_hand.set(points=player_hand.points + [action.point_uuid])
4425
- # @reset player_hand.completed_clusters = getcompletedclusters(s.fig, player_hand)
4426
- player_hand = player_hand.set(completed_clusters=getcompletedclusters(s.game_config.fig, player_hand))
4427
- # @reset s.player_hands = [p.player_idx == a.player_idx ? player_hand : p for p in s.player_hands]
4428
- s = s.transform(
4429
- ('player_hands', player_hand_idx),
4430
- player_hand.set(player_idx=player_hand.player_idx),
4431
- )
4432
- # @reset s.most_clusters_player_idxs = getmostclustersplayeridxs(s.player_hands)
4433
- s = s.set(most_clusters_player_idxs=getmostclustersplayeridxs(s.player_hands))
4434
-
4435
- return s
4436
-
4437
-
4438
- # Implementing the following Julia function:
4439
- # function getmostclustersplayeridxs(player_hands::Vector{PlayerInfo})
4440
- # most_clusters = maximum([length(p.completed_clusters) for p in player_hands])
4441
- # if iszero(most_clusters)
4442
- # return Int[]
4443
- # end
4444
- # [p.player_idx for p in player_hands if length(p.completed_clusters) == most_clusters]
4445
- # end
4446
- def getmostclustersplayeridxs(player_hands):
4447
- most_clusters = max(len(p.completed_clusters) for p in player_hands)
4448
- if most_clusters == 0:
4449
- return []
4450
- return [p.player_idx for p in player_hands if len(p.completed_clusters) == most_clusters]
4451
-
4452
-
4453
- # Implementing the following Julia function:
4454
- # function getcompletedclusters(fig::Fig, player_hand::PlayerInfo; log=false)
4455
- # (; clusters) = fig.board_config
4456
- # completed = filter(clusters) do cluster
4457
- # for point in cluster.points
4458
- # if !in(point, player_hand.points)
4459
- # return false
4460
- # end
4461
- # end
4462
- # true
4463
- # end
4464
- # if isempty(completed)
4465
- # return UUID[]
4466
- # end
4467
- # [x.uuid for x in completed]
4468
- # end
4469
- def getcompletedclusters(fig, player_hand, log=False):
4470
- clusters = fig.board_config.clusters
4471
- completed = [
4472
- cluster
4473
- for cluster in clusters
4474
- if all(point in player_hand.points for point in cluster.points)
4475
- ]
4476
- if not completed:
4477
- return []
4478
- return [x.uuid for x in completed]
4479
-
4480
- # Implementing the following Julia function:
4481
- # function removecombo(player_hand::PlayerInfo, combo::String)
4482
- # (; unit_cards) = player_hand
4483
- # unit_cards_to_remove = parse.(Int, split(combo, "-"))
4484
- # new_unit_cards = filter(x->!in(x, unit_cards_to_remove), unit_cards)
4485
- # new_discards = unit_cards_to_remove
4486
- # new_unit_cards, new_discards
4487
- # end
4488
- def removecombo(player_hand, combo):
4489
- if not combo:
4490
- return player_hand.unit_cards, []
4491
- unit_cards_to_remove = list(map(int, combo.split("-")))
4492
- new_unit_cards = pvector([x for x in player_hand.unit_cards if x not in unit_cards_to_remove])
4493
- new_discards = pvector([x for x in unit_cards_to_remove if x in player_hand.unit_cards])
4494
- if len(new_discards) != len(unit_cards_to_remove):
4495
- raise ValueError(f"Discarded cards {new_discards} do not match combo {combo} (from {player_hand.unit_cards})")
4496
- return new_unit_cards, new_discards
4497
-
4498
-
4499
- @dispatch(State, AltAction, DrawUnitFaceupAction)
4500
- def getnextstate(s, action, action_type):
4501
- pass
4502
- # Implementing the following Julia function:
4503
- # function getnextstate(s::State, a::Action, ::Val{:DRAW_UNIT_FACEUP})
4504
- # player_hand_idx = findfirst(p -> p.player_idx == a.player_idx, s.player_hands)
4505
- # player_hand = s.player_hands[player_hand_idx]
4506
- # player_new_unit_idx = s.faceup_spots[a.draw_faceup_spot_num]
4507
-
4508
- # if isempty(s.unit_cards)
4509
- # # TODO: do we need to reshuffle the unit discards?
4510
- # @reset s.faceup_spots[a.draw_faceup_spot_num] = nothing
4511
- # else
4512
- # @reset s.faceup_spots[a.draw_faceup_spot_num] = s.unit_cards[end]
4513
- # @reset s.unit_cards = s.unit_cards[1:end-1]
4514
- # end
4515
-
4516
- # s = recycleunitdiscardsifneeded(s)
4517
- # @reset s.player_hands[player_hand_idx].unit_cards = [player_hand.unit_cards..., player_new_unit_idx]
4518
- # num_market_refills = 0
4519
-
4520
- # num_faceup_spots = getsettingvalue(s.fig, :num_faceup_spots)
4521
-
4522
- # s
4523
- # end
4524
- player_hand_idx = next((i for i, p in enumerate(s.player_hands) if p.player_idx == action.player_idx), None)
4525
- if player_hand_idx is None:
4526
- raise ValueError(f"Player index {action.player_idx} not found in player hands.")
4527
- player_hand = s.player_hands[player_hand_idx]
4528
- player_new_unit_idx = s.faceup_spots[action.draw_faceup_spot_num-1]
4529
-
4530
- if not s.unit_cards:
4531
- # TODO: do we need to reshuffle the unit discards?
4532
- # @reset s.faceup_spots[a.draw_faceup_spot_num] = nothing
4533
- s = s.set(
4534
- faceup_spots = s.faceup_spots.set(action.draw_faceup_spot_num-1, None)
4535
- )
4536
- else:
4537
- # Implementing the following Julia code:
4538
- # @reset s.faceup_spots[a.draw_faceup_spot_num] = s.unit_cards[end]
4539
- # @reset s.unit_cards = s.unit_cards[1:end-1]
4540
- s = s.set(
4541
- faceup_spots = s.faceup_spots.set(action.draw_faceup_spot_num-1, s.unit_cards[-1])
4542
- )
4543
- s = s.set(unit_cards = s.unit_cards[:-1])
4544
-
4545
- # s = recycleunitdiscardsifneeded(s)
4546
- unit_cards = player_hand.unit_cards
4547
- s = s.transform(
4548
- ('player_hands', player_hand_idx),
4549
- player_hand.set(unit_cards=unit_cards.append(player_new_unit_idx)),
4550
- )
4551
- num_market_refills = 0
4552
- num_faceup_spots = getsettingvalue(s.game_config.fig, 'num_faceup_spots')
4553
- return s
4554
-
4555
-
4556
- # Implementing the following Julia function:
4557
- # function getsettingvalue(f::Fig, setting_name::Symbol)
4558
- # for setting in f.board_config.settings
4559
- # if Symbol(setting.name) === setting_name
4560
- # return JSON3.read(setting.value_json)
4561
- # end
4562
- # end
4563
- # nothing
4564
- # end
4565
- @dispatch(Fig, str)
4566
- def getsettingvalue(f, setting_name):
4567
- for setting in f.board_config.settings:
4568
- if setting.name == setting_name:
4569
- return json.loads(setting.value_json)
4570
- return None
4571
-
4572
- @dispatch(State, str)
4573
- def getsettingvalue(s, setting_name):
4574
- return getsettingvalue(s.game_config.fig, setting_name)
4575
-
4576
-
4577
- @dispatch(State, AltAction, DrawUnitDeckAction)
4578
- def getnextstate(s, action, action_type):
4579
- # Implementing the following Julia function:
4580
- # function getnextstate(s::State, a::Action, ::Val{:DRAW_UNIT_DECK})
4581
- # player_hand_idx = findfirst(p -> p.player_idx == a.player_idx, s.player_hands)
4582
- # player_hand = s.player_hands[player_hand_idx]
4583
- # @assert anyunitcardsleft(s) "Unit and discard decks are empty. Action illegal!"
4584
- # s = recycleunitdiscardsifneeded(s)
4585
- # drawn_card = s.unit_cards[end]
4586
- # @reset s.unit_cards = s.unit_cards[1:end-1]
4587
- # @reset s.player_hands[player_hand_idx].unit_cards = [player_hand.unit_cards..., drawn_card]
4588
- # s = recycleunitdiscardsifneeded(s)
4589
- # s
4590
- # end
4591
- player_hand_idx = next((i for i, p in enumerate(s.player_hands) if p.player_idx == action.player_idx), None)
4592
- if player_hand_idx is None:
4593
- raise ValueError(f"Player index {action.player_idx} not found in player hands.")
4594
-
4595
- ## if not anyunitcardsleft(s):
4596
- ## raise ValueError("Unit and discard decks are empty. Action illegal!")
4597
- ## s = recycleunitdiscardsifneeded(s)
4598
- drawn_card = s.unit_cards[-1]
4599
- s = s.set(unit_cards = s.unit_cards[:-1])
4600
-
4601
- # @reset s.player_hands[player_hand_idx].unit_cards = [player_hand.unit_cards..., drawn_card]
4602
- player_hand = s.player_hands[player_hand_idx]
4603
- unit_cards = player_hand.unit_cards
4604
- s = s.transform(
4605
- ('player_hands', player_hand_idx),
4606
- player_hand.set(unit_cards=unit_cards.append(drawn_card)),
4607
- )
4608
-
4609
- ## s = recycleunitdiscardsifneeded(s)
4610
- return s
4611
4247
 
4612
4248
 
4613
- @dispatch(State, AltAction)
4614
- def getnextstateold(s, action):
4615
- action_type = getactiontype(action.action_name)
4616
- next = getnextstate(s, action, action_type)
4617
- next = next.set(action_history=(next.action_history + [action]))
4618
- return next
4619
4249
 
4620
4250
 
4621
- # Implementing the following Julia function:
4622
- # function isactionlegal(s::State, a::Action)
4623
- # action_specs = getlegalactions(s)
4624
- # for action_spec in action_specs
4625
- # if istospec(action_spec, a)
4626
- # return true
4627
- # else
4628
- # # println("Action is not to spec~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", a, action_spec)
4629
- # end
4630
- # end
4631
- # false
4632
- # end
4633
- def isactionlegal(s, a):
4634
- action_specs = getlegalactionspecs(s)
4635
- for action_spec in action_specs:
4636
- if istospec(action_spec, a):
4637
- return True
4638
- else:
4639
- # println("Action is not to spec~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", a, action_spec)
4640
- pass
4641
- return False
4642
-
4643
4251
 
4644
4252
  def isactionlegal2(s, a):
4645
4253
  return run_accept_action_hooks(s, a, ACCEPT_ACTION_HOOKS, False)
4646
4254
 
4647
4255
 
4648
- def istospec(action_spec, a):
4649
- if action_spec.action_name != a.action_name:
4650
- # print(f"istospec: action_spec.action_name != a.action_name: {action_spec.action_name} != {a.action_name}")
4651
- return False
4652
- if action_spec.player_idx != a.player_idx:
4653
- # print(f"istospec: action_spec.player_idx != a.player_idx: {action_spec.player_idx} != {a.player_idx}")
4654
- return False
4655
- # TODO: properly implement
4656
- return True
4657
-
4658
-
4659
- @dispatch(State, AltAction)
4660
- def getnextstate(s, action):
4661
- return getnextstate(s, action, False)
4662
-
4663
-
4664
- # Implementing the following Julia function:
4665
- # function getnextstate(s::State, a::Action)
4666
- # if !isactionlegal(s, a)
4667
- # println("Action is not legal~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", a)
4668
- # return nothing
4669
- # end
4670
- # next = getnextstate(s, a, Val(Symbol(a.action_name)))
4671
-
4672
- # if next.last_to_play == a.player_idx
4673
- # @reset next.terminal = true
4674
- # next = calcwinners(next)
4675
- # elseif isnothing(next.last_to_play)
4676
- # player_hand = next.player_hands[a.player_idx]
4677
- # if getsettingvalue(s.fig, :terminal_two_or_less_pieces) && player_hand.num_pieces <= 2
4678
- # @reset next.last_to_play = a.player_idx
4679
- # elseif getsettingvalue(s.fig, :terminal_first_cluster) && length(player_hand.completed_clusters) > 0
4680
- # @reset next.last_to_play = a.player_idx
4681
- # @reset next.terminal = true
4682
- # next = calcwinners(next)
4683
- # elseif (
4684
- # getsettingvalue(s.fig, :terminal_no_available_points)
4685
- # && length(getunavailablepoints(next)) == length(next.fig.board_config.points)
4686
- # )
4687
- # @reset next.last_to_play = a.player_idx
4688
- # @reset next.terminal = true
4689
- # next = calcwinners(next)
4690
- # end
4691
- # end
4692
-
4693
- # @reset next.action_history = [next.action_history..., a]
4694
- # assertallcardsaccountedfor(next)
4695
- # next
4696
- # end
4697
- @dispatch(State, AltAction, bool)
4698
- def getnextstate(s, action, log):
4699
- if log:
4700
- printstate(s)
4701
- print("(Potential action)")
4702
- printaction(action, getstateidx(s))
4703
-
4704
- if not isactionlegal(s, action):
4705
- print("Action is not legal~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", action)
4706
- return None
4707
- next = getnextstate(s, action, getactiontype(action.action_name))
4708
-
4709
- if next.last_to_play == action.player_idx:
4710
- next = next.set(terminal=True)
4711
- next = calcwinners(next)
4712
- elif next.last_to_play is None:
4713
- player_hand = next.player_hands[action.player_idx]
4714
- terminal_two_or_less_pieces = getsettingvalue(s.game_config.fig, 'terminal_two_or_less_pieces')
4715
- terminal_first_cluster = getsettingvalue(s.game_config.fig, 'terminal_first_cluster')
4716
- terminal_no_available_points = getsettingvalue(s.game_config.fig, 'terminal_no_available_points')
4717
- if terminal_two_or_less_pieces and player_hand.num_pieces <= 2:
4718
- next = next.set(last_to_play=action.player_idx)
4719
- elif terminal_first_cluster and len(player_hand.completed_clusters) > 0:
4720
- next = next.set(last_to_play=action.player_idx, terminal=True)
4721
- next = calcwinners(next)
4722
- elif (
4723
- terminal_no_available_points
4724
- and len(getunavailablepoints(next)) == len(next.game_config.fig.board_config.points)
4725
- ):
4726
- next = next.set(last_to_play=action.player_idx, terminal=True)
4727
- next = calcwinners(next)
4728
-
4729
- next = next.set(action_history=(next.action_history + [action]))
4730
- assertallcardsaccountedfor(next)
4731
-
4732
- return next
4733
-
4734
-
4735
4256
  def getnextstate2(s, a, log=False):
4736
4257
  s = run_state_action_hooks(s, a, AFTER_ACCEPT_ACTION_HOOKS, log)
4737
4258
  s = run_state_action_hooks(s, a, HANDLE_ACTION_HOOKS, log)
@@ -4741,46 +4262,6 @@ def getnextstate2(s, a, log=False):
4741
4262
  s = run_state_action_hooks(s, a, EMPTY_LEGAL_ACTIONS_HOOKS, log)
4742
4263
  return s
4743
4264
 
4744
- @dispatch(State, AltAction, RouteDiscardAction)
4745
- def getnextstate(s, action, action_type):
4746
- # Implementing the following Julia function:
4747
- # function getnextstate(s::State, a::Action, ::Val{:ROUTE_DISCARD})
4748
- # player_hand = s.player_hands[a.player_idx]
4749
- # route_card_hand_nums = collect(a.return_route_cards)
4750
- # return_route_card_nums = player_hand.new_route_cards[route_card_hand_nums]
4751
- # chosen = setdiff(Set(player_hand.new_route_cards), Set(return_route_card_nums))
4752
- # existing_route_cards = player_hand.route_cards
4753
- # @reset s.player_hands[a.player_idx].route_cards = [existing_route_cards..., chosen...]
4754
- # @reset s.route_discards = [s.route_discards..., return_route_card_nums...]
4755
- # @reset s.player_hands[a.player_idx].new_route_cards = []
4756
- # s
4757
- # end
4758
- player_hand_idx = next((i for i, p in enumerate(s.player_hands) if p.player_idx == action.player_idx), None)
4759
- if player_hand_idx is None:
4760
- raise ValueError(f"Player index {action.player_idx} not found in player hands.")
4761
-
4762
- player_hand = s.player_hands[player_hand_idx]
4763
- route_card_hand_idxs = list(action.return_route_cards)
4764
- return_route_card_nums = [player_hand.new_route_cards[i] for i in route_card_hand_idxs]
4765
- chosen = set(list(player_hand.new_route_cards)) - set(return_route_card_nums)
4766
-
4767
- print(f"new_route_cards: {list(player_hand.new_route_cards)}")
4768
- print(f"return_route_card_nums: {return_route_card_nums}")
4769
- print(f"Chosen route cards: {chosen}")
4770
-
4771
- # @reset s.player_hands[a.player_idx].route_cards = [existing_route_cards..., chosen...]
4772
- print(f"Existing route cards: {list(player_hand.route_cards)}")
4773
- player_hand = player_hand.set(route_cards=player_hand.route_cards + pvector(list(chosen)))
4774
- print(f"New route cards: {list(player_hand.route_cards)}")
4775
- # @reset s.route_discards = [s.route_discards..., return_route_card_nums...]
4776
- s = s.set(route_discards=s.route_discards + return_route_card_nums)
4777
- # @reset s.player_hands[a.player_idx].new_route_cards = []
4778
- player_hand = player_hand.set(new_route_cards=pvector([]))
4779
- print(f"New route cards: {list(player_hand.route_cards)}")
4780
-
4781
- s = s.transform(('player_hands', player_hand_idx), player_hand)
4782
-
4783
- return s
4784
4265
 
4785
4266
 
4786
4267
  @dispatch(State, QValueLearningPolicy)
@@ -4799,52 +4280,6 @@ def getnextaction(s, policy):
4799
4280
  return legal_actions[argmax_idx]
4800
4281
 
4801
4282
 
4802
- def get_all_legal_actions(s, player_idx, legal_action_specs):
4803
- legal_actions = []
4804
-
4805
- for action_spec in legal_action_specs:
4806
- if action_spec.action_name == "ROUTE_DISCARD":
4807
- legal_actions.append(
4808
- AltAction(
4809
- action_name="ROUTE_DISCARD",
4810
- player_idx=player_idx,
4811
- return_route_cards=[0], # Placeholder, should be filled with actual logic
4812
- )
4813
- )
4814
-
4815
- elif action_spec.action_name == "DRAW_UNIT_FACEUP":
4816
- draw_faceup_spot_num = 1 # Placeholder, should be filled with actual logic
4817
- legal_actions.append(
4818
- AltAction(
4819
- action_name="DRAW_UNIT_FACEUP",
4820
- player_idx=player_idx,
4821
- draw_faceup_unit_card_num=s.faceup_spots[draw_faceup_spot_num-1],
4822
- draw_faceup_spot_num=draw_faceup_spot_num,
4823
- )
4824
- )
4825
-
4826
- elif action_spec.action_name == "DRAW_UNIT_DECK":
4827
- legal_actions.append(
4828
- AltAction(
4829
- action_name="DRAW_UNIT_DECK",
4830
- player_idx=player_idx,
4831
- )
4832
- )
4833
-
4834
- elif action_spec.action_name == "CLAIM_POINT":
4835
- for point in action_spec.points:
4836
- legal_actions.append(
4837
- AltAction(
4838
- action_name="CLAIM_POINT",
4839
- player_idx=player_idx,
4840
- point_uuid=str(point.point_uuid),
4841
- unit_combo=point.default_combo, # Placeholder, should be filled with actual logic
4842
- )
4843
- )
4844
-
4845
- return legal_actions
4846
-
4847
-
4848
4283
  @dispatch(State, RandoPolicy)
4849
4284
  def getnextaction(s, policy):
4850
4285
  player_idx = gettoplay(s)[0]
@@ -4885,14 +4320,6 @@ def getnextaction(s, policy):
4885
4320
  return None
4886
4321
 
4887
4322
 
4888
- @dispatch(State, int)
4889
- def getplayerstate(s, player_idx):
4890
- return PlayerState(
4891
- public=getpublicstate(s),
4892
- private=getprivatestate(s, player_idx),
4893
- )
4894
-
4895
-
4896
4323
  def getpublicplayerscore(s, player_score):
4897
4324
  print("*****************321 player_score: ", player_score)
4898
4325
  if s.terminal:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graph_games_proto
3
- Version: 0.3.1739
3
+ Version: 0.3.1741
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=sI31dBPkrs_UHYsuc1Q2sdYkJfpVPKpB--FuqghA208,864
2
2
  graph_games_proto/all_types.py,sha256=IpbwftEcHS5Ewz-saFNk0lO9FvcbuHG36odRTayCXUk,54911
3
- graph_games_proto/fns.py,sha256=6g0ZmnvRPm24KVE8G8X6ZHiy4MCw2lTdLckxIcxKX9w,264080
3
+ graph_games_proto/fns.py,sha256=Yjdzi-ST7rSv5PLcJiECu5fgWXSbOjNl_LCYmulfuJc,239934
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.1739.dist-info/METADATA,sha256=entYuJ6psfY811c2Vkniil53jz5-U_RR1XStLn34CtE,188
7
- graph_games_proto-0.3.1739.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
- graph_games_proto-0.3.1739.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
- graph_games_proto-0.3.1739.dist-info/RECORD,,
6
+ graph_games_proto-0.3.1741.dist-info/METADATA,sha256=iaIQuc2Cf9DaYgB4dq4A1j85nGei4di7auJx4wb3Ans,188
7
+ graph_games_proto-0.3.1741.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
+ graph_games_proto-0.3.1741.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
+ graph_games_proto-0.3.1741.dist-info/RECORD,,