diff options
Diffstat (limited to 'go/game/targets.go')
| -rw-r--r-- | go/game/targets.go | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/go/game/targets.go b/go/game/targets.go index 56ec9b30..92fc6104 100644 --- a/go/game/targets.go +++ b/go/game/targets.go @@ -397,10 +397,10 @@ func singleTargetConstraint(desc string, s *LocalState, action Action) TargetCon constraints = append(constraints, parseTileTargetConstraint(desc, s, action)...) } else if strings.Contains(desc, "card") { constraints = append(constraints, parseCardTargetConstraint(desc, s, action)...) - // } else if strings.Contains("action") { + // } else if strings.Contains(desc, "action") { // constraints = append(constraints, parseActionTargetConstraint(desc, s, action)...) - // } else if strings.Contains("spell") { - // constraints = append(constraints, parseSpellTargetConstraint(desc, s, action)...) + } else if strings.Contains(desc, "spell") { + constraints = append(constraints, parseSpellTargetConstraint(desc, s, action)...) } return conjunction(constraints...) @@ -512,7 +512,7 @@ func typeTargetConstraint[T any](typeDesc string) TargetConstraintFunc { } } -func cardTypeTargetConstraint(f func(CardType) bool) TargetConstraintFunc { +func permanentCardTypeConstraint(f func(CardType) bool) TargetConstraintFunc { return func(t any) (err error) { p, ok := t.(Permanent) if !ok { @@ -530,12 +530,31 @@ func cardTypeTargetConstraint(f func(CardType) bool) TargetConstraintFunc { } } +func cardTypeConstraint(cardType CardType) TargetConstraintFunc { + return func(t any) (err error) { + c, ok := t.(*Card) + if !ok { + err = fmt.Errorf("unexpected target type %T not *Card", t) + return + } + + if c.Type != cardType { + err = fmt.Errorf("unexpected card type: %v not %v", c.Type, cardType) + return + } + + return + } +} + var ( - permanentTargetConstraint TargetConstraintFunc = typeTargetConstraint[Permanent]("Permanent") - unitTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Unit]("*Unit") - tileTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Tile]("*Tile") - artifactTargetConstraint TargetConstraintFunc = cardTypeTargetConstraint(CardType.IsArtifact) - cardTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Card]("*Card") + permanentTargetConstraint TargetConstraintFunc = typeTargetConstraint[Permanent]("Permanent") + unitTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Unit]("*Unit") + tileTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Tile]("*Tile") + artifactTargetConstraint TargetConstraintFunc = permanentCardTypeConstraint(CardType.IsArtifact) + cardTargetConstraint TargetConstraintFunc = typeTargetConstraint[*Card]("*Card") + playActionTargetConstraint TargetConstraintFunc = typeTargetConstraint[*PlayAction]("*PlayAction") + spellTargetConstraint TargetConstraintFunc = cardTypeConstraint(CardTypes.Spell) ) var ErrTargetHasShroud = errors.New("target has shroud") @@ -856,6 +875,43 @@ func parseCardTargetConstraint(desc string, s *LocalState, action Action) []Targ return constraints } +func playedCardTypeConstraint(cardType CardType) TargetConstraintFunc { + return func(t any) error { + pa := t.(*PlayAction) + if pa.Card.Type != cardType { + return fmt.Errorf("played cardtype %s not %s", pa.Card.Type, cardType) + } + return nil + } +} + +func parseSpellTargetConstraint(desc string, s *LocalState, action Action) []TargetConstraintFunc { + var constraints []TargetConstraintFunc + + // The target has to be a declared play action + if strings.Contains(desc, "declared") { + constraints = []TargetConstraintFunc{ + playActionTargetConstraint, + playedCardTypeConstraint(CardTypes.Spell), + func(t any) error { + pa := t.(*PlayAction) + if !utils.InterfaceSliceContains(utils.TypedSliceToInterfaceSlice(s.stack.Actions), pa) { + return fmt.Errorf("action %s not declared", pa) + } + return nil + }, + } + // The target may be any spell card + } else { + constraints = []TargetConstraintFunc{ + cardTargetConstraint, + spellTargetConstraint, + } + } + + return constraints +} + func (t *Target) candidates() []any { c := []any{} if strings.Contains(t.desc, "unit") || |
