From 14c2b6e9b00575cefca13717dd48f34af46a1e19 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 22 Mar 2023 09:35:36 +0100 Subject: [PATCH] Update formats (#14) * Add missing docstring section to `Deck::singleton` * Add `Deck::unlimited_champions` * Fix typo in `Deck::singleton` docstring * Rename *Standard* to *Eternal* * Allow displaying *Unlimited Champions* * Add more legality tests --- src/data/deckcode/deck.rs | 72 +++++++++++++++++++++++++++++++-------- src/discord/handler.rs | 6 ++-- src/telegram/display.rs | 7 ++-- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/data/deckcode/deck.rs b/src/data/deckcode/deck.rs index 8b17946..bb6da9e 100644 --- a/src/data/deckcode/deck.rs +++ b/src/data/deckcode/deck.rs @@ -440,7 +440,7 @@ impl Deck { /// Get the number of cards in the deck. /// - /// In the *Standard* and *Singleton* formats, this is never more than 40. + /// In the *Eternal* and *Singleton* formats, this is never more than 40. /// /// # Example /// @@ -460,7 +460,7 @@ impl Deck { /// Get the number of champion cards in the deck. /// - /// In the *Standard* and *Singleton* format, this is never more than 6. + /// In the *Eternal* and *Singleton* format, this is never more than 6. /// /// # Example /// @@ -544,13 +544,13 @@ impl Deck { } } - /// Check if the [`Deck`] is legal for play in the *Standard* format. + /// Check if the [`Deck`] is legal for play in the *Eternal* format. /// /// # Returns /// - /// - `None` if the deck is not legal for *Standard* play. - /// - `Some(regions)` if the deck is legal for *Standard* play considering the specified region set. - pub fn standard(&self, cards: &CardIndex) -> Option> { + /// - `None` if the deck is not legal for *Eternal* play. + /// - `Some(regions)` if the deck is legal for *Eternal* play considering the specified region set. + pub fn eternal(&self, cards: &CardIndex) -> Option> { let copies_limit = self.contents.values().all(|n| n <= &3); let cards_limit = self.card_count() == 40; let champions_limit = self.champions_count(cards) <= 6; @@ -563,6 +563,11 @@ impl Deck { } /// Check if the [`Deck`] is legal for play in the *Singleton* format. + /// + /// # Returns + /// + /// - `None` if the deck is not legal for *Singleton* play. + /// - `Some(regions)` if the deck is legal for *Singleton* play considering the specified region set. pub fn singleton(&self, cards: &CardIndex) -> Option> { let copies_limit = self.contents.values().all(|n| n <= &1); let cards_limit = self.card_count() == 40; @@ -574,6 +579,23 @@ impl Deck { true => regions, } } + + /// Check if the [`Deck`] is legal to play in the *Unlimited Champions* format. + /// + /// # Returns + /// + /// - `None` if the deck is not legal for *Unlimited Champions* play. + /// - `Some(regions)` if the deck is legal for *Unlimited Champions* play considering the specified region set. + pub fn unlimited_champions(&self, cards: &CardIndex) -> Option> { + let copies_limit = self.contents.values().all(|n| n <= &3); + let cards_limit = self.card_count() == 40; + let regions = self.regions(cards, 2); + + match copies_limit && cards_limit { + false => None, + true => regions, + } + } } /// An error occoured while decoding a [`Deck`] from a code. @@ -855,24 +877,24 @@ mod tests { } test_legality!( - test_legality_standard_lonelyporo1, + test_legality_eternal_lonelyporo1, deck!("CEAAAAIBAEAQQ"), - Deck::standard, false + Deck::eternal, false ); test_legality!( - test_legality_standard_twistedshrimp, + test_legality_eternal_twistedshrimp, deck!("CICACBAFAEBAGBQICABQCBJLF4YQOAQGAQEQYEQUDITAAAIBAMCQO"), - Deck::standard, true + Deck::eternal, true ); test_legality!( - test_legality_standard_poros, + test_legality_eternal_poros, deck!("CQDQCAQBAMAQGAICAECACDYCAECBIFYCAMCBEEYCAUFIYANAAEBQCAIICA2QCAQBAEVTSAA"), - Deck::standard, true + Deck::eternal, true ); test_legality!( - test_legality_standard_sand, + test_legality_eternal_sand, deck!("CMBAGBAHANTXEBQBAUCAOFJGFIYQEAIBAUOQIBAHGM5HM6ICAECAOOYCAECRSGY"), - Deck::standard, true + Deck::eternal, true ); test_legality!( @@ -900,4 +922,26 @@ mod tests { deck!("CQAAADABAICACAIFBLAACAIFAEHQCBQBEQBAGBADAQBAIAIKBUBAKBAWDUBQIBACA4GAMAIBAMCAYHJBGADAMBAOCQKRMKBLA4AQIAQ3D4QSIKZYBACAODJ3JRIW3AABQIAYUAI"), Deck::singleton, true ); + + // From https://lor.cardsrealm.com/en-us/articles/new-game-modes-in-lor-unlimited-and-free-decks-to-discover + test_legality!( + test_legality_unlchamp_gwenkataelise, + deck!("CUCACAIDFIAQEAYJAMDAKDAQBYCACBJVCYUDCAQCAEBRGOAEAYCSMHANEAAQCAIDFY"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_norraveigarsenna, + deck!("CUCQCBIFBEAQMBIUAIAQKKABAMDAUDYVCECAKCS5MIY2MAICAECQVGABAECQKCADAECQVVIBAECQKCQBAYFBO"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_poros, + deck!("CQDQCAQBAMAQGAICAECACDYCAECBIFYCAMCBEEYCAUFIYANAAEBQCAIICA2QCAQBAEVTSAA"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_paltri, + deck!("CQAAADABAICACAIFBLAACAIFAEHQCBQBEQBAGBADAQBAIAIKBUBAKBAWDUBQIBACA4GAMAIBAMCAYHJBGADAMBAOCQKRMKBLA4AQIAQ3D4QSIKZYBACAODJ3JRIW3AABQIAYUAI"), + Deck::unlimited_champions, false + ); } diff --git a/src/discord/handler.rs b/src/discord/handler.rs index 01d41a0..ccdb718 100644 --- a/src/discord/handler.rs +++ b/src/discord/handler.rs @@ -226,8 +226,10 @@ impl EventHandler { None => format!("```text\n{}\n```", deck.to_code(DeckCodeFormat::F1).expect("to be able to serialize the deck code")), }); - let (format, regions) = if let Some(regions) = deck.standard(&engine.cards) { - ("<:neutral:1056022926660481094> Standard", regions) + let (format, regions) = if let Some(regions) = deck.eternal(&engine.cards) { + ("<:neutral:1056022926660481094> Eternal", regions) + } else if let Some(regions) = deck.unlimited_champions(&engine.cards) { + ("<:neutral:1056022926660481094> Unlimited Champions", regions) } else if let Some(regions) = deck.singleton(&engine.cards) { ("<:neutral:1056022926660481094> Singleton", regions) } else { diff --git a/src/telegram/display.rs b/src/telegram/display.rs index f8d7752..a5dde0d 100644 --- a/src/telegram/display.rs +++ b/src/telegram/display.rs @@ -204,8 +204,11 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: &str, name: &Option<&s let mut tags: Vec<&'static str> = vec![]; - let regions = if let Some(regions) = deck.standard(index) { - tags.push("#Standard"); + let regions = if let Some(regions) = deck.eternal(index) { + tags.push("#Eternal"); + regions + } else if let Some(regions) = deck.unlimited_champions(index) { + tags.push("#UnlimitedChampions"); regions } else if let Some(regions) = deck.singleton(index) { tags.push("#Singleton");