Conditions

Conditions in Chaos Cards (or generally in card games) contributes to the diversity of effects, by specifying/constraining under what situation should the effects be triggered and what are the valid targets for the effects. We formulate conditions with two main nonterminal types, TargetCond and IndeCond, where the former is for conditions having to be associated to certain characters/cards, while the latter does not have to be. Both of which will contain smaller parts specifying different aspects of the conditions. We illustrate in more details below.

TargetCond

TargetCond :=

| charTargetCond(CharTargetCond)

| cardTargetCond(CardTargetCond)

CharTargetCond :=

| justCharCond(AlleCond, CharTypeCond, AbilCond, StatCond)

CardTargetCond :=

| justCharCond(CardPosCond, AlleCond, CharTypeCond, AbilCond, StatCond)

TargetCond nodes represent the type of conditions associated to particular cards, used as the target constraints for targeted effects and source conditions (see [Here] at the effect page) for either targeted or untargeted effects, and target applicabilities (see [Here] at the effect page) in certain untargeted effects. They are generally saying how the character or card should look like. For example, "a Beast card at your hand with Charge having at most 5 mana cost" would be such a condition.

    • We categorize TargetCond into two main categories, conditions on characters (CharTargetCond) or condition on cards (CardTargetCond), due to the fact that characters and cards having very different collection of valid requirements (e.g it does not make sense to place a position requirement on characters as characters are always on the field, but it make sense to do so on cards as cards can be at the hands or in the decks).

    • Each such conditions can be decomposed into different parts, including requirements on position (only for cards), allegiance (which side), type, abilities and stats. These are discussed in more details in the Condition Part section below.

IndeCond

IndeCond :=

| fieldExistCond(CharTargetCond)

| cardExistCond(CardTargetCond)

| leaderCond(AlleCond, AbilCond, StatCond)

| mpCond(AlleCond, StatCondVariant)

| maxMpCond(AlleCond, StatCondVariant)

