module Solutions.RavnicaAllegiance7 where

import Dovin.V2
import Dovin.Prelude

unblockable :: [Char]
unblockable = [Char]
"unblockable"

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
18

    Location -> GameMonad () -> GameMonad ()
withLocation Location
Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> GameMonad ()
addAura [Char]
"Deep Freeze 1"
      [Char] -> GameMonad ()
addAura [Char]
"Sky Tether"
      [Char] -> GameMonad ()
addSorcery [Char]
"Ghostform"

    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]
"Hallowed Fountain"
      Int -> [Char] -> GameMonad ()
addLands Int
2 [Char]
"Stomping Ground"
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
trample (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
0, Int
8) [Char]
"Erratic Cyclops"
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
0, Int
4) [Char]
"Suspicious Bookcase 1"
      [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
0, Int
4) [Char]
"Suspicious Bookcase 2"
      (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
2, Int
1) [Char]
"Goblin Locksmith"
      [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
vigilance] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
3, Int
5) [Char]
"Arcades, the Strategist"
      [Char] -> GameMonad ()
addAura [Char]
"Deep Freeze 2"

    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
        [[Char]] -> GameMonad () -> GameMonad ()
withAttributes [[Char]
flying, [Char]
lifelink] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
5, Int
5) [Char]
"Lyra Dawnbringer"
        (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
1) [Char]
"Gyre Engineer 1"
        (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
1) [Char]
"Gyre Engineer 2"
        [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
0, Int
4) [Char]
"Gyre Engineer 3"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Deep Freeze opposing Lyra" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Hallowed Fountain 1"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Hallowed Fountain 2"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"G" [Char]
"Stomping Ground 1"
    [Char] -> [Char] -> GameMonad ()
cast [Char]
"2U" [Char]
"Deep Freeze 1" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

    [Char] -> GameMonad ()
target [Char]
"Lyra Dawnbringer"
    [Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
defender [Char]
"Lyra Dawnbringer"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Sky Tether Erratic Cyclops" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"W" [Char]
"Hallowed Fountain 3"
    [Char] -> [Char] -> GameMonad ()
cast [Char]
"W" [Char]
"Sky Tether" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

    [Char] -> GameMonad ()
target [Char]
"Erratic Cyclops"
    [Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
defender [Char]
"Erratic Cyclops"

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Ghostform both bookcases" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"U" [Char]
"Hallowed Fountain 4"
    [Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"G" [Char]
"Stomping Ground 2"

    [Char] -> [Char] -> GameMonad ()
cast [Char]
"1U" [Char]
"Ghostform" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop

    [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
      [Char] -> GameMonad ()
target ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
numbered Int
n [Char]
"Suspicious Bookcase"
      [Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
unblockable (Int -> [Char] -> [Char]
numbered Int
n [Char]
"Suspicious Bookcase")

  [Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Attack with all, only two wizards can block Goblin and Cyclops" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    -- Don't use attackWith here, because want to allow defenders to attack
    let attackers :: CardMatcher
attackers = CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
creature
    CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards CardMatcher
attackers (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
      [Char] -> GameMonad ()
tap [Char]
cn
      [Char] -> [Char] -> GameMonad ()
gainAttribute [Char]
attacking [Char]
cn

    CardMatcher -> ([Char] -> GameMonad ()) -> GameMonad ()
forCards (CardMatcher
attackers CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
matchAttribute [Char]
defender) (([Char] -> GameMonad ()) -> GameMonad ())
-> ([Char] -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \[Char]
cn -> do
      -- Fake Arcades effect, it shouldn't actually change their power.
      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 Int
p Int
t) -> Int -> Int -> CardStrength
CardStrength Int
t Int
t) [Char]
cn

    -- Defenders can't block, per Goblin Locksmith
    CardMatcher -> [Char] -> GameMonad ()
validate ([Char] -> CardMatcher
matchAttribute [Char]
defender) [Char]
"Gyre Engineer 3"
    CardMatcher -> [Char] -> GameMonad ()
validate ([Char] -> CardMatcher
matchAttribute [Char]
defender) [Char]
"Lyra Dawnbringer"

    -- No flyers to block
    CardMatcher -> [Char] -> GameMonad ()
validate ([Char] -> CardMatcher
matchAttribute [Char]
flying) [Char]
"Arcades, the Strategist"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Arcades, the Strategist"

    -- Bookcases cannot be blocked
    CardMatcher -> [Char] -> GameMonad ()
validate ([Char] -> CardMatcher
matchAttribute [Char]
unblockable) [Char]
"Suspicious Bookcase 1"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Suspicious Bookcase 1"
    CardMatcher -> [Char] -> GameMonad ()
validate ([Char] -> CardMatcher
matchAttribute [Char]
unblockable) [Char]
"Suspicious Bookcase 2"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [] [Char]
"Suspicious Bookcase 2"

    -- Only remaining blocks
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Gyre Engineer 1"] [Char]
"Goblin Locksmith"
    [[Char]] -> [Char] -> GameMonad ()
combatDamage [[Char]
"Gyre Engineer 2"] [Char]
"Erratic Cyclops"

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

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