Skip to content
This repository has been archived by the owner on May 15, 2020. It is now read-only.

One dollar price limit #15

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 84 additions & 50 deletions src/main/java/setup/cardlists/MakeAllCardsList.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,46 @@
public class MakeAllCardsList {

//This code is meant to be run using some kind of scheduler.
private static boolean test = false;

public static void main(String[] args) throws Exception{
public static void main(String[] args) throws Exception {

final int TIMES_CHECKED = 168; //Hours in a week
//final int TIMES_CHECKED = 1; //For testing
final int TIMES_CHECKED = (test ? 1 : 168); // 168 hours per week

//Create a list of set abbreviations from the provided file, and check how many times the program has been run so far.
List<String> setAbbr;
List<String> setAbbr;

if (!new File("MTGO_Set_Abbreviations").exists())
{
setAbbr = FileConverter.readToList(MakeAllCardsList.class.getClassLoader().getResource("MTGO_Set_Abbreviations"));
}
else {
setAbbr = FileConverter.readToList("MTGO_Set_Abbreviations");
if (test) {
if (!new File("MTGO_Set_Abbreviations_test").exists())
{
setAbbr = FileConverter.readToList(MakeAllCardsList.class.getClassLoader().getResource("MTGO_Set_Abbreviations_test"));
}
else {
setAbbr = FileConverter.readToList("MTGO_Set_Abbreviations_test");
}
} else {
if (!new File("MTGO_Set_Abbreviations").exists())
{
setAbbr = FileConverter.readToList(MakeAllCardsList.class.getClassLoader().getResource("MTGO_Set_Abbreviations"));
}
else {
setAbbr = FileConverter.readToList("MTGO_Set_Abbreviations");
}
}
if (!new File("Count.txt").exists())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. If we're changing (or maybe "settling on") brace style then we should apply it throughout.

{

if (!new File("Count.txt").exists()) {
FileConverter.writeFile(0, "Count.txt");
}
int count = FileConverter.readToInt("Count.txt");

//Increase the count of how many times this program has been run, and update the text file to reflect that.
count++;

if (count < TIMES_CHECKED){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. This change makes sense but ideally would be in a separate commit for ease of review.

if (count <= TIMES_CHECKED) {
//In each valid run, get a snapshot of all legal cards and put it in a file
FileConverter.writeFile(getLegalSnapshot(setAbbr), "Run_"+String.format("%03d", count)+".txt");
} else if (count == TIMES_CHECKED) { //On the last run only, after all lists have been created:

FileConverter.writeFile(getLegalSnapshot(setAbbr), "Run_" + String.format("%03d", count) + ".txt");
}
if (count == TIMES_CHECKED) { //On the last run only, after all lists have been created:

//Makes a map of "card names -> # of times it was at 0.01 tix"
Map<String, Integer> timesLegalMap = new HashMap<>();
Expand All @@ -62,19 +71,27 @@ public static void main(String[] args) throws Exception{
legalCards.add(card);
}

//Add to an array all cards that were equal or below $1 50% or more of the time
List<String> dollarLegalCards = new ArrayList<>();
for (String card : timesLegalMap.keySet()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this differ from the check for 1c cards? It seems like it's doing the same thing?

if (timesLegalMap.get(card) >= TIMES_CHECKED / 2)
dollarLegalCards.add(card);
}

//Print the arrays out as usable, readable files
legalCards.retainAll(dollarLegalCards);
FileConverter.writeFile(legalCards, "legal_cards.txt");
System.out.println("File written!");
System.out.println("Starting Analysis...");
ChangeAnalyzer.main(new String[0]);

}
FileConverter.writeFile(count, "Count.txt");
}

//Updates the map with the snapshot passed to it.
private static void updateMap(List<String> snapshot, Map<String, Integer> map){
for (String card : snapshot){
private static void updateMap(List<String> snapshot, Map<String, Integer> map) {
for (String card : snapshot) {
map.merge(card, 1, (val, one) -> val + one);
}
}
Expand All @@ -84,19 +101,29 @@ private static Set<String> getLegalSnapshot(List<String> setCodes) throws Except
Set<String> legalCards = new HashSet<>();

//Cycle through the "set pages" for every set available on MTGO
for (String str : setCodes){
URL thisUrl = new URL("https://www.mtggoldfish.com/index/"+str+"#online");
for (String str : setCodes) {
URL mtgoUrl = new URL("https://www.mtggoldfish.com/index/" + str + "#online");
URL paperUrl = new URL("https://www.mtggoldfish.com/index/" + str + "#paper");

//Reads the webpage into an array of strings.
List<String> webpage = FileConverter.readToList(thisUrl);
List<String> mtgoWebpage = FileConverter.readToList(mtgoUrl);
List<String> paperWebpage = FileConverter.readToList(paperUrl);

Map<String, Double> cards = getCardNamesAndPrices(webpage);
Map<String, Double> mtgoCards = getCardNamesAndPrices(mtgoWebpage, "online");
Map<String, Double> paperCards = getCardNamesAndPrices(paperWebpage, "paper");

cards.entrySet().stream() //
mtgoCards.entrySet().stream() //
.filter(e -> e.getValue() == 0.01) //
.map(Map.Entry::getKey) //
.forEach(legalCards::add);

.forEach(legalCards::add);

Set<String> paperLegalCards = new HashSet<>();
paperCards.entrySet().stream() //
.filter(e -> e.getValue() <= 1) //
.map(Map.Entry::getKey) //
.forEach(paperLegalCards::add);
legalCards.retainAll(paperLegalCards);

System.out.println("Legal cards from "+str+" found!");
}

Expand All @@ -111,16 +138,16 @@ private static Set<String> getLegalSnapshot(List<String> setCodes) throws Except
return legalCards;
}

private static Map<String, Double> getCardNamesAndPrices(List<String> html) {
private static Map<String, Double> getCardNamesAndPrices(List<String> html, String markerStr) {
Map<String, Double> cards = new HashMap<>();
int linesSinceMarker = -1;
String lastCardFound = null;

for (String str : html){

for (String str : html) {
linesSinceMarker++;

if (str.length() > 17 && str.substring(0, 17).equals("<td class='card'>") && str.indexOf("#online\">") > -1){ //Looks for a marker line
String marker = "#" + markerStr + "\">";
if (str.length() > 17 && str.substring(0, 17).equals("<td class='card'>") && str.indexOf(marker) > -1) { //Looks for a marker line

//Get the locations of the second ">" and the third "<", the card's name is located between them
int secondClose = str.indexOf('>',str.indexOf('>')+1);
Expand All @@ -131,21 +158,28 @@ private static Map<String, Double> getCardNamesAndPrices(List<String> html) {
String cardname = formatEnglishName(thisCard).replace("&#39;", "'").replace("Lim-Dul","Lim-Dûl").replace("Jotun","Jötun");

//MTGGoldfish doesn't include the accent, but it should, so I add it.
switch (cardname){
case "Seance": cardname = "Séance";
break;
case "Dandan": cardname = "Dandân";
break;
case "Khabal Ghoul": cardname = "Khabál Ghoul";
break;
case "Junun Efreet": cardname = "Junún Efreet";
break;
case "Ghazban Ogre": cardname = "Ghazbán Ogre";
break;
case "Ifh-Biff Efreet": cardname = "Ifh-Bíff Efreet";
break;
case "Ring of Ma'ruf": cardname = "Ring of Ma'rûf";
break;
switch (cardname) {
case "Seance":
cardname = "Séance";
break;
case "Dandan":
cardname = "Dandân";
break;
case "Khabal Ghoul":
cardname = "Khabál Ghoul";
break;
case "Junun Efreet":
cardname = "Junún Efreet";
break;
case "Ghazban Ogre":
cardname = "Ghazbán Ogre";
break;
case "Ifh-Biff Efreet":
cardname = "Ifh-Bíff Efreet";
break;
case "Ring of Ma'ruf":
cardname = "Ring of Ma'rûf";
break;
}

// Retain knowledge of the last card we found
Expand All @@ -156,9 +190,9 @@ private static Map<String, Double> getCardNamesAndPrices(List<String> html) {
}

// If we've found a card, then the third line after the marker has the card price
if (lastCardFound != null && linesSinceMarker == 4){
if (lastCardFound != null && linesSinceMarker == 4) {
cards.put(lastCardFound, Double.parseDouble(str));

lastCardFound = null;
linesSinceMarker = -1;
}
Expand All @@ -167,13 +201,13 @@ private static Map<String, Double> getCardNamesAndPrices(List<String> html) {
return cards;
}

private static String formatEnglishName(String name){
private static String formatEnglishName(String name) {
String formatted = "";
for (int c = 0; c < name.length(); c++){
for (int c = 0; c < name.length(); c++) {
char letter = name.charAt(c);

//Some cards with multiple promo printings have (second promo) or something in parens, this gets rid of that so we don't get duplicates
if(letter == '('){
if (letter == '(') {
formatted = formatted.trim();
break;
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/MTGO_Set_Abbreviations_test
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RIX
XLN
HOU
AKH
AER
KLD