Skip to content

Commit

Permalink
change deck message format, add support for bottled relics, card prev…
Browse files Browse the repository at this point in the history
…iew on other cards, optimize format

 - now the deck is represented as a list of indexes, and then each unique card is sent in a separate array

   - this allows for easy handling of card.cardsOnPreview even when it differs for unupgraded
     and upgraded versions

 - the exports now include information on whether a card is bottled

 - the order of properties in the card format has been changed in such a way to maximize the likelihood of
   having long substrings that are the same in many cards. Basically this specific order should result in
   shorter compressed messages than most other orders, based on prior probabilities of given values and also
   their relationships.
  • Loading branch information
avolny committed Apr 23, 2020
1 parent d2737ae commit f43e204
Showing 1 changed file with 144 additions and 35 deletions.
179 changes: 144 additions & 35 deletions src/main/java/str_exporter/DeckJSONBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -22,11 +21,15 @@ public class DeckJSONBuilder extends JSONMessageBuilder{
public static final Logger logger = LogManager.getLogger(TipsJSONBuilder.class.getName());

private ArrayList<String> keywords;
private ArrayList<String> cardsRepr;
private ArrayList<AbstractCard> cards;

public DeckJSONBuilder(String login, String secret, String version) {
super(login, secret, version, 4);

keywords = new ArrayList<>();
cardsRepr = new ArrayList<>();
cards = new ArrayList<>();

TEXT = CardCrawlGame.languagePack.getUIString("TipHelper").TEXT;
}
Expand All @@ -43,9 +46,15 @@ protected void buildMessage(StringBuilder sb) {
sb.append("\"c\":\"").append(character).append("\","); // character

keywords.clear();
cardsRepr.clear();
cards.clear();

// deck;;;cards;;;keywords
StringBuilder sb_message = new StringBuilder();
boolean nonempty = buildCards(sb_message);
sb_message.append(nonempty ? ";": ";;;"); // ;;; delimits cards from keywords
buildDeck(sb_message);
sb_message.append(";;;");
buildCards(sb_message);
sb_message.append(";;;");
buildKeywords(sb_message);

sb.append("\"k\":\""); // deck
Expand Down Expand Up @@ -94,69 +103,157 @@ private int getKeywordIndex(String keyword) {
}
}

private boolean buildCards(StringBuilder sb) {
//returns true if deck has 1 or more cards

private boolean buildDeck(StringBuilder sb) {
int size = 0;

if (CardCrawlGame.isInARun()) {
CardGroup deck = CardCrawlGame.dungeon.player.masterDeck;
for (int i = 0; i < deck.group.size(); i++) {
buildCard(sb, deck.group.get(i));
sb.append(";;");
sb.append(getCardIndex(deck.group.get(i)));
if (i < deck.group.size() - 1)
sb.append(',');
}

size = deck.group.size();
}

if (size == 0) {
sb.append('-');
}

return size > 0;
}

private void buildCards(StringBuilder sb) {
//returns true if deck has 1 or more cards

for (int i = 0; i < cards.size(); i++) {
buildCard(sb, cards.get(i));
if (i < cards.size() - 1)
sb.append(";;");
}

if (cards.isEmpty())
sb.append('-');
}

private int getCardIndex(AbstractCard card) {
String cardShortRepr = getShortCardRepr(card);

int index = cardsRepr.indexOf(cardShortRepr);

if (index >= 0)
return index;
else {
cards.add(card);
cardsRepr.add(cardShortRepr);
return cardsRepr.size() - 1;
}
}

private String getShortCardRepr(AbstractCard card) {
StringBuilder sb = new StringBuilder();

sb.append(sanitize(card.name));
sb.append(';');
sb.append(encodeCardColor(card));
sb.append(';');
sb.append(card.rawDescription);

return sb.toString();
}

private void buildCard(StringBuilder sb, AbstractCard card) {
String name = sanitize(card.name);
String desc = parseDescription(card);
int timesUpgraded = card.timesUpgraded;
int cost = card.cost;
// inTip == true when we're building a card that's supposed to appear in a card tip (e.g. a Shiv)

if (name.isEmpty())
name = "-";
String name = sanitizeEmpty(sanitize(card.name));
String desc = sanitizeEmpty(parseDescription(card));
String keywords = sanitizeEmpty(encodeKeywords(card));

if (desc.isEmpty())
desc = "-";
AbstractCard copy = card.makeStatEquivalentCopy();
copy.upgrade();
copy.displayUpgrades();
String upgradedDesc = sanitizeEmpty(parseDescription(copy));
String upgradedName = sanitizeEmpty(copy.name);
String upgradedKeywords = sanitizeEmpty(encodeKeywords(copy));

// if (timesUpgraded > 0) {
// name = colorizeString(name, "#g");
// }
int timesUpgraded = card.timesUpgraded;
int cost = card.cost;

// name ; type ; rarity ; color ; cost ; upgrades ; description ; img path ; keywords
if (!card.canUpgrade() && card.timesUpgraded > 0) {
// card is already upgraded and cannot be upgraded further
upgradedDesc = "_";
upgradedName = "_";
upgradedKeywords = "_";
} else if (!card.canUpgrade() && card.timesUpgraded == 0) {
// card cannot be upgraded at all, e.g. a Curse
upgradedName = "null";
upgradedDesc = "-";
upgradedKeywords = "-";
} else if (card.canUpgrade() && card.timesUpgraded == 0 && upgradedName.equals(name + '+')) {
// card is not upgraded and can be upgraded and uses the common + sign notation
upgradedName = "+";
} else if (upgradedKeywords.equals(keywords)) {
upgradedKeywords = "_";
}

// for a regular card:
// name ; bottleStatus ; cardToPreview ; cardToPreview upgraded ; nameUpgraded ; upgrades ; keyword upgraded ; descriptionUpgraded ; keywords ; cost ; type ; rarity ; color ; description

sb.append(name);
sb.append(";");
sb.append(encodeBottleStatus(card));
sb.append(';');
sb.append(encodeCardToPreview(card));
sb.append(';');
sb.append(encodeCardToPreview(copy));
sb.append(';');
sb.append(upgradedName);
sb.append(";");
sb.append(timesUpgraded);
sb.append(';');
sb.append(upgradedKeywords);
sb.append(';');
sb.append(upgradedDesc);
sb.append(';');
sb.append(keywords);
sb.append(';');
sb.append(cost);
sb.append(";");
sb.append(encodeCardType(card));
sb.append(";");
sb.append(encodeCardRarity(card));
sb.append(";");
sb.append(encodeCardColor(card));
sb.append(";");
sb.append(cost);
sb.append(";");
sb.append(timesUpgraded);
sb.append(';');
sb.append(desc);
sb.append(';');
}

if (card.keywords.size() == 0) {
sb.append('-');
} else {
Iterator<String> iter = card.keywords.iterator();
private String sanitizeEmpty(String s) {
return s.isEmpty() ? "-" : s;
}

while(iter.hasNext()) {
sb.append(getKeywordIndex(iter.next()));
private String encodeCardToPreview(AbstractCard card) {
if (card.cardsToPreview != null) {
return Integer.toString(getCardIndex(card.cardsToPreview));
} else {
return "-1";
}
}

if (iter.hasNext())
sb.append(',');
}
private String encodeKeywords(AbstractCard card) {
StringBuilder sb = new StringBuilder();

Iterator<String> iter = card.keywords.iterator();

while(iter.hasNext()) {
sb.append(getKeywordIndex(iter.next()));

if (iter.hasNext())
sb.append(',');
}

return sb.toString();
}

private String encodeCardType(AbstractCard card) {
Expand All @@ -174,6 +271,18 @@ private String encodeCardColor(AbstractCard card) {
return ord > 5 ? card.color.toString() : Integer.toString(ord);
}

private String encodeBottleStatus(AbstractCard card) {
if (card.inBottleFlame) {
return "1";
} else if (card.inBottleLightning) {
return "2";
} else if (card.inBottleTornado) {
return "3";
} else {
return "0";
}
}

private String sanitize(String s) {
return s.replaceAll(";", ":")
.replaceAll("\"", "\\\"")
Expand Down Expand Up @@ -204,7 +313,7 @@ private String parseDescription(AbstractCard card) {
sb.append(line.text);

if(i < card.description.size() - 1)
sb.append(" ");
sb.append(" NL ");
}

String[] parts = sb.toString().split(" ");
Expand Down

0 comments on commit f43e204

Please sign in to comment.