module Solutions.GuildsOfRavnica8 where
import Control.Monad.Except (throwError, when)
import Control.Lens
import qualified Data.Set as S
import Dovin.V1
solution :: GameMonad ()
solution :: GameMonad ()
solution = do
let black :: [Char]
black = [Char]
"black"
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]
"Diamond Mare"
Card
c <- [Char] -> CardMatcher -> GameMonad Card
requireCard [Char]
name CardMatcher
forall a. Monoid a => a
mempty
Bool -> GameMonad () -> GameMonad ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Char] -> Card -> Bool
hasAttribute [Char]
black Card
c) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Int -> GameMonad ()
gainLife Int
1
[Char] -> GameMonad ()
trigger [Char]
"Epicure of Blood"
Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
loseLife Int
1
let castWithMuldrotha :: [Char] -> [Char] -> [Char] -> GameMonad ()
castWithMuldrotha = \[Char]
ptype [Char]
mana [Char]
cn -> do
let ptypes :: Set [Char]
ptypes = [[Char]] -> Set [Char]
forall a. Ord a => [a] -> Set a
S.fromList [[Char]
"artifact", [Char]
"creature", [Char]
"land", [Char]
"enchantment"]
let counterName :: [Char]
counterName = [Char]
"muldrotha-" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
ptype
Bool -> GameMonad () -> GameMonad ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Set [Char] -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member [Char]
ptype Set [Char]
ptypes) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
[Char] -> GameMonad ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Invalid permanent type: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
ptype
Int
n <- Getting Int Board Int
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((HashMap [Char] Int -> Const Int (HashMap [Char] Int))
-> Board -> Const Int Board
Lens' Board (HashMap [Char] Int)
counters ((HashMap [Char] Int -> Const Int (HashMap [Char] Int))
-> Board -> Const Int Board)
-> ((Int -> Const Int Int)
-> HashMap [Char] Int -> Const Int (HashMap [Char] Int))
-> Getting Int Board 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)
counterName ((Maybe Int -> Const Int (Maybe Int))
-> HashMap [Char] Int -> Const Int (HashMap [Char] Int))
-> ((Int -> Const Int Int) -> Maybe Int -> Const Int (Maybe Int))
-> (Int -> Const Int Int)
-> HashMap [Char] Int
-> Const Int (HashMap [Char] 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)
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then
[Char] -> GameMonad ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError ([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Already cast card of type with Muldrotha: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
ptype
else
do
CardLocation -> [Char] -> [Char] -> GameMonad ()
castFromLocation (Player
Active, Location
Graveyard) [Char]
mana [Char]
cn
[Char] -> GameMonad ()
resolve [Char]
cn
ASetter Board Board (Maybe Int) (Maybe Int)
-> Maybe Int -> GameMonad ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
assign ((HashMap [Char] Int -> Identity (HashMap [Char] Int))
-> Board -> Identity Board
Lens' Board (HashMap [Char] Int)
counters ((HashMap [Char] Int -> Identity (HashMap [Char] Int))
-> Board -> Identity Board)
-> ((Maybe Int -> Identity (Maybe Int))
-> HashMap [Char] Int -> Identity (HashMap [Char] Int))
-> ASetter Board Board (Maybe Int) (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)
counterName) (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1)
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Initial state" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
setLife Int
7
CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
(Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
4, Int
4) [Char]
"Epicure of Blood"
(Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
6, Int
6) [Char]
"Muldrotha, the Gravetide"
Int -> [Char] -> GameMonad ()
addLands Int
3 [Char]
"Memorial to Folly"
Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Watery Grave"
Int -> [Char] -> GameMonad ()
addLands Int
4 [Char]
"Overgrown Tomb"
CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Graveyard) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
artifact (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
3) [Char]
"Diamond Mare"
[Char] -> GameMonad ()
addLand [Char]
"Detection Tower"
[Char] -> GameMonad ()
addArtifact [Char]
"Mox Amber"
[Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
black (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
2) [Char]
"Vicious Conquistador"
(Int, Int) -> [Char] -> GameMonad ()
addCreature (Int
1, Int
4) [Char]
"Sailor of Means"
CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Hand) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
black (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> GameMonad ()
addSorcery [Char]
"March of the Drowned"
[Char] -> GameMonad ()
addSorcery [Char]
"Gruesome Menagerie"
[Char] -> GameMonad ()
addAura [Char]
"Dead Weight"
[Char] -> GameMonad ()
addSorcery [Char]
"Find"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Detection Tower, Mox Amber, Diamond Mare from graveyard" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> [Char] -> GameMonad ()
castWithMuldrotha [Char]
"land" [Char]
"" [Char]
"Detection Tower"
[Char] -> [Char] -> [Char] -> GameMonad ()
castWithMuldrotha [Char]
"artifact" [Char]
"" [Char]
"Mox Amber"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"1" [Char]
"Detection Tower"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"1" [Char]
"Mox Amber"
[Char] -> [Char] -> [Char] -> GameMonad ()
castWithMuldrotha [Char]
"creature" [Char]
"2" [Char]
"Diamond Mare"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"March of the Drowned on Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Memorial to Folly 1"
([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]
"B") [Char]
"March of the Drowned"
[Char] -> GameMonad ()
resolve [Char]
"March of the Drowned"
Location -> [Char] -> GameMonad ()
moveTo Location
Hand [Char]
"Vicious Conquistador"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Memorial to Folly 2"
([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]
"B") [Char]
"Vicious Conquistador"
[Char] -> GameMonad ()
resolve [Char]
"Vicious Conquistador"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Dead Weight on Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Memorial to Folly 3"
([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]
"B") [Char]
"Dead Weight"
[Char] -> GameMonad ()
target [Char]
"Vicious Conquistador"
[Char] -> GameMonad ()
resolve [Char]
"Dead Weight"
(Int, Int) -> [Char] -> GameMonad ()
modifyStrength (-Int
2, -Int
2) [Char]
"Vicious Conquistador"
Location -> [Char] -> GameMonad ()
moveTo Location
Graveyard [Char]
"Dead Weight"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Gruesome Menagerie for Sailor of Means and Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Watery Grave 1"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Watery Grave 2"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Watery Grave 3"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Watery Grave 4"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Overgrown Tomb 1"
([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]
"3BB") [Char]
"Gruesome Menagerie"
[Char] -> GameMonad ()
resolve [Char]
"Gruesome Menagerie"
CardLocation -> [Char] -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) [Char]
"Vicious Conquistador"
CardLocation -> [Char] -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) [Char]
"Sailor of Means"
Location -> [Char] -> GameMonad ()
moveTo Location
Play [Char]
"Vicious Conquistador"
Location -> [Char] -> GameMonad ()
moveTo Location
Play [Char]
"Sailor of Means"
CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play)
(GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> GameMonad () -> GameMonad ()
withAttribute [Char]
token
(GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ [Char] -> GameMonad ()
addArtifact [Char]
"Treasure"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Dead Weight on Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Overgrown Tomb 2"
([Char] -> GameMonad ()) -> [Char] -> GameMonad ()
forall a.
([Char]
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) a)
-> [Char] -> GameMonad ()
withTriggers ([Char] -> [Char] -> [Char] -> GameMonad ()
castWithMuldrotha [Char]
"enchantment" [Char]
"B") [Char]
"Dead Weight"
[Char] -> GameMonad ()
target [Char]
"Vicious Conquistador"
(Int, Int) -> [Char] -> GameMonad ()
modifyStrength (-Int
2, -Int
2) [Char]
"Vicious Conquistador"
Location -> [Char] -> GameMonad ()
moveTo Location
Graveyard [Char]
"Dead Weight"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Find for Vicous Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Overgrown Tomb 3"
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Overgrown Tomb 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]
"BB") [Char]
"Find"
[Char] -> GameMonad ()
resolve [Char]
"Find"
CardLocation -> [Char] -> GameMonad ()
targetInLocation (Player
Active, Location
Graveyard) [Char]
"Vicious Conquistador"
Location -> [Char] -> GameMonad ()
moveTo Location
Hand [Char]
"Vicious Conquistador"
[Char] -> GameMonad () -> GameMonad ()
forall a. [Char] -> GameMonad a -> GameMonad a
step [Char]
"Vicious Conquistador" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
[Char] -> [Char] -> GameMonad ()
tapForMana [Char]
"B" [Char]
"Treasure"
[Char] -> GameMonad ()
sacrifice [Char]
"Treasure"
([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]
"B") [Char]
"Vicious Conquistador"
[Char] -> GameMonad ()
resolve [Char]
"Vicious Conquistador"
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]
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"mana" (ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countCards ([Char] -> CardMatcher
matchAttribute [Char]
"land" CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> [Char] -> CardMatcher
missingAttribute [Char]
"tapped")
[Char]
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a. Show a => [Char] -> GameMonad a -> FormatMonad ()
attribute [Char]
"life" (ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ())
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
-> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player
-> ExceptT
[Char] (ReaderT Env (StateT Board (WriterT [Step] Identity))) Int
countLife Player
Opponent