magic/CardParser.hs

163 lines
5.3 KiB
Haskell
Raw Normal View History

2012-03-03 02:15:06 +00:00
module CardParser where
import Magic
import Card
2012-03-06 07:30:12 +00:00
import qualified Mana as M
import qualified ManaParser as MP
2012-03-03 02:15:06 +00:00
import Text.ParserCombinators.Parsec
test_creature = unlines $ [ "AEther Adept"
2012-03-03 02:15:06 +00:00
, "1UU"
, "Creature -- Human Wizard"
, "2/2"
, "When AEther Adept enters the battlefield, return target creature to its owner's hand."
, "M11-C, M12-U"
]
test_enchantment = unlines $ [ "AEther Barrier"
, "2U"
, "Enchantment"
, "Whenever a player casts a creature spell, that player sacrifices a permanent unless he or she pays {1}."
, "NE-R"
]
test_scheme = unlines $ [ "A Display of My Dark Power"
, "Scheme"
, "When you set this scheme in motion, until your next turn, whenever a player taps a land for mana, that player adds one mana to his or her mana pool of any type that land produced."
, "ARC-C"
]
2012-03-06 07:30:12 +00:00
test_split = unlines $ [ "Assault // Battery"
, "R // 3G"
, "Sorcery // Sorcery"
, "Assault deals 2 damage to target creature or player. // Put a 3/3 green Elephant creature token onto the battlefield."
, "IN-U, TSP-S, HOP-U"
]
2012-03-05 20:04:37 +00:00
card_list :: Parser [Card]
2012-03-06 07:30:12 +00:00
card_list = do
let normal_card = do
card' <- card
return [card']
let split_card = do
split_name; eol
manyTill (name >> eol) $ try $ lookAhead (sets >> eol)
sets; eol
return []
let any_card = (try split_card) <|> normal_card
card_list <- sepEndBy any_card $ string "\n"
return $ concat card_list
2012-03-05 20:04:37 +00:00
2012-03-06 07:30:12 +00:00
split_c :: Parser Char
split_c = try $ do
c <- char '/'
notFollowedBy $ char '/'
return c
<|> noneOf "\n\r"
2012-03-05 20:04:37 +00:00
2012-03-06 07:30:12 +00:00
split_name :: Parser String
split_name = manyTill split_c $ string "//" >> many split_c
eol :: Parser String
eol = try (string "\r\n")
<|> try (string "\n\r")
<|> string "\n"
<|> string "\r"
<?> "end of line"
word :: Parser String
word = many $ noneOf "\n\r "
name :: Parser String
name = do
ws <- sepBy1 word $ char ' '
return $ unwords ws
card_types :: Parser [String]
card_types =
do try $ do
main <- manyTill (noneOf "\n\r") $ string " -- "
subtypes <- sepBy word $ char ' '
return (main:subtypes)
<|> do main <- name
return [main]
<?> "card types"
stat :: Parser Int
stat = do
let d = ['0'..'9'] ++ "\r\n /"
skipMany $ noneOf d
stat' <- sepEndBy digit (many $ noneOf d)
case stat' of
[] -> return 0
_ -> return (read stat' :: Int)
power :: Parser Int
power = stat <?> "power"
toughness :: Parser Int
toughness = stat <?> "toughness"
2012-03-03 02:15:06 +00:00
set :: Parser (String, Rarity)
set = do
2012-03-06 01:02:12 +00:00
set' <- many1 $ oneOf $ ['A'..'Z'] ++ ['0'..'9']
2012-03-03 02:15:06 +00:00
char '-'
rarity' <- oneOf "LCURMS"
case rarity' of
'L' -> return (set', Land)
'C' -> return (set', Common)
'U' -> return (set', Uncommon)
'R' -> return (set', Rare)
'M' -> return (set', Mythic)
'S' -> return (set', Special)
2012-03-06 07:30:12 +00:00
sets :: Parser [(String, Rarity)]
sets = sepBy set $ string ", "
card :: Parser Card
card = do
let cost = do
cost' <- MP.cost; eol
return cost'
let ability = do
ability' <- name; eol
return ability'
let abilities = do
manyTill ability $ try $ lookAhead (sets >> eol)
name' <- name; eol
cost' <- option (M.Cost [] [] []) $ try cost
card_type':card_subtypes' <- card_types; eol
case card_type' of
"Creature" -> do
power' <- power; char '/'; toughness' <- toughness; eol
abilities' <- abilities
sets' <- sets; eol
let rarity' = case sets' of [] -> Special
xs -> snd $ last xs
return $ Card { card_rarity = rarity'
, card_name = name'
, card_type = card_type'
, card_subtypes = card_subtypes'
, card_cost = cost'
, card_abilities = abilities'
, card_power = power'
, card_toughness = toughness'
}
_ -> do
abilities' <- abilities
sets' <- sets; eol
let rarity' = case sets' of [] -> Special
xs -> snd $ last xs
return $ Card { card_rarity = rarity'
, card_name = name'
, card_type = card_type'
, card_subtypes = card_subtypes'
, card_cost = cost'
, card_abilities = abilities'
, card_power = 0
, card_toughness = 0
}
<?> "magic card"