module Solutions.GuildsOfRavnica9 where

import Control.Lens
import Control.Monad
import Control.Monad.Except (throwError)

import Dovin.V1

solution :: GameMonad ()
solution :: GameMonad ()
solution = do
  -- This puzzle relies heavily on casting triggers, so wrap the relevant ones
  -- up in this helper.
  --
  -- For ease of use, spells that will be copied are named with a trailing " 1"
  -- and subsequent copies increment this number.
  let withTriggers :: ([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers = \[Char]
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a
action [Char]
name -> do
        [Char]
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a
action [Char]
name
        [Char] -> GameMonad ()
trigger [Char]
"Thousand-Year Storm"
        (Int -> GameMonad ()) -> GameMonad ()
triggerStorm ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
          \Int
n -> [Char] -> [Char] -> GameMonad ()
copySpell
                  (Int -> [Char] -> [Char]
numbered (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ((Char -> Char -> Char) -> [Char] -> [Char] -> [Char]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Char -> Char -> Char
forall a b. a -> b -> a
const [Char]
name (Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
2 [Char]
name)))
                  [Char]
name

        [Char] -> GameMonad ()
trigger [Char]
"Adeliz, the Cinder Wind"
        (Int, Int) -> [Char] -> GameMonad ()
modifyStrength (Int
1, Int
1) [Char]
"Adeliz, the Cinder Wind"

  -- We'll be making a lot of archers...
  let addArcherCopy :: [Char] -> GameMonad ()
addArcherCopy [Char]
name = do
        CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
          [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
token, [Char]
summoned] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
4) [Char]
name

  let angel :: [Char]
angel = [Char]
"angel"
  let merfolk :: [Char]
merfolk = [Char]
"merfolk"

  [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
12

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Hand) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad ()
addSorcery [Char]
"Undercity Uprising"
      [Char] -> GameMonad ()
addSorcery [Char]
"Doublecast 1"
      [Char] -> GameMonad ()
addInstant [Char]
"Plummet 1"
      [Char] -> GameMonad ()
addSorcery [Char]
"Quasiduplicate 1"
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
flying (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
7, Int
6) [Char]
"Torgaar, Famine Incarnate"
      [Char] -> GameMonad ()
addAura [Char]
"Waterknot"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad ()
addEnchantment [Char]
"Thousand-Year Storm"
      -- Has +2/+2 from Maniacal Rage aura
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
flying (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Adeliz, the Cinder Wind"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
4) [Char]
"Afzocan Archer"

      Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Timber Gorge"
      Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Submerged Boneyard"
      Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Highland Lake"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Opponent, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
"merfolk" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Kopala, Warden of Waves"
      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
token] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Angel 1"
      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
token] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Angel 2"
      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
token] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Angel 3"

      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
angel]
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            CardMatcher
matchInPlay
            Card -> CardMatcher
matchOtherCreatures
            (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
. [Char] -> Card -> Card
setAttribute [Char]
hexproof)
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
3, Int
4) [Char]
"Shalai, Voice of Plenty"

      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
lifelink, [Char]
angel]
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            CardMatcher
matchInPlay
            (Card -> CardMatcher
matchOtherCreatures (Card -> CardMatcher)
-> (Card -> CardMatcher) -> Card -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> (CardMatcher -> Card -> CardMatcher
forall a b. a -> b -> a
const (CardMatcher -> Card -> CardMatcher)
-> CardMatcher -> Card -> CardMatcher
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
angel))
            (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
<>) (Card -> Card) -> (Card -> Card) -> Card -> Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Card -> Card
setAttribute [Char]
lifelink)
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Lyra Dawnbringer"

      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
merfolk
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            CardMatcher
matchInPlay
            (Card -> CardMatcher
matchOtherCreatures (Card -> CardMatcher)
-> (Card -> CardMatcher) -> Card -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> (CardMatcher -> Card -> CardMatcher
forall a b. a -> b -> a
const (CardMatcher -> Card -> CardMatcher)
-> CardMatcher -> Card -> CardMatcher
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
merfolk))
            (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]
"Merfolk Mistbinder 1"

      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
merfolk
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            CardMatcher
matchInPlay
            (Card -> CardMatcher
matchOtherCreatures (Card -> CardMatcher)
-> (Card -> CardMatcher) -> Card -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> (CardMatcher -> Card -> CardMatcher
forall a b. a -> b -> a
const (CardMatcher -> Card -> CardMatcher)
-> CardMatcher -> Card -> CardMatcher
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
merfolk))
            (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
3, Int
3) [Char]
"Merfolk Mistbinder 2"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Use Undercity Uprising on Adeliz to destroy Shalai" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"G" (Int -> [Char] -> [Char]
numbered Int
1 [Char]
"Timber Gorge")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" (Int -> [Char] -> [Char]
numbered Int
1 [Char]
"Submerged Boneyard")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" (Int -> [Char] -> [Char]
numbered Int
2 [Char]
"Submerged Boneyard")

    ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> GameMonad ()
