Skip to content

Commit

Permalink
Support Dominions and Fortresses in the deck
Browse files Browse the repository at this point in the history
 For instance:
    deck "Nexor the Farseer, Depth Riser(3), Alpha Rebuked, CS, IA"
        vs
    deck "Daedalus Charged, Alpha Replicant, Loathe Abysswing(3), FF(2)"
        (expected that cardabbrs.txt file contains CS, IA, FF)
    -----------------------------------------------------------------------
    TURN 1 begins for P1 Commander [Daedalus Charged hp:82]
    P1 Structure 0 [Alpha Replicant hp:66 cd:4] reduces its timer
    P1 Structure 1 [Forcefield hp:35 cd:5] reduces its timer
    P1 Structure 2 [Forcefield hp:35 cd:5] reduces its timer
    P1 Commander [Daedalus Charged hp:82] plays Assault 0 [Loathe Abysswing: 1/20/0 vindi bloodthirsty, Strike all 2, Jam 2 every 6, Legion 6]
    ...
    ------------------------------------------------------------------------
    TURN 2 begins for P0 Commander [Nexor the Farseer hp:107]
    P0 Structure 0 [Alpha Rebuked hp:63 cd:4] reduces its timer
    P0 Structure 1 [Corrosive Spore hp:27 cd:4] reduces its timer
    P0 Structure 2 [Inspiring Altar hp:23 cd:4] reduces its timer
    P0 Commander [Nexor the Farseer hp:107] plays Assault 0 [Depth Riser: 10/62/3 legend xeno, Evade 7, Counter 15, Leech 18]
  • Loading branch information
dsuchka committed Nov 24, 2016
1 parent 84021f1 commit 1869775
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 26 deletions.
2 changes: 1 addition & 1 deletion SimpleTUOptimizeStarter.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Gui, Add, Edit, vSimOptions r1 xs w600, %IniSimOptions%
Gui, Add, Button, default r2 w100 x100 y+15 section, Simulate
Gui, Add, Checkbox, vx86 Checked%Inix86%, x86 (32-bit)
Gui, Add, Button, r2 w100 ys xs+200, Exit
Gui, Show,, Simple Tyrant Unleashed Optimize Starter v2.36.0
Gui, Show,, Simple Tyrant Unleashed Optimize Starter v2.37.0
return