IndeCond nodes represent the type of conditions that are not associated to or does not have to associate to particular cards. These conditions are used as independent conditions (see [Here] at the effect page) for either targeted or untargeted effects. They are generally saying requirements on the existence of characters/cards, the state of the leader(s) (a leader is associated with a card but referring to a leader clear and does not have to specify another card), or the state of the player (MP or max MP). Different subtypes of such conditions are briefly discussed as follows.

  • fieldExistenceCond and cardExistenceCond are requirements about the existence of certain kinds of the character and cards respectively. The qualification for checking for existence is specified by the CharTargetCond and CardTargetCond parts respectively (see the section below). For example, "there exist a Beast card at your hand with Charge having at most 5 mana cost" would be such a condition. The semantics of this existence always exclude the source character/card itself (i.e. where the effect is on).

    • leaderCond conditions are requirements on some or both leaders. While it is already clear we are referring to leader(s), there are still freedom in specifying the allegiance (who's leader(s)), or requirements on abilities or stats on the leader(s). For example, "both leaders are with Untargetability having at least 10 health" would be such a condition.

    • mpCond and maxMpCond are requirements about some player(s)' current MP or max MP. It needs to have the allegiance (which player(s)), and a numerical requirement on the corresponding stat (MP or max MP) that is represented with a StatCondVariant node (see the section below). For example, "the opponent has at least 5 Max MP" would be such a condition, where "at least 5" is what the StatCondVariant part would represent in this case.

Condition Parts

The following illustrates different parts that can be involved in a condition or condition-like structure.

CardPosCond :=

| cardPosHandOrDeck()

| cardPosHand()

| cardPosDeck()

CardPosCond is for requirements on position of cards. It can be at either hand(s) or deck(s) (basically no requirement), at the hand(s) or in the deck(s).

AlleCond :=

| anyAllegiance()

| allyAllegiance()

| oppoAllegiance()

AlleCond is for requirements on allegiance. It can be either/both side(s) (no requirement), or requiring your side, or the opponent's side. This nonterminal is used in a variety of context, not only for conditions on characters or cards, but anything that requires specifying "which side it applies for". The allegiance is always relative to the source card, i.e. where the effect is. When used in source condition, as the card is always on its own side. So it can never be on the opponent's side, and "either side" would have the same functionality as "your side". In our implementation, in this case, it is always forced to be "either side" as it makes it easier to make a cleaner description ("itself is a Beast minion" feels better than "itself is a friendly Beast minion").

CharTypeCond :=

| isCharater()

| isMinion()

| isBeast()

| isDragon()

| isDemon()

CharTypeCond is for the requirements on the type of characters. It can be any character (no requirement), or requiring a minion, or a specific type of minion. Leader is also considered as character (will be considered valid for "any character") but is not listed separately as a requirement as requirements specifically on leaders would be covered by leaderCond in the section above. When generating such conditions, there are some consideration on context to prevent creating conditions that are too trivial. For example, if the condition is used with the context of the effect "change the minion type to Beast", we don't want the target constraint to be specifically Beast minions (could include Beast minion, like just minion, or any character), to make trivial conditions like "change the minion type of a Beast to Beast". Another example is when the card is a Beast card and we are generating a source condition here, so we don't just want "itself is Beast" because that is by default true. We wish, if this type of condition is generated, player has to think of a way to change it to a Beast to get it triggered. Similar concept also apply to other cases like the CardTypeCond, AbilCond, and StatCond parts below.

CardTypeCond :=

| isCard()

| isLeaderCard()

| isMinionCard()

| isSpellCard()

| isBeastCard()

| isDragongCard()

| isDemonCard()

CardTypeCond is for the requirements on the type of card. It can be any card (no requirement), or requiring one of the three main card types (leader, minion, spell), or a specific type of minion. The use of context in generating this type of node include the case of preventing trivial conditions when deciding a specific minion type to require, but it has slightly more use here. The other use of context is to prevent impossible conditions. Chaos Cards allows minion types, abilities to be modified by effects, but it does not allow the main card type to be modified, e.g. a spell card is always a spell card. Therefore, when generating a source condition on a spell card, we can never create something like "itself is a minion card" because it would be impossible to be satisfied. As "itself is a spell card" would be trivial in this case, so we basically forbid all of these and just force it to select "any card" as this part should have any requirement anyway.

AbilCond :=

| noAbilCond()

| chargeCond()

| tauntCond()

| stealCond()

| untargetableCond()

| shieldCond()

| poisonousCond()

| lifesetealCond()

AbilCond is for requirements on abilites of characters or cards. It can be no requirement, or requiring one of the seven abilities (there is nothing wrong requiring more as they can co-exist but those are usually less meaningful as having multiple abilities is not common). Triviability consideration generally applies expect for the case of stealth and shield abilities after card play time (e.g. turn start/end effects, deathrattle effects), because stealth and shield are easily lost on the field. Impossibility consideration also applies in that leaders cannot get Stealth ability, and spells cannot get Charge, Taunt, Stealth or Shield abilities.

StatCond :=

| noStatCond()

| costCond(StatCondVariant)

| atkCond(StatCondVariant)

| hpCond(StatCondVariant)

| atkTimesCond(StatCondVariant)

StatCondVariant :=

| statGe(int)

| statLe(int)

StatCond is for requirements on stats on cards. It can be no requirement, or having a requirement on one of the four stats, mana cost, attack, health (referring to remaining health, not max health; I suppose that could be another potential stat to consider for condition), and attack times (there is nothing wrong requiring more than one but it would look too complicated). The requirement on a numerical stat is represented by a StatCondVariant node which is basically a relation check on the value. The currently implementation implements "greater than or equal" (at least) and "less than or equal" (at most), other numerical relation conditions can be potentially added as needed. Triviability consideration applies, e.g. we don't generate "itself is of at least 2 mana cost" for a cost 3 card (expect the stats being modified to satisfy the condition). Impossibility (or here it is more like applicability) consideration also applies in that spells does not have another other stats than the mana cost.