package dk.itu.mario.level.grammar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; import java.util.TreeSet; import dk.itu.mario.level.LevelComponent; import dk.itu.mario.level.LevelComponent.TYPE; public class LevelGrammar { private Variable start; private Map ruleMap = new HashMap(); private Set variables = new TreeSet(); public void addVariable(Variable var) { if (variables.contains(var)) { throw new IllegalArgumentException( "Grammar already contains variable: " + var); } variables.add(var); } public void addProductionRule(ProductionRule rule) { if (ruleMap.containsKey(rule.getLHS())) { throw new IllegalArgumentException( "Grammar already contains rule with LHS: " + rule.getLHS()); } ruleMap.put(rule.getLHS(), rule); } public LevelParseTree generateRandomTree(long randomSeed, int width) { System.out.println("Generating random level parameters using seed: " + randomSeed); Variable startRuleLHS = getStart(); ParseNode rootNode = new ParseNode(startRuleLHS.getType(), 1.0); generateRecursive(rootNode, getRule(startRuleLHS).getRHS(), 1.0); LevelParseTree parseTree = new LevelParseTree(rootNode, 0, width); return parseTree; } private ParseNode generateRecursive(ParseNode parseNode, Clause clause, double relativeWidth) { if (clause.isVariable()) { if (clause.isTerminal()) { parseNode.addChild(new ParseNode(((Variable) clause).getType(), relativeWidth)); } else { generateRecursive(parseNode, getRule((Variable) clause) .getRHS(), relativeWidth); } } else { if (clause.isChoice()) { generateRecursive(parseNode, clause.makeRandomChoice(), relativeWidth); } else { int numSubClauses = clause.getNumSubClauses(); for (int i = 0; i < numSubClauses; i++) { generateRecursive(parseNode, clause.getSubClause(i), relativeWidth / numSubClauses); } } } return parseNode; } public Variable getVariable(String varName) { for (Variable var : variables) { if (varName.equals(var.getValue())) { return var; } } return null; } public ProductionRule getRule(Variable var) { return ruleMap.get(var); } public Variable getStart() { return start; } public void setStart(String startVar) { for (Variable var : variables) { if (startVar.equals(var.getValue())) { start = var; return; } } } public void setStart(Variable start) { this.start = start; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Variables:\n"); for (Variable var : variables) { sb.append("VAR "); sb.append(var.getValue()); sb.append(" = "); sb.append(var.getType()); sb.append("\n"); } sb.append("\n"); for (Entry entry : ruleMap.entrySet()) { //could as easily have used LHS instead of getKey().getValue() sb.append("RULE " + entry.getKey().getValue() + " -> " + entry.getValue().getRHS()); sb.append("\n"); } sb.append("\n"); sb.append("START = " + start.getValue()); return sb.toString(); } }