cast [Char]
"1GB") [Char]
"Undercity Uprising"
    [Char] -> GameMonad ()
resolve [Char]
"Undercity Uprising"
    CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards
      ([Char] -> CardMatcher
matchAttribute [Char]
creature CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play))
      ([Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
deathtouch)

    [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with [Char]
"Shalai, Voice of Plenty" (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
      GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
        [Char] -> [Char] -> GameMonad ()
fight [Char]
"Adeliz, the Cinder Wind" [Char]
enemy
      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Doublecast" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"R" (Int -> [Char] -> [Char]
numbered Int
2 [Char]
"Timber Gorge")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"R" (Int -> [Char] -> [Char]
numbered Int
3 [Char]
"Timber Gorge")
    ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> GameMonad ()
cast [Char]
"RR") [Char]
"Doublecast 1"

    [Char] -> GameMonad ()
resolve [Char]
"Doublecast 2"
    [Char] -> GameMonad ()
resolve [Char]
"Doublecast 1"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Plummet to destroy all fliers" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"G" [Char]
"Timber Gorge 4"
    ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> GameMonad ()
cast [Char]
"G") [Char]
"Plummet 1"

    -- From double doublecast earlier
    [Char] -> [Char] -> GameMonad ()
copySpell [Char]
"Plummet 4" [Char]
"Plummet 1"
    [Char] -> [Char] -> GameMonad ()
copySpell [Char]
"Plummet 5" [Char]
"Plummet 1"

    [Char] -> GameMonad ()
resolve [Char]
"Plummet 5"
    [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with [Char]
"Lyra Dawnbringer" (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
      [Char] -> GameMonad ()
target [Char]
enemy
      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
flying
      [Char] -> GameMonad ()
destroy [Char]
enemy
      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)

    [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
1..Int
3] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
      [Char] -> GameMonad ()
resolve (Int -> [Char] -> [Char]
numbered (Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Char]
"Plummet")
      [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with (Int -> [Char] -> [Char]
numbered Int
n [Char]
"Angel") (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
        [Char] -> GameMonad ()
target [Char]
enemy
        [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
flying
        [Char] -> GameMonad ()
destroy [Char]
enemy

    [Char] -> GameMonad ()
resolve [Char]
"Plummet 1" -- No target

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Quasiduplicate on archer, destroy one of the Mistbinders" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" (Int -> [Char] -> [Char]
numbered Int
1 [Char]
"Highland Lake")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" (Int -> [Char] -> [Char]
numbered Int
2 [Char]
"Highland Lake")
    ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> GameMonad ()
cast [Char]
"UU") [Char]
"Quasiduplicate 1"

    [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with ([Char]
"Merfolk Mistbinder 2") (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
      GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
1..Int
4] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
        let tokenName :: [Char]
tokenName = ([Char]
"Afzocan Archer " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n)
        [Char] -> GameMonad ()
resolve ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered (Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Char]
"Quasiduplicate"
        [Char] -> GameMonad ()
addArcherCopy [Char]
tokenName
        [Char] -> [Char] -> GameMonad ()
fight [Char]
tokenName [Char]
enemy

      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Jump-start Quasiduplicate again (w/ Waterknot), destroy merfolk" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" (Int -> [Char] -> [Char]
numbered Int
3 [Char]
"Highland Lake")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" (Int -> [Char] -> [Char]
numbered Int
4 [Char]
"Highland Lake")
    ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> [Char] -> GameMonad ()
jumpstart [Char]
"UU" [Char]
"Waterknot") [Char]
"Quasiduplicate 1"

    [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with (Int -> [Char] -> [Char]
numbered Int
1 [Char]
"Merfolk Mistbinder") (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
      GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
1..Int
2] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
        let tokenName :: [Char]
tokenName = ([Char]
"Afzocan Archer " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n)
        [Char] -> GameMonad ()
resolve ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered (Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Char]
"Quasiduplicate"
        [Char] -> GameMonad ()
addArcherCopy [Char]
tokenName
        [Char] -> [Char] -> GameMonad ()
fight [Char]
tokenName [Char]
enemy

      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)

    [Char] -> ([Char] -> GameMonad ()) -> GameMonad ()
with [Char]
"Kopala, Warden of Waves" (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
enemy -> do
      GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
3..Int
4] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
        let tokenName :: [Char]
tokenName = Int -> [Char] -> [Char]
numbered Int
n [Char]
"Afzocan Archer"
        [Char] -> GameMonad ()
resolve ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered (Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Char]
"Quasiduplicate"
        [Char] -> GameMonad ()
addArcherCopy [Char]
tokenName
        [Char] -> [Char] -> GameMonad ()
fight [Char]
tokenName [Char]
enemy

      [Char] -> CardMatcher -> GameMonad ()
validate [Char]
enemy (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)

    [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
5] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
      let tokenName :: [Char]
tokenName = Int -> [Char] -> [Char]
numbered Int
n [Char]
"Afzocan Archer"
      [Char] -> GameMonad ()
resolve ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered (Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Char]
"Quasiduplicate"
      [Char] -> GameMonad ()
addArcherCopy [Char]
tokenName

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Torgaar, sacrificing archers to reduce cost" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" (Int -> [Char] -> [Char]
numbered Int
3 [Char]
"Submerged Boneyard")
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" (Int -> [Char] -> [Char]
numbered Int
4 [Char]
"Submerged Boneyard")
    [Char] -> GameMonad ()
