module Solutions.RivalsOfIxalan7 where

import Dovin.Prelude
import Dovin.V1

blocked :: [Char]
blocked = [Char]
"blocked"

solution :: GameMonad ()
solution :: GameMonad ()
solution = do
  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Initial state" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
setLife Int
7

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Int -> [Char] -> GameMonad ()
addLands Int
2 [Char]
"Mountain"
      Int -> [Char] -> GameMonad ()
addLands Int
2 [Char]
"Plains"

      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
trample] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
5, Int
5) [Char]
"Rowdy Crew"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Needletooth Raptor"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
0, Int
1) [Char]
"Tilonalli's Skinshifter"
      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying]
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            (CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
exerted)
            (    CardLocation -> CardMatcher
matchLocation (CardLocation -> CardMatcher)
-> (Card -> CardLocation) -> Card -> CardMatcher
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting CardLocation Card CardLocation -> Card -> CardLocation
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting CardLocation Card CardLocation
Lens' Card CardLocation
cardLocation
              (Card -> CardMatcher)
-> (Card -> CardMatcher) -> Card -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> Card -> CardMatcher
forall a b. a -> b -> a
const ([Char] -> CardMatcher
matchAttribute [Char]
creature)
            )
            (Card -> Identity Card
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Card -> Identity Card) -> (Card -> Card) -> Card -> Identity Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Card Card CardStrength CardStrength
-> (CardStrength -> CardStrength) -> Card -> Card
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter Card Card CardStrength CardStrength
Lens' Card CardStrength
cardStrength ((Int, Int) -> CardStrength
mkStrength (Int
1, Int
1) CardStrength -> CardStrength -> CardStrength
forall a. Semigroup a => a -> a -> a
<>))
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Tah-Crop Elite"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Hand) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
haste (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
1) [Char]
"Fanatical Firebrand"
      [Char] -> GameMonad ()
addInstant [Char]
"Sure Strike"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Opponent, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad ()
addLand [Char]
"Spires of Orcaza"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Aerial Responder"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
3, Int
5) [Char]
"Bellowing Aegisaur 1"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
3, Int
5) [Char]
"Bellowing Aegisaur 2"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Firebrand" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"R" [Char]
"Mountain 1"
    [Char] -> [Char] -> GameMonad ()
cast [Char]
"R" [Char]
"Fanatical Firebrand" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Activate Firebrand to damage raptor, killing Aerial Responder" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
activate [Char]
"" [Char]
"Fanatical Firebrand"
    [Char] -> GameMonad ()
tap [Char]
"Fanatical Firebrand"
    [Char] -> GameMonad ()
sacrifice [Char]
"Fanatical Firebrand"
    [Char] -> GameMonad ()
target [Char]
"Needletooth Raptor"

    [Char] -> GameMonad ()
trigger [Char]
"Needletooth Raptor"
    (Card -> Int) -> Target -> [Char] -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
