diff --git a/src/lpsim/server/action.py b/src/lpsim/server/action.py index 77393291..f459427b 100644 --- a/src/lpsim/server/action.py +++ b/src/lpsim/server/action.py @@ -312,7 +312,8 @@ class CreateRandomObjectAction(ActionBase): """ Action for creating random objects. A list of names are provided, and `number` of them will be created by uniformly selecting from the list and doing - `CreateObjectAction` for each of them. + `CreateObjectAction` for each of them. Replace means whether the sample is with or + without replacement. True meaning that a value of a can be selected multiple times. NOTE: some actions will not generate existing objects, e.g. elemental skill of Rhodeia will not summoning existing objects unless full. This action will not deal with such situation, you need to write logic to filter out existing objects before @@ -324,15 +325,16 @@ class CreateRandomObjectAction(ActionBase): object_names: List[str] object_arguments: dict number: int + replace: bool def select_by_idx( self, idx: int ) -> Tuple[CreateObjectAction, "CreateRandomObjectAction"]: """ Select an object name by index and create a `CreateObjectAction` for it. - It will also return a new `CreateRandomObjectAction` with the same - arguments but with the `number` reduced by 1 and the selected object - name removed from the list. + It will also return a new `CreateRandomObjectAction`. If replace is False, with + the same arguments but with the `number` reduced by 1 and the selected object + name removed from the list. If replace is True, only number is decreased by 1. Returns: CreateObjectAction: The action for creating the object. @@ -341,18 +343,29 @@ def select_by_idx( """ selected = self.object_names[idx] others = self.object_names[:idx] + self.object_names[idx + 1 :] - return ( - CreateObjectAction( + if self.replace: + ret_action = CreateRandomObjectAction( object_position=self.object_position, - object_name=selected, + object_names=self.object_names, object_arguments=self.object_arguments, - ), - CreateRandomObjectAction( + number=self.number - 1, + replace=True, + ) + else: + ret_action = CreateRandomObjectAction( object_position=self.object_position, object_names=others, object_arguments=self.object_arguments, number=self.number - 1, + replace=False, + ) + return ( + CreateObjectAction( + object_position=self.object_position, + object_name=selected, + object_arguments=self.object_arguments, ), + ret_action, ) diff --git a/src/lpsim/server/card/event/resonance.py b/src/lpsim/server/card/event/resonance.py index a17318be..8ba98429 100644 --- a/src/lpsim/server/card/event/resonance.py +++ b/src/lpsim/server/card/event/resonance.py @@ -565,6 +565,7 @@ def get_actions( ), object_arguments={}, number=1, + replace=False, ) ] @@ -609,6 +610,7 @@ def get_actions( ), object_arguments={}, number=1, + replace=False, ) ] diff --git a/src/lpsim/server/character/hydro/rhodeia_3_3.py b/src/lpsim/server/character/hydro/rhodeia_3_3.py index 346fb699..c208a121 100644 --- a/src/lpsim/server/character/hydro/rhodeia_3_3.py +++ b/src/lpsim/server/character/hydro/rhodeia_3_3.py @@ -128,6 +128,7 @@ def get_actions(self, match: Any) -> List[ChargeAction | CreateRandomObjectActio object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number, + replace=False, ) ) elif len(unexist_names) >= self._summon_number: @@ -138,6 +139,7 @@ def get_actions(self, match: Any) -> List[ChargeAction | CreateRandomObjectActio object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number, + replace=False, ) ) else: @@ -148,6 +150,7 @@ def get_actions(self, match: Any) -> List[ChargeAction | CreateRandomObjectActio object_position=target_position, object_arguments={"version": self.version}, number=len(unexist_names), + replace=False, ) ) ret.append( @@ -156,6 +159,7 @@ def get_actions(self, match: Any) -> List[ChargeAction | CreateRandomObjectActio object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number - len(unexist_names), + replace=False, ) ) ret.append(self.charge_self(1)) diff --git a/src/lpsim/server/patch/v43/balance/rhodeia_of_loch_4_3.py b/src/lpsim/server/patch/v43/balance/rhodeia_of_loch_4_3.py index 7fafc9f9..76a86b3d 100644 --- a/src/lpsim/server/patch/v43/balance/rhodeia_of_loch_4_3.py +++ b/src/lpsim/server/patch/v43/balance/rhodeia_of_loch_4_3.py @@ -72,6 +72,7 @@ def get_actions( object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number, + replace=False, ) ) elif ( @@ -85,6 +86,7 @@ def get_actions( object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number, + replace=False, ) ) else: @@ -95,6 +97,7 @@ def get_actions( object_position=target_position, object_arguments={"version": self.version}, number=len(unexist_names) - 1, + replace=False, ) ) ret.append( @@ -103,6 +106,7 @@ def get_actions( object_position=target_position, object_arguments={"version": self.version}, number=self._summon_number - len(unexist_names) + 1, + replace=False, ) ) ret.append(self.charge_self(1)) diff --git a/src/lpsim/server/patch/v43/cards/mamere_4_3.py b/src/lpsim/server/patch/v43/cards/mamere_4_3.py index 82501843..0b431643 100644 --- a/src/lpsim/server/patch/v43/cards/mamere_4_3.py +++ b/src/lpsim/server/patch/v43/cards/mamere_4_3.py @@ -108,6 +108,7 @@ def event_handler_USE_CARD( object_position=position, object_arguments=args, number=1, + replace=True, ) ) res += self.check_should_remove() diff --git a/src/lpsim/server/patch/v44/cards/sunyata_flower_4_4.py b/src/lpsim/server/patch/v44/cards/sunyata_flower_4_4.py index 80e96d16..11f31b0e 100644 --- a/src/lpsim/server/patch/v44/cards/sunyata_flower_4_4.py +++ b/src/lpsim/server/patch/v44/cards/sunyata_flower_4_4.py @@ -1,7 +1,13 @@ from typing import Any, Dict, List, Literal, Type from pydantic import PrivateAttr -from ....action import ActionTypes, Actions, CreateObjectAction, RemoveObjectAction +from ....action import ( + ActionTypes, + Actions, + CreateObjectAction, + CreateRandomObjectAction, + RemoveObjectAction, +) from .....utils.class_registry import get_instance, register_class from ....event import GameStartEventArguments, MoveObjectEventArguments from ....modifiable_values import CostValue @@ -109,30 +115,30 @@ def get_targets(self, match: Match) -> List[ObjectPosition]: def get_actions( self, target: ObjectPosition | None, match: Match - ) -> List[RemoveObjectAction | CreateObjectAction]: + ) -> List[RemoveObjectAction | CreateObjectAction | CreateRandomObjectAction]: """ remove target, and generate 2 random support cards, and create status """ assert target is not None - ret: List[RemoveObjectAction | CreateObjectAction] = [ - RemoveObjectAction(object_position=target) - ] + ret: List[ + RemoveObjectAction | CreateObjectAction | CreateRandomObjectAction + ] = [RemoveObjectAction(object_position=target)] candidate_list = self._get_candidate_list(match) - for i in range(2): - random_target = candidate_list[int(match._random() * len(candidate_list))] - position = ObjectPosition( - player_idx=self.position.player_idx, area=ObjectPositionType.HAND, id=-1 - ) - args = {} - if self._accept_version is not None: - args["version"] = self._accept_version - ret.append( - CreateObjectAction( - object_name=random_target, - object_position=position, - object_arguments=args, - ) + position = ObjectPosition( + player_idx=self.position.player_idx, area=ObjectPositionType.HAND, id=-1 + ) + args = {} + if self._accept_version is not None: + args["version"] = self._accept_version + ret.append( + CreateRandomObjectAction( + object_names=candidate_list, + object_position=position, + object_arguments=args, + number=2, + replace=True, ) + ) ret.append( CreateObjectAction( object_name=self.name,