ButtonSimulate:
Expand Down
2 changes: 2 additions & 0 deletions card.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Card
std::vector<SkillSpec> m_skills;
unsigned m_skill_value[Skill::num_skills];
CardType::CardType m_type;
CardCategory::CardCategory m_category;
const Card* m_top_level_card; // [TU] corresponding full-level card
unsigned m_recipe_cost;
std::map<const Card*, unsigned> m_recipe_cards;
Expand All @@ -43,6 +44,7 @@ class Card
m_set(0),
m_skills(),
m_type(CardType::assault),
m_category(CardCategory::normal),
m_top_level_card(this),
m_recipe_cost(0),
m_recipe_cards(),
Expand Down
22 changes: 16 additions & 6 deletions deck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ void Deck::set(const std::vector<unsigned>& ids, const std::map<signed, char> &m
for(auto id: ids)
{
const Card* card{all_cards.by_id(id)};
if(card->m_type == CardType::commander)
if (card->m_type == CardType::commander)
{
if (commander == nullptr)
{
Expand All @@ -243,6 +243,14 @@ void Deck::set(const std::vector<unsigned>& ids, const std::map<signed, char> &m
std::cerr << "WARNING: Ignoring additional commander " << card->m_name << " (" << commander->m_name << " already in deck)\n";
}
}
else if (card->m_category == CardCategory::dominion)
{
dominion_cards.emplace_back(card);
}
else if (card->m_category == CardCategory::fortress_defense || card->m_category == CardCategory::fortress_siege)
{
fortress_cards.emplace_back(card);
}
else
{
cards.emplace_back(card);
Expand Down Expand Up @@ -316,10 +324,10 @@ void Deck::set_given_hand(const std::string& deck_string)

void Deck::add_forts(const std::string& deck_string)
{
auto && id_marks = string_to_ids(all_cards, deck_string, "fort_cards");
auto && id_marks = string_to_ids(all_cards, deck_string, "fortress_cards");
for (auto id: id_marks.first)
{
fort_cards.push_back(all_cards.by_id(id));
fortress_cards.push_back(all_cards.by_id(id));
}
}

Expand Down Expand Up @@ -368,7 +376,7 @@ std::string Deck::medium_description() const
{
ios << "No commander";
}
for (const Card * card: fort_cards)
for (const Card * card: fortress_cards)
{
ios << ", " << card->m_name;
}
Expand Down Expand Up @@ -406,7 +414,7 @@ std::string Deck::long_description() const
{
ios << "No commander\n";
}
for (const Card * card: fort_cards)
for (const Card * card: fortress_cards)
{
show_upgrades(ios, card, card->m_top_level_card->m_level, "");
}
Expand Down Expand Up @@ -532,8 +540,10 @@ const Card* Deck::upgrade_card(const Card* card, unsigned card_max_level, std::m
void Deck::shuffle(std::mt19937& re)
{
shuffled_commander = commander;
shuffled_dominions.clear();
boost::insert(shuffled_dominions, shuffled_dominions.end(), dominion_cards);
shuffled_forts.clear();
boost::insert(shuffled_forts, shuffled_forts.end(), fort_cards);
boost::insert(shuffled_forts, shuffled_forts.end(), fortress_cards);
shuffled_cards.clear();
boost::insert(shuffled_cards, shuffled_cards.end(), cards);
if(!variable_cards.empty())
Expand Down
4 changes: 3 additions & 1 deletion deck.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Deck
std::map<signed, char> card_marks; // <positions of card, prefix mark>: -1 indicating the commander. E.g, used as a mark to be kept in attacking deck when optimizing.

const Card* shuffled_commander;
std::deque<const Card*> shuffled_dominions;
std::deque<const Card*> shuffled_forts;
std::deque<const Card*> shuffled_cards;

Expand All @@ -70,7 +71,8 @@ class Deck
std::unordered_set<unsigned> allowed_candidates;
std::unordered_set<unsigned> disallowed_candidates;
std::vector<unsigned> given_hand;
std::vector<const Card*> fort_cards;
std::vector<const Card*> dominion_cards;
std::vector<const Card*> fortress_cards;

Deck(
const Cards& all_cards_,
Expand Down
4 changes: 4 additions & 0 deletions sim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2182,6 +2182,10 @@ Results<uint64_t> play(Field* fd)
// Play fortresses
for (unsigned _ = 0; _ < 2; ++ _)
{
for (const Card* played_card: fd->tap->deck->shuffled_dominions)
{
PlayCard(played_card, fd).op<CardType::structure>();
}
for (const Card* played_card: fd->tap->deck->shuffled_forts)
{
PlayCard(played_card, fd).op<CardType::structure>();
Expand Down
13 changes: 12 additions & 1 deletion tyrant.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef TYRANT_H_INCLUDED
#define TYRANT_H_INCLUDED

#define TYRANT_OPTIMIZER_VERSION "2.36.0"
#define TYRANT_OPTIMIZER_VERSION "2.37.0"

#include <string>
#include <sstream>
Expand Down Expand Up @@ -249,6 +249,17 @@ enum CardType {
};
}

namespace CardCategory {
enum CardCategory {
normal,
special,
fortress_defense,
fortress_siege,
dominion,
num_cardcategories
};
}

extern const std::string cardtype_names[CardType::num_cardtypes];

extern const std::string rarity_names[];
Expand Down
101 changes: 84 additions & 17 deletions xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ void parse_card_node(Cards& all_cards, Card* card, xml_node<>* card_node)
xml_node<>* cost_node(card_node->first_node("cost"));
xml_node<>* rarity_node(card_node->first_node("rarity"));
xml_node<>* type_node(card_node->first_node("type"));
xml_node<>* fortress_type_node(card_node->first_node("fortress_type"));
xml_node<>* set_node(card_node->first_node("set"));
int set(set_node ? atoi(set_node->value()) : card->m_set);
xml_node<>* level_node(card_node->first_node("level"));
Expand All @@ -152,28 +153,94 @@ void parse_card_node(Cards& all_cards, Card* card, xml_node<>* card_node)
if (cost_node) { card->m_delay = atoi(cost_node->value()); }
if (id_node)
{
// [0 .. 999]
if (card->m_id < 1000)
{ card->m_type = CardType::assault; }
{
card->m_type = CardType::assault;
}

// [1000 .. 1999]
else if (card->m_id < 2000)
{ card->m_type = CardType::commander; }
{
card->m_type = CardType::commander;
}

// [2000 .. 2999]
else if (card->m_id < 3000)
{ card->m_type = CardType::structure; }
{
card->m_type = CardType::structure;

// fortress
if (card->m_id >= 2700 && card->m_id < 2997)
{
if (fortress_type_node) {
unsigned fort_type_value = atoi(fortress_type_node->value());
switch (fort_type_value) {
case 1:
card->m_category = CardCategory::fortress_defense;
break;
case 2:
card->m_category = CardCategory::fortress_siege;
break;
default:
std::cerr << "Warning: parsing card [" << card->m_id << "]: unsupported fortress_type=" << fort_type_value << std::endl;
}
}
else
{
std::cerr << "Warning: parsing card [" << card->m_id << "]: expected fortress_type node" << std::endl;
}
}
}

// [3000 ... 7999]
else if (card->m_id < 8000)
{ card->m_type = CardType::assault; }
{
card->m_type = CardType::assault;
}

// [8000 .. 9999]
else if (card->m_id < 10000)
{ card->m_type = CardType::structure; }
{
card->m_type = CardType::structure;
}

// [10000 .. 16999]
else if (card->m_id < 17000)
{ card->m_type = CardType::assault; }
{
card->m_type = CardType::assault;
}

// [17000 .. 24999]
else if (card->m_id < 25000)
{ card->m_type = CardType::structure; }
{
card->m_type = CardType::structure;
}

// [25000 .. 29999]
else if (card->m_id < 30000)
{ card->m_type = CardType::commander; }
{
card->m_type = CardType::commander;
}

// [30000 .. 50000]
else if (card->m_id < 50001)
{ card->m_type = CardType::assault; }
{
card->m_type = CardType::assault;
}

// [50001 .. 55000]
else if (card->m_id < 55001)
{ card->m_type = CardType::structure; }
{
card->m_type = CardType::structure;
card->m_category = CardCategory::dominion;
}

// [55001+]
else
{ card->m_type = CardType::assault; }
{
card->m_type = CardType::assault;
}
}
if(rarity_node) { card->m_rarity = atoi(rarity_node->value()); }
if(type_node) { card->m_faction = static_cast<Faction>(atoi(type_node->value())); }
Expand Down Expand Up @@ -276,13 +343,13 @@ Deck* read_deck(Decks& decks, const Cards& all_cards, xml_node<>* node, DeckType
xml_node<>* commander_max_level_node(node->first_node("commander_max_level"));
unsigned commander_max_level = commander_max_level_node ? atoi(commander_max_level_node->value()) : commander_card->m_top_level_card->m_level;
unsigned upgrade_opportunities = commander_max_level - card->m_level;
std::vector<const Card*> fort_cards;
std::vector<const Card*> fortress_cards;
for (xml_node<>* fortress_card_node = node->first_node("fortress_card");
fortress_card_node;
fortress_card_node = fortress_card_node->next_sibling("fortress_card"))
fortress_card_node = fortress_card_node->next_sibling("/fortress_card"))
{
const Card * card = all_cards.by_id(atoi(fortress_card_node->first_attribute("id")->value()));
fort_cards.push_back(card);
fortress_cards.push_back(card);
upgrade_opportunities += card->m_top_level_card->m_level - card->m_level;
}
std::vector<const Card*> always_cards;
Expand Down Expand Up @@ -331,22 +398,22 @@ Deck* read_deck(Decks& decks, const Cards& all_cards, xml_node<>* node, DeckType
decks.decks.push_back(Deck{all_cards, decktype, id, deck_name, (upgrade_opportunities + 1) * (level - 1) / (max_level - 1), upgrade_opportunities});
Deck* deck = &decks.decks.back();
deck->set(commander_card, commander_max_level, always_cards, some_cards, mission_req);
deck->fort_cards = fort_cards;
deck->fortress_cards = fortress_cards;
decks.add_deck(deck, deck_name);
decks.add_deck(deck, decktype_names[decktype] + " #" + to_string(id) + "-" + to_string(level));
}

decks.decks.push_back(Deck{all_cards, decktype, id, base_deck_name});
Deck* deck = &decks.decks.back();
deck->set(commander_card, commander_max_level, always_cards, some_cards, mission_req);
deck->fort_cards = fort_cards;
deck->fortress_cards = fortress_cards;

// upgrade cards for full-level missions/raids
if (max_level > 1)
{
while (deck->commander->m_level < commander_max_level)
{ deck->commander = deck->commander->upgraded(); }
for (auto && card: deck->fort_cards)
for (auto && card: deck->fortress_cards)
{ card = card->m_top_level_card; }
for (auto && card: deck->cards)
{ card = card->m_top_level_card; }
Expand Down

0 comments on commit 1869775

Please sign in to comment.