5) ([Char] -> Target
targetCard [Char]
"Aerial Responder") [Char]
"Needletooth Raptor"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Attack with all, Skinshifter as Tah-Crop and exerting Tah-Crop" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> CardMatcher -> GameMonad ()
validate [Char]
"Aerial Responder" (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher -> CardMatcher
invert CardMatcher
matchInPlay

    [[Char]] -> GameMonad ()
attackWith
      [ [Char]
"Tah-Crop Elite"
      , [Char]
"Rowdy Crew"
      , [Char]
"Needletooth Raptor"
      , [Char]
"Tilonalli's Skinshifter"
      ]

    [Char] -> GameMonad ()
exert [Char]
"Tah-Crop Elite"

    [Char] -> GameMonad ()
trigger [Char]
"Tilonalli's Skinshifter"
    [Char] -> GameMonad ()
target [Char]
"Tah-Crop Elite"
    [Char] -> CardMatcher -> GameMonad ()
validate [Char]
"Tah-Crop Elite" (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
attacking
    [Char] -> [Char] -> GameMonad ()
copyAttributes [Char]
"Tah-Crop Elite" [Char]
"Tilonalli's Skinshifter"
    [Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
flying [Char]
"Tilonalli's Skinshifter"

  [GameMonad ()] -> GameMonad ()
fork
    [ [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"No spire, block out ground damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Tah-Crop Elite"
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Tilonalli's Skinshifter"
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Bellowing Aegisaur 1"] [Char]
"Rowdy Crew"
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Bellowing Aegisaur 2"] [Char]
"Needletooth Raptor"

        Player -> Int -> GameMonad ()
validateLife Player
Opponent Int
0

    , [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Spire one of the flyers, sure strike pushes through damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
        [Char] -> GameMonad ()
tap [Char]
"Spires of Orcaza"
        [Char] -> GameMonad ()
untap [Char]
"Tah-Crop Elite"
        [Char] -> [Char] -> GameMonad ()
loseAttribute [Char]
attacking [Char]
"Tah-Crop Elite"

        [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"R" [Char]
"Mountain 2"
        [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"W" [Char]
"Plains 1"
        [Char] -> [Char] -> GameMonad ()
cast [Char]
"1R" [Char]
"Sure Strike" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
        [Char] -> GameMonad ()
target [Char]
"Tilonalli's Skinshifter"
        (Int, Int) -> [Char] -> GameMonad ()
modifyStrength (Int
3, Int
0) [Char]
"Tilonalli's Skinshifter"

        [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Tilonalli's Skinshifter"
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Bellowing Aegisaur 1"] [Char]
"Rowdy Crew"
        [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Bellowing Aegisaur 2"] [Char]
"Needletooth Raptor"

        Player -> Int -> GameMonad ()
validateLife Player
Opponent Int
0
    ]


attributes :: Formatter
attributes = FormatMonad () -> Formatter
attributeFormatter (FormatMonad () -> Formatter) -> FormatMonad () -> Formatter
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> GameMonad Int -> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"opponent life" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player -> GameMonad Int
countLife Player
Opponent
  [Char] -> GameMonad Int -> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"mana" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$
    Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (Int -> Int -> Int)
-> GameMonad Int
-> ExceptT
     [Char]
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Int -> Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CardMatcher -> GameMonad Int
countCards
              ([Char] -> CardMatcher
matchAttribute [Char]
land
              CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
missingAttribute [Char]
tapped
              CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> Player -> CardMatcher
matchController Player
Active
              )
        ExceptT
  [Char]
  (ReaderT Env (StateT Board (WriterT [Step] Identity)))
  (Int -> Int)
-> GameMonad Int -> GameMonad Int
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Player -> GameMonad Int
countManaPool Player
Active

formatter :: a -> Formatter
formatter a
1 = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
boardFormatter
formatter a
3 = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<>
  [Char] -> CardMatcher -> Formatter
cardFormatter
    [Char]
"remaining creatures"
    (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Play) CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature)
formatter a
4 = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<>
  [Char] -> CardMatcher -> Formatter
cardFormatter
    [Char]
"non-blocked creatures"
      (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play)
      CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
attacking
      CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
missingAttribute [Char]
blocked
      )
formatter a
5 = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<>
  [Char] -> CardMatcher -> Formatter
cardFormatter
    [Char]
"damaging creatures"
    (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play)
    CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
attacking
    CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> ([Char] -> CardMatcher
missingAttribute [Char]
blocked CardMatcher -> CardMatcher -> CardMatcher
`matchOr` [Char] -> CardMatcher
matchAttribute [Char]
trample)
    )
formatter a
6 = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<>
  [Char] -> CardMatcher -> Formatter
cardFormatter
    [Char]
"damaging creatures"
    (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play)
    CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
attacking
    CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> ([Char] -> CardMatcher
missingAttribute [Char]
blocked CardMatcher -> CardMatcher -> CardMatcher
`matchOr` [Char] -> CardMatcher
matchAttribute [Char]
trample)
    )
formatter a
_ = Formatter
attributes

copyAttributes :: CardName -> CardName -> GameMonad ()
copyAttributes :: [Char] -> [Char] -> GameMonad ()
copyAttributes [Char]
from [Char]
to = do
  Card
toCard <- [Char] -> CardMatcher -> GameMonad Card
requireCard [Char]
to ([Char] -> CardMatcher
matchAttribute [Char]
creature)

  -- Can't use requireCard because need access to the base strength
  Maybe BaseCard
maybeCard <- Getting (Maybe BaseCard) Board (Maybe BaseCard)
-> ExceptT
     [Char]
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe BaseCard)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use (Getting (Maybe BaseCard) Board (Maybe BaseCard)
 -> ExceptT
      [Char]
      (ReaderT Env (StateT Board (WriterT [Step] Identity)))
      (Maybe BaseCard))
-> Getting (Maybe BaseCard) Board (Maybe BaseCard)
-> ExceptT
     [Char]
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe BaseCard)
forall a b. (a -> b) -> a -> b
$ (HashMap [Char] BaseCard
 -> Const (Maybe BaseCard) (HashMap [Char] BaseCard))
-> Board -> Const (Maybe BaseCard) Board
Lens' Board (HashMap [Char] BaseCard)
cards ((HashMap [Char] BaseCard
  -> Const (Maybe BaseCard) (HashMap [Char] BaseCard))
 -> Board -> Const (Maybe BaseCard) Board)
-> ((Maybe BaseCard -> Const (Maybe BaseCard) (Maybe BaseCard))
    -> HashMap [Char] BaseCard
    -> Const (Maybe BaseCard) (HashMap [Char] BaseCard))
-> Getting (Maybe BaseCard) Board (Maybe BaseCard)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap [Char] BaseCard)
-> Lens'
     (HashMap [Char] BaseCard)
     (Maybe (IxValue (HashMap [Char] BaseCard)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at [Char]
Index (HashMap [Char] BaseCard)
from

  case Maybe BaseCard
maybeCard of
    Maybe BaseCard
Nothing -> [Char] -> GameMonad ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Card does not exist: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
from
    Just (BaseCard Card
card) -> do
      ASetter Card Card CardStrength CardStrength
-> (CardStrength -> CardStrength) -> [Char] -> GameMonad ()
forall a b.
ASetter Card Card a b -> (a -> b) -> [Char] -> GameMonad ()
modifyCard ASetter Card Card CardStrength CardStrength
Lens' Card CardStrength
cardStrength (CardStrength -> CardStrength -> CardStrength
forall a b. a -> b -> a
const (CardStrength -> CardStrength -> CardStrength)
-> CardStrength -> CardStrength -> CardStrength
forall a b. (a -> b) -> a -> b
$ Getting CardStrength Card CardStrength -> Card -> CardStrength
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting CardStrength Card CardStrength
Lens' Card CardStrength
cardStrength Card
card) [Char]
to