module Solutions.WarOfTheSpark2 where

import Dovin.V3

dinosaur :: [Char]
dinosaur = [Char]
"dinosaur"

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
4

    Location -> GameMonad () -> GameMonad ()
withLocation Location
Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad ()
addAura [Char]
"Kaya's Ghostform"
      [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]
"Dreadhorde Butcher"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Merfolk Trickster"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Massacre Girl"

    Location -> GameMonad () -> GameMonad ()
withLocation Location
Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Steam Vents"
      Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Blood Crypt"

      Int -> GameMonad () -> GameMonad ()
withPlusOneCounters Int
2 (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Flux Channeler"
      Int -> GameMonad () -> GameMonad ()
withPlusOneCounters Int
3 (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
firststrike (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
1) [Char]
"Rigging Runner"
      Int -> GameMonad () -> GameMonad ()
withPlusOneCounters Int
1 (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
2) [Char]
"Spellgorger Weird"

    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Location -> GameMonad () -> GameMonad ()
withLocation Location
Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
        (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
3, Int
2) [Char]
"Midnight Reaper"
        EffectMonad Bool
-> EffectMonad CardMatcher
-> [LayeredEffectPart]
-> [Char]
-> GameMonad ()
-> GameMonad ()
withEffectWhen
          (do
            Player
controller <- Getting Player Card Player
-> ReaderT EffectMonadEnv Identity Player
forall b. Getting b Card b -> ReaderT EffectMonadEnv Identity b
viewSelf Getting Player Card Player
Lens' Card Player
cardController
            [Card]
dinos <- CardMatcher -> EffectMonad [Card]
askCards (CardMatcher -> EffectMonad [Card])
-> CardMatcher -> EffectMonad [Card]
forall a b. (a -> b) -> a -> b
$ [Char] -> CardMatcher
matchAttribute [Char]
dinosaur
                             CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher
matchInPlay
                             CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> Player -> CardMatcher
matchController Player
controller

            Bool -> EffectMonad Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> EffectMonad Bool) -> Bool -> EffectMonad Bool
forall a b. (a -> b) -> a -> b
$ [Card] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Card]
dinos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
          )
          (Card -> CardMatcher
matchCard (Card -> CardMatcher)
-> ReaderT EffectMonadEnv Identity Card -> EffectMonad CardMatcher
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT EffectMonadEnv Identity Card
askSelf)
          [ (Int, Int) -> LayeredEffectPart
effectPTAdjust (Int
2, Int
2)
          ]
          [Char]
"+2/+2 so long as you control another dinosaur"
            (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
1) [Char]
"Drover of the Mighty"

        [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
indestructible, [Char]
dinosaur] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
          (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
8) [Char]
"Zetalpa, Primal Dawn"
        (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
5, Int
5) [Char]
"God-Eternal Rhonas"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Merfolk Trickster, targeting Drover" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Steam Vents 1"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Steam Vents 2"

    [Char] -> [Char] -> GameMonad ()
cast [Char]
"UU" [Char]
"Merfolk Trickster" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

    [Char] -> GameMonad ()
target [Char]
"Drover of the Mighty"
    LayeredEffectPart -> [Char] -> GameMonad ()
addEffect LayeredEffectPart
effectNoAbilities [Char]
"Drover of the Mighty"
    [Char] -> GameMonad ()
tap [Char]
"Drover of the Mighty"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Kaya's Ghostform on Merfolk Trickster" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Blood Crypt 1"

    [Char] -> [Char] -> GameMonad ()
cast [Char]
"B" [Char]
"Kaya's Ghostform"
    [Char] -> GameMonad ()
target [Char]
"Merfolk Trickster"

    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"Proliferate" [Char]
"Flux Channeler"
    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"+1/+1" [Char]
"Spellgorger Weird"

    [Char] -> GameMonad ()
resolve [Char]
"+1/+1"
    ASetter Card Card Int Int -> (Int -> Int) -> [Char] -> GameMonad ()
forall a b.
ASetter Card Card a b -> (a -> b) -> [Char] -> GameMonad ()
modifyCard ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Char]
"Spellgorger Weird"

    [Char] -> GameMonad ()
resolve [Char]
"Proliferate"
    ASetter Card Card Int Int -> (Int -> Int) -> [Char] -> GameMonad ()
forall a b.
ASetter Card Card a b -> (a -> b) -> [Char] -> GameMonad ()
modifyCard ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Char]
"Spellgorger Weird"
    ASetter Card Card Int Int -> (Int -> Int) -> [Char] -> GameMonad ()
forall a b.
ASetter Card Card a b -> (a -> b) -> [Char] -> GameMonad ()
modifyCard ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Char]
"Rigging Runner"
    ASetter Card Card Int Int -> (Int -> Int) -> [Char] -> GameMonad ()