sacrifice ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered Int
1 [Char]
"Afzocan Archer"
    [Char] -> GameMonad ()
sacrifice ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered Int
2 [Char]
"Afzocan Archer"
    [Char] -> GameMonad ()
sacrifice ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered Int
3 [Char]
"Afzocan Archer"
    [Char] -> [Char] -> GameMonad ()
cast [Char]
"BB" [Char]
"Torgaar, Famine Incarnate"
    [Char] -> GameMonad ()
resolve [Char]
"Torgaar, Famine Incarnate"
    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
setLife Int
10

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Attack with Adeliz and initial archer for lethal" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [[Char]] -> GameMonad ()
attackWith [[Char]
"Adeliz, the Cinder Wind", [Char]
"Afzocan Archer"]

    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Adeliz, the Cinder Wind"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Afzocan Archer"

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

formatter :: Int -> Formatter
formatter :: Int -> Formatter
formatter Int
_ = 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]
"mana" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> 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")
  [Char] -> GameMonad Int -> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"storm"  (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> GameMonad Int
countValue [Char]
"storm"
  [Char] -> GameMonad CardStrength -> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"adeliz" (GameMonad CardStrength -> FormatMonad ())
-> GameMonad CardStrength -> FormatMonad ()
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 -> CardStrength)
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Card
-> GameMonad CardStrength
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char]
-> CardMatcher
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Card
requireCard [Char]
"Adeliz, the Cinder Wind" CardMatcher
forall a. Monoid a => a
mempty
  [Char] -> GameMonad Int -> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"enemies" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher -> GameMonad Int
countCards (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Play))

triggerStorm :: (Int -> GameMonad ()) -> GameMonad ()
triggerStorm :: (Int -> GameMonad ()) -> GameMonad ()
triggerStorm Int -> GameMonad ()
action = do
  Maybe Int
maybeStorm <- Getting (Maybe Int) Board (Maybe Int)
-> ExceptT
     [Char]
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe Int)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use (Getting (Maybe Int) Board (Maybe Int)
 -> ExceptT
      [Char]
      (ReaderT Env (StateT Board (WriterT [Step] Identity)))
      (Maybe Int))
-> Getting (Maybe Int) Board (Maybe Int)
-> ExceptT
     [Char]
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe Int)
forall a b. (a -> b) -> a -> b
$ (HashMap [Char] Int -> Const (Maybe Int) (HashMap [Char] Int))
-> Board -> Const (Maybe Int) Board
Lens' Board (HashMap [Char] Int)
counters ((HashMap [Char] Int -> Const (Maybe Int) (HashMap [Char] Int))
 -> Board -> Const (Maybe Int) Board)
-> ((Maybe Int -> Const (Maybe Int) (Maybe Int))
    -> HashMap [Char] Int -> Const (Maybe Int) (HashMap [Char] Int))
-> Getting (Maybe Int) Board (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap [Char] Int)
-> Lens'
     (HashMap [Char] Int) (Maybe (IxValue (HashMap [Char] Int)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at [Char]
Index (HashMap [Char] Int)
"storm"

  case Maybe Int
maybeStorm of
    Maybe Int
Nothing -> [Char]
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) [()]
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"No counter in state: storm"
    Just Int
c -> [Int]
-> (Int -> GameMonad ())
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
1..Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> GameMonad ())
 -> ExceptT
      [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) [()])
-> (Int -> GameMonad ())
-> ExceptT
     [Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) [()]
forall a b. (a -> b) -> a -> b
$ \Int
n -> Int -> GameMonad ()
action Int
n

  () -> GameMonad ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()