module Solutions.ChannelFireball where
import Dovin.V2
import Dovin.Prelude
import Control.Lens
solution :: GameMonad ()
solution :: GameMonad ()
solution = do
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Initial state" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Int -> GameMonad ()
setLife Int
1
Location -> GameMonad () -> GameMonad ()
withLocation Location
Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Int -> String -> GameMonad ()
addLands Int
4 String
"Steam Vents"
Int -> String -> GameMonad ()
addLands Int
4 String
"Breeding Pool"
String -> GameMonad ()
addArtifact String
"Aetherflux Reservoir"
(Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
2) String
"Beamsplitter Mage"
(Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
2) String
"Man-o'-War"
Location -> GameMonad () -> GameMonad ()
withLocation Location
Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> GameMonad ()
addInstant String
"High Tide"
String -> GameMonad ()
addInstant String
"Snap"
String -> GameMonad ()
addInstant String
"Rewind"
String -> GameMonad ()
addSorcery String
"Baral's Expertise"
String -> GameMonad ()
addSorcery String
"Channel"
String -> GameMonad ()
addSorcery String
"Fireball"
String -> GameMonad () -> GameMonad ()
withAttribute String
flash (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
1) String
"Snapcaster Mage"
(Int, Int) -> String -> GameMonad ()
addCreature (Int
0, Int
0) String
"Walking Ballista"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast High Tide with a Steam Vents" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Steam Vents 1"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"U") String
"High Tide"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
1
String -> GameMonad ()
resolve String
"High Tide"
ASetter Board Board Int Int -> (Int -> Int) -> GameMonad ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying
ASetter Board Board Int Int
Lens' Board Int
highTideCounter
(Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Snapcaster, targeting High Tide, with second Steam Vents" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Steam Vents 2"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
2
String -> GameMonad ()
resolve String
"Snapcaster Mage"
CardLocation -> String -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) String
"High Tide"
String -> String -> GameMonad ()
gainAttribute String
snapped String
"High Tide"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Flashback High Tide with third Steam Vents" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Steam Vents 3"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
flashbackSnapped String
"U") String
"High Tide"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
3
String -> GameMonad ()
resolve String
"High Tide"
ASetter Board Board Int Int -> (Int -> Int) -> GameMonad ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying
ASetter Board Board Int Int
Lens' Board Int
highTideCounter
(Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Tap five remaining lands for 3 mana each" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 4"
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 1"
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 2"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 3"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Walking Ballista for 1, leave on stack" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"") String
"Walking Ballista"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Stack Snap, targeting Beamsplitter then copying to Snapcaster" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snap"
String -> GameMonad ()
target String
"Beamsplitter Mage"
String -> String -> GameMonad ()
trigger String
"Copied Snap" String
"Beamsplitter Mage" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
String -> String -> GameMonad ()
copySpell String
"Snap Copy (Snapcaster Mage)" String
"Snap"
String -> GameMonad ()
target String
"Snapcaster Mage"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Counter Walking Ballista with Rewind, untapping Steam Vents" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"2UU") String
"Rewind"
String -> GameMonad ()
counter String
"Walking Ballista"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
6
String -> GameMonad ()
resolve String
"Rewind"
String -> GameMonad ()
untap String
"Steam Vents 1"
String -> GameMonad ()
untap String
"Steam Vents 2"
String -> GameMonad ()
untap String
"Steam Vents 3"
String -> GameMonad ()
untap String
"Steam Vents 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Resolve Snap copy, returning Snapcaster, untapping Breeding Pools" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> GameMonad ()
resolve String
"Snap Copy (Snapcaster Mage)"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Snapcaster Mage"
String -> GameMonad ()
untap String
"Breeding Pool 1"
String -> GameMonad ()
untap String
"Breeding Pool 2"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Resolve Snap, returning Beamsplitter, untapping Breeding Pools" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
5
String -> GameMonad ()
resolve String
"Snap"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Beamsplitter Mage"
String -> GameMonad ()
untap String
"Breeding Pool 3"
String -> GameMonad ()
untap String
"Breeding Pool 4"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
4
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Recast Beamsplitter, stacking Snapcaster targeting Snap" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"RU") String
"Beamsplitter Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
8
String -> GameMonad ()
resolve String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
7
String -> GameMonad ()
resolve String
"Beamsplitter Mage"
CardLocation -> String -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) String
"Snap"
String -> String -> GameMonad ()
gainAttribute String
snapped String
"Snap"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Tap all lands for 3 mana each" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Steam Vents 1"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Steam Vents 2"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 3"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 4"
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 1"
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 2"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 3"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Stack flashbacked Snap, targeting Beamsplitter then copy to Snapcaster" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
flashbackSnapped String
"1U") String
"Snap"
String -> GameMonad ()
target String
"Beamsplitter Mage"
String -> String -> GameMonad ()
trigger String
"Copied Snap" String
"Beamsplitter Mage" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
String -> String -> GameMonad ()
copySpell String
"Snap Copy (Snapcaster Mage)" String
"Snap"
String -> GameMonad ()
target String
"Snapcaster Mage"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Resolve Snap copy, returning Snapcaster, untap Breeding Pools" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> GameMonad ()
resolve String
"Snap Copy (Snapcaster Mage)"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Snapcaster Mage"
String -> GameMonad ()
untap String
"Breeding Pool 1"
String -> GameMonad ()
untap String
"Breeding Pool 2"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Replay Snapcaster, targeting Rewind" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
10
String -> GameMonad ()
resolve String
"Snapcaster Mage"
CardLocation -> String -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) String
"Rewind"
String -> String -> GameMonad ()
gainAttribute String
snapped String
"Rewind"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Resolve Snap on Beamsplitter, untap Steam Vents" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
9
String -> GameMonad ()
resolve String
"Snap"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Beamsplitter Mage"
String -> GameMonad ()
untap String
"Steam Vents 3"
String -> GameMonad ()
untap String
"Steam Vents 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Baral's Expertise for all 3 in play, replaying Aetherflux for free" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"3UU") String
"Baral's Expertise"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
11
String -> GameMonad ()
resolve String
"Baral's Expertise"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Aetherflux Reservoir"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Man-o'-War"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Snapcaster Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"") String
"Aetherflux Reservoir"
String -> GameMonad ()
resolve String
"Aetherflux Reservoir"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Beamsplitter Mage, stacking Snapcaster targeting Baral's" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"UR") String
"Beamsplitter Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
14
String -> GameMonad ()
resolve String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
13
String -> GameMonad ()
resolve String
"Beamsplitter Mage"
CardLocation -> String -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) String
"Baral's Expertise"
String -> String -> GameMonad ()
gainAttribute String
snapped String
"Baral's Expertise"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Flashback Baral's Expertise targeting all 3 in play, replaying Aetherflux" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
flashbackSnapped String
"3UU") String
"Baral's Expertise"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
15
String -> GameMonad ()
resolve String
"Baral's Expertise"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Aetherflux Reservoir"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Beamsplitter Mage"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Snapcaster Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"") String
"Aetherflux Reservoir"
String -> GameMonad ()
resolve String
"Aetherflux Reservoir"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Tap remaining lands for 3 mana each" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 1"
String -> String -> GameMonad ()
tapForManaWithTide String
"G" String
"Breeding Pool 2"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 3"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Channel and Fireball for life only" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"GG") String
"Channel"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
17
String -> GameMonad ()
resolve String
"Channel"
Int
l <- (-) (Int -> Int -> Int)
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> ExceptT
String
(ReaderT Env (StateT Board (WriterT [Step] Identity)))
(Int -> Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Active ExceptT
String
(ReaderT Env (StateT Board (WriterT [Step] Identity)))
(Int -> Int)
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
1
let payment :: String
payment = Int -> String
forall a. Show a => a -> String
show Int
l String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"R"
Int -> GameMonad ()
loseLife Int
l
String -> GameMonad ()
addMana (String -> GameMonad ()) -> String -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
l
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
payment) String
"Fireball"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
18
String -> GameMonad ()
resolve String
"Fireball"
(Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
l) (Player -> Target
targetPlayer Player
Opponent) String
"Fireball"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Beamsplitter Mage, stacking Snapcaster targeting Fireball" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"UR") String
"Beamsplitter Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
20
String -> GameMonad ()
resolve String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
19
String -> GameMonad ()
resolve String
"Beamsplitter Mage"
CardLocation -> String -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) String
"Fireball"
String -> String -> GameMonad ()
gainAttribute String
snapped String
"Fireball"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Man-'o-War, returning Snapcaster Mage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"2U") String
"Man-o'-War"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
21
String -> GameMonad ()
resolve String
"Man-o'-War"
String -> GameMonad ()
target String
"Snapcaster Mage"
CardLocation -> CardLocation -> String -> GameMonad ()
move (Player
Active, Location
Play) (Player
Active, Location
Hand) String
"Snapcaster Mage"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Snapcaster, counter with flashback Rewind" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
cast String
"1U") String
"Snapcaster Mage"
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
flashbackSnapped String
"2UU") String
"Rewind"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
23
String -> GameMonad ()
resolve String
"Rewind"
String -> GameMonad ()
counter String
"Snapcaster Mage"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
22
String -> GameMonad ()
untap String
"Breeding Pool 1"
String -> GameMonad ()
untap String
"Breeding Pool 2"
String -> GameMonad ()
untap String
"Steam Vents 3"
String -> GameMonad ()
untap String
"Steam Vents 4"
String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Flashback Fireball with all remaining mana and life" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 1"
String -> String -> GameMonad ()
tapForManaWithTide String
"U" String
"Breeding Pool 2"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 3"
String -> String -> GameMonad ()
tapForManaWithTide String
"R" String
"Steam Vents 4"
Int
life <- Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Active
Int
mana <- Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countManaPool Player
Active
let dmg :: Int
dmg = (Int
life Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
mana Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
let payment :: String
payment = Int -> String
forall a. Show a => a -> String
show Int
dmg String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"R"
Int -> GameMonad ()
loseLife (Int
life Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
String -> GameMonad ()
addMana (String -> GameMonad ()) -> String -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int
life Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
(String -> GameMonad ()) -> String -> GameMonad ()
forall t a.
(t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers (String -> String -> GameMonad ()
flashbackSnapped String
payment) String
"Fireball"
Integer -> GameMonad ()
forall a. Show a => a -> GameMonad ()
resolveAetherflux Integer
24
String -> GameMonad ()
resolve String
"Fireball"
(Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
life) (Player -> Target
targetPlayer Player
Opponent) String
"Fireball"
attributes :: Formatter
attributes = FormatMonad () -> Formatter
attributeFormatter (FormatMonad () -> Formatter) -> FormatMonad () -> Formatter
forall a b. (a -> b) -> a -> b
$ do
String
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"life" (ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Active
String
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"pool" (ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countManaPool Player
Active
String
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"spells" (ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Getting Int Board Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Int Board Int
Lens' Board Int
spellCounter
playExLandFormatter :: Formatter
playExLandFormatter = String -> CardMatcher -> Formatter
cardFormatter String
"Play (ex. Land)"
(CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play) CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert (String -> CardMatcher
matchAttribute String
land))
formatter :: Step -> Formatter
formatter Step
step = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> case Getting Int Step Int -> Step -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int Step Int
Lens' Step Int
stepNumber Step
step of
Int
1 -> Formatter
boardFormatter
Int
3 -> String -> CardMatcher -> Formatter
cardFormatter String
"Play" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
6 -> Formatter
stackFormatter
Int
7 -> Formatter
stackFormatter
Int
8 -> Formatter
stackFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Play" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play))
Int
9 -> Formatter
stackFormatter
Int
10 -> Formatter
stackFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
11 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Play" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
13 -> Formatter
stackFormatter
Int
14 -> Formatter
stackFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
15 -> Formatter
stackFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
16 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Play" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play))
Int
17 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
playExLandFormatter
Int
18 ->
Formatter
playExLandFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
19 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
playExLandFormatter
Int
21 -> FormatMonad () -> Formatter
attributeFormatter (String
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"opponent" (ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Opponent)
Int
22 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
playExLandFormatter
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"Graveyard" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Graveyard))
Int
23 ->
String -> CardMatcher -> Formatter
cardFormatter String
"Hand" (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Hand))
Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
playExLandFormatter
Int
25 -> FormatMonad () -> Formatter
attributeFormatter (String
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"opponent" (ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Opponent)
Int
_ -> Formatter
forall a. Monoid a => a
mempty
spellCounter :: Lens' Board Int
spellCounter :: (Int -> f Int) -> Board -> f Board
spellCounter = (HashMap String Int -> f (HashMap String Int)) -> Board -> f Board
Lens' Board (HashMap String Int)
counters ((HashMap String Int -> f (HashMap String Int))
-> Board -> f Board)
-> ((Int -> f Int) -> HashMap String Int -> f (HashMap String Int))
-> (Int -> f Int)
-> Board
-> f Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap String Int)
-> Lens'
(HashMap String Int) (Maybe (IxValue (HashMap String Int)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at String
Index (HashMap String Int)
"spell-count" ((Maybe Int -> f (Maybe Int))
-> HashMap String Int -> f (HashMap String Int))
-> ((Int -> f Int) -> Maybe Int -> f (Maybe Int))
-> (Int -> f Int)
-> HashMap String Int
-> f (HashMap String Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Iso' (Maybe Int) Int
forall a. Eq a => a -> Iso' (Maybe a) a
non Int
0
highTideCounter :: Lens' Board Int
highTideCounter :: (Int -> f Int) -> Board -> f Board
highTideCounter = (HashMap String Int -> f (HashMap String Int)) -> Board -> f Board
Lens' Board (HashMap String Int)
counters ((HashMap String Int -> f (HashMap String Int))
-> Board -> f Board)
-> ((Int -> f Int) -> HashMap String Int -> f (HashMap String Int))
-> (Int -> f Int)
-> Board
-> f Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap String Int)
-> Lens'
(HashMap String Int) (Maybe (IxValue (HashMap String Int)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at String
Index (HashMap String Int)
"high-tide-count" ((Maybe Int -> f (Maybe Int))
-> HashMap String Int -> f (HashMap String Int))
-> ((Int -> f Int) -> Maybe Int -> f (Maybe Int))
-> (Int -> f Int)
-> HashMap String Int
-> f (HashMap String Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Iso' (Maybe Int) Int
forall a. Eq a => a -> Iso' (Maybe a) a
non Int
0
aetherfluxTriggerName :: a -> String
aetherfluxTriggerName a
n = String
"Aetherflux Trigger #" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
n
snapped :: String
snapped = String
"snapped"
withTriggers :: (t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> t -> GameMonad ()
withTriggers t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a
fn t
name = do
t
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) a
fn t
name
ASetter Board Board Int Int -> (Int -> Int) -> GameMonad ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying
ASetter Board Board Int Int
Lens' Board Int
spellCounter
(Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
CardMatcher -> (String -> GameMonad ()) -> GameMonad ()
forCards
(CardMatcher
matchInPlay CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher
matchName String
"Aetherflux Reservoir")
((String -> GameMonad ()) -> GameMonad ())
-> (String -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ GameMonad () -> String -> GameMonad ()
forall a b. a -> b -> a
const (GameMonad () -> String -> GameMonad ())
-> GameMonad () -> String -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Int
x <- Getting Int Board Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Int Board Int
Lens' Board Int
spellCounter
String -> String -> GameMonad ()
trigger (Int -> String
forall a. Show a => a -> String
aetherfluxTriggerName Int
x) String
"Aetherflux Reservoir"
tapForManaWithTide :: String -> String -> GameMonad ()
tapForManaWithTide String
pool String
cn = do
String -> String -> GameMonad ()
tapForMana String
pool String
cn
Int
x <- Getting Int Board Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Int Board Int
Lens' Board Int
highTideCounter
String -> GameMonad ()
addMana (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
x Char
'U')
resolveAetherflux :: a -> GameMonad ()
resolveAetherflux a
n = do
String -> GameMonad ()
resolve (String -> GameMonad ()) -> String -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
aetherfluxTriggerName a
n
Int
x <- Getting Int Board Int
-> ExceptT
String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Int Board Int
Lens' Board Int
spellCounter
Int -> GameMonad ()
gainLife Int
x
flashbackSnapped :: String -> String -> GameMonad ()
flashbackSnapped String
mana String
castName = do
CardMatcher -> String -> GameMonad ()
validate (String -> CardMatcher
matchAttribute String
snapped) String
castName
String -> String -> GameMonad ()
flashback String
mana String
castName