forall a b.
ASetter Card Card a b -> (a -> b) -> [Char] -> GameMonad ()
modifyCard ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Char]
"Flux Channeler"

    [Char] -> GameMonad ()
resolve [Char]
"Kaya's Ghostform"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Cast Massacre Girl, killing Drover" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Blood Crypt 2"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Blood Crypt 3"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Blood Crypt 4"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Steam Vents 3"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Steam Vents 4"

    [Char] -> [Char] -> GameMonad ()
cast [Char]
"3BB" [Char]
"Massacre Girl" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

    GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards (CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert ([Char] -> CardMatcher
matchName [Char]
"Massacre Girl")) (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
        LayeredEffectPart -> [Char] -> GameMonad ()
addEffect ((Int, Int) -> LayeredEffectPart
effectPTAdjust (-Int
1, -Int
1)) [Char]
cn

    CardMatcher -> [Char] -> GameMonad ()
validate (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)) [Char]
"Drover of the Mighty"

    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"-1/-1" [Char]
"Massacre Girl"
    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> [Char] -> GameMonad ()
trigger [Char]
"Self-damage" [Char]
"Midnight Reaper"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Resolve midnight reaper damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> GameMonad ()
resolve [Char]
"Self-damage"

    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
loseLife Int
1

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Resolve -1/-1, killing Midnight Reaper and Trickster" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> GameMonad ()
resolve [Char]
"-1/-1"

    GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards (CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert ([Char] -> CardMatcher
matchName [Char]
"Massacre Girl")) (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
        LayeredEffectPart -> [Char] -> GameMonad ()
addEffect ((Int, Int) -> LayeredEffectPart
effectPTAdjust (-Int
1, -Int
1)) [Char]
cn

    -- Active player triggers stack first
    CardMatcher -> [Char] -> GameMonad ()
validate (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard)) [Char]
"Merfolk Trickster"
    CardMatcher -> [Char] -> GameMonad ()
validate (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Graveyard)) [Char]
"Midnight Reaper"
    Location -> [Char] -> GameMonad ()
moveTo Location
Graveyard [Char]
"Kaya's Ghostform"

    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"Return Trickster" [Char]
"Kaya's Ghostform"
    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"-1/-1 Trickster" [Char]
"Massacre Girl"
    [Char] -> [Char] -> GameMonad ()
trigger [Char]
"-1/-1 Reaper" [Char]
"Massacre Girl"
    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> [Char] -> GameMonad ()
trigger [Char]
"Self-damage" [Char]
"Midnight Reaper"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Resolve midnight reaper damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> GameMonad ()
resolve [Char]
"Self-damage"

    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
loseLife Int
1

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Resolve -1/-1 for Reaper" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> GameMonad ()
resolve [Char]
"-1/-1 Reaper"

    GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards (CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert ([Char] -> CardMatcher
matchName [Char]
"Massacre Girl")) (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
        LayeredEffectPart -> [Char] -> GameMonad ()
addEffect ((Int, Int) -> LayeredEffectPart
effectPTAdjust (-Int
1, -Int
1)) [Char]
cn

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Resolve -1/-1 for Trickster" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> GameMonad ()
resolve [Char]
"-1/-1 Trickster"

    GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards (CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert ([Char] -> CardMatcher
matchName [Char]
"Massacre Girl")) (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
        LayeredEffectPart -> [Char] -> GameMonad ()
addEffect ((Int, Int) -> LayeredEffectPart
effectPTAdjust (-Int
1, -Int
1)) [Char]
cn

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Return Trickster to play from Ghostform, targeting God-Eternal" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    Location -> [Char] -> GameMonad ()
moveTo Location
Play [Char]
"Merfolk Trickster"

    [Char] -> GameMonad ()
target [Char]
"God-Eternal Rhonas"
    [Char] -> GameMonad ()
tap [Char]
"God-Eternal Rhonas"
    LayeredEffectPart -> [Char] -> GameMonad ()
addEffect LayeredEffectPart
effectNoAbilities [Char]
"God-Eternal Rhonas"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Attack with all original creatures, opponent can only block 1 and can't kill it" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [[Char]] -> GameMonad ()
attackWith [[Char]
"Flux Channeler", [Char]
"Rigging Runner", [Char]
"Spellgorger Weird"]

    -- First strike damage
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Zetalpa, Primal Dawn"] [Char]
"Rigging Runner"

    -- Regular damage
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Flux Channeler"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Spellgorger Weird"

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

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]
"life" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player -> GameMonad Int
countLife Player
Opponent
formatter :: p -> Formatter
formatter p
_ = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
boardFormatter