Now with file-based level grammar.
This commit is contained in:
@@ -1,12 +1,128 @@
|
||||
package dk.itu.mario.level.grammar;
|
||||
|
||||
import dk.itu.mario.level.LevelArchetype;
|
||||
import dk.itu.mario.level.LevelComponent;
|
||||
import dk.itu.mario.level.PlayerProfile;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dk.itu.mario.level.LevelComponent;
|
||||
|
||||
public class LevelGrammarFactory {
|
||||
public static LevelGrammar createGrammar(PlayerProfile playerProfile, LevelArchetype archetype) {
|
||||
public static LevelGrammar createGrammar(File grammarFile) throws FileNotFoundException, IOException {
|
||||
FileInputStream fis = new FileInputStream(grammarFile);
|
||||
LevelGrammar levelGrammar = new LevelGrammar();
|
||||
try {
|
||||
InputStreamReader reader = new InputStreamReader(fis);
|
||||
BufferedReader buf = new BufferedReader(reader);
|
||||
String line;
|
||||
while ((line = buf.readLine()) != null) {
|
||||
line = line.trim(); // trim off newline/whitespace
|
||||
if (line.length() == 0 || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
System.out.println("Read: " + line);
|
||||
//split on whitespace
|
||||
String[] fields;
|
||||
if (line.startsWith("VAR")) {
|
||||
fields = line.split("\\s");
|
||||
if ("=".equals(fields[2]) && fields.length == 4) {
|
||||
levelGrammar.addVariable(new Variable(fields[1],LevelComponent.TYPE.valueOf(fields[3])));
|
||||
} else {
|
||||
throw new RuntimeException("Invalid VAR syntax: " + line);
|
||||
}
|
||||
} else if (line.startsWith("RULE")) {
|
||||
fields = line.split("->");
|
||||
String ruleName = fields[0].split("\\s")[1];
|
||||
System.out.println("Rule name: " + ruleName);
|
||||
Variable lhs = levelGrammar.getVariable(ruleName);
|
||||
if (lhs == null) {
|
||||
throw new RuntimeException("LHS variable not found: " + ruleName);
|
||||
}
|
||||
Clause rhs = getClause(fields[1].trim(),levelGrammar);
|
||||
levelGrammar.addProductionRule(new ProductionRule(lhs,rhs));
|
||||
} else if (line.startsWith("START")) {
|
||||
fields = line.split("\\s");
|
||||
if ("=".equals(fields[1]) && fields.length == 3) {
|
||||
levelGrammar.setStart(fields[2]);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid START syntax: " + line);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unable to parse grammar file " + grammarFile.getName() + " due to invalid line: " + line);
|
||||
}
|
||||
}
|
||||
return levelGrammar;
|
||||
} finally {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static Clause getClause(String clause, LevelGrammar grammar) {
|
||||
if (!clause.contains("|") && !clause.contains("+")) {
|
||||
return grammar.getVariable(clause);
|
||||
}
|
||||
int lBraceIndex = clause.indexOf("{");
|
||||
boolean isOrClause = false;
|
||||
int rBraceIndex = 0;
|
||||
|
||||
double[] chances = {};
|
||||
|
||||
if (lBraceIndex != -1) {
|
||||
isOrClause = true;
|
||||
rBraceIndex = clause.indexOf("}");
|
||||
System.out.println("Read OR-clause probabilities from: " + lBraceIndex + " to " + rBraceIndex);
|
||||
String[] doubleFields = clause.substring(lBraceIndex+1,rBraceIndex).split(",");
|
||||
chances = new double[doubleFields.length];
|
||||
for (int i = 0; i < doubleFields.length; i++) {
|
||||
chances[i] = Double.valueOf(doubleFields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
String remainder = clause.substring(rBraceIndex);
|
||||
List<String> rhsClauseStrings = new ArrayList<String>();
|
||||
if (remainder.contains("(")) {
|
||||
int nextLeftIndex = -1;
|
||||
do {
|
||||
nextLeftIndex = remainder.indexOf("(", nextLeftIndex+1);
|
||||
if (nextLeftIndex != -1) {
|
||||
int nextRightIndex = remainder.indexOf(")", nextLeftIndex+1);
|
||||
if (nextRightIndex == -1) {
|
||||
throw new RuntimeException("Unmatched left '(' in clause");
|
||||
}
|
||||
rhsClauseStrings.add(remainder.substring(nextLeftIndex+1,nextRightIndex));
|
||||
nextLeftIndex = nextRightIndex;
|
||||
}
|
||||
} while (nextLeftIndex != -1);
|
||||
} else {
|
||||
isOrClause = remainder.contains("|");
|
||||
if (isOrClause) {
|
||||
for (String subclause : remainder.split("\\|")) {
|
||||
rhsClauseStrings.add(subclause.trim());
|
||||
}
|
||||
} else {
|
||||
for (String subclause : remainder.split("\\+")) {
|
||||
rhsClauseStrings.add(subclause.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Clause> rhsClauses = new ArrayList<Clause>();
|
||||
|
||||
for (String subclause : rhsClauseStrings) {
|
||||
rhsClauses.add(getClause(subclause,grammar));
|
||||
}
|
||||
|
||||
if (isOrClause) {
|
||||
return new OrClause(chances, rhsClauses);
|
||||
} else {
|
||||
return new AndClause(rhsClauses);
|
||||
}
|
||||
}
|
||||
public static LevelGrammar createGrammar() {
|
||||
LevelGrammar grammar = new LevelGrammar();
|
||||
|
||||
Variable v_START = new Variable("S", LevelComponent.TYPE.LEVEL);
|
||||
|
||||
Reference in New Issue
Block a user