package net.demilich.metastone.gui.trainingmode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import net.demilich.metastone.GameNotification;
import net.demilich.metastone.game.behaviour.threat.FeatureVector;
import net.demilich.metastone.game.behaviour.threat.WeightedFeature;
import net.demilich.metastone.trainingmode.TrainingData;
import net.demilich.metastone.utils.ResourceInputStream;
import net.demilich.metastone.utils.ResourceLoader;
import net.demilich.metastone.utils.UserHomeMetastone;
import net.demilich.nittygrittymvc.Proxy;
public class TrainingProxy extends Proxy<GameNotification> {
public static final String NAME = "TrainingProxy";
private static final String TRAINING_FOLDER = "training";
private static final String TRAINING_FOLDER_PATH = UserHomeMetastone.getPath() + File.separator + TRAINING_FOLDER;
private static Logger logger = LoggerFactory.getLogger(TrainingProxy.class);
private final HashMap<String, FeatureVector> trainingData = new HashMap<String, FeatureVector>();
public TrainingProxy() {
super(NAME);
if (new File(TRAINING_FOLDER_PATH).mkdir()) {
logger.info(TRAINING_FOLDER_PATH + " folder created");
}
try {
loadTrainingData();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public TrainingData getTrainingData(String deckName) {
return trainingData.containsKey(deckName) ? new TrainingData(deckName, trainingData.get(deckName)) : null;
}
public void loadTrainingData() throws IOException, URISyntaxException {
trainingData.clear();
// load training from resources jar on the classpath
Collection<ResourceInputStream> inputStreams = ResourceLoader.loadJsonInputStreams(TRAINING_FOLDER, false);
// load cards from ~/metastone/training folder on the filesystem
if (Paths.get(TRAINING_FOLDER_PATH).toFile().exists()) {
inputStreams.addAll((ResourceLoader.loadJsonInputStreams(TRAINING_FOLDER_PATH, true)));
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
HashMap<String, Object> map;
Reader reader;
for (ResourceInputStream resourceInputStream : inputStreams) {
reader = new InputStreamReader(resourceInputStream.inputStream);
map = gson.fromJson(reader, new TypeToken<HashMap<String, Object>>() {}.getType());
final String DECK_NAME = "deck";
if (!map.containsKey(DECK_NAME)) {
logger.error("Training data {} does not specify a value for '{}' and is therefor not valid", resourceInputStream.fileName, DECK_NAME);
continue;
}
String deckName = (String) map.get(DECK_NAME);
map.remove(DECK_NAME);
FeatureVector featureVector = new FeatureVector();
for (String element : map.keySet()) {
try {
WeightedFeature feature = WeightedFeature.valueOf(element);
double value = (double) map.get(element);
featureVector.set(feature, value);
} catch (IllegalArgumentException ex) {
logger.warn("Illegal argument in training data: " + element + " Value: " + map.get(element));
}
}
trainingData.put(deckName, featureVector);
}
}
public void saveTrainingData(TrainingData trainingData) {
String deckName = trainingData.getDeckName();
FeatureVector featureVector = trainingData.getFeatureVector();
this.trainingData.put(deckName, featureVector);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
HashMap<String, Object> saveData = new HashMap<String, Object>();
saveData.put("deck", deckName);
for (WeightedFeature feature : featureVector.getValues().keySet()) {
double value = featureVector.get(feature);
saveData.put(feature.toString(), value);
}
String jsonData = gson.toJson(saveData);
try {
String filename = deckName.toLowerCase();
filename = filename.replaceAll(" ", "_");
filename = filename.replaceAll("\\W+", "");
filename = TRAINING_FOLDER_PATH + File.separator + filename + ".json";
Files.write(Paths.get(filename), jsonData.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}