Merge branch 'master' of woodyfolsom.net:/opt/git/cs8803p3
Conflicts: src/dk/itu/mario/level/PCGLevel.java
This commit is contained in:
@@ -2,7 +2,7 @@ package dk.itu.mario.level;
|
|||||||
|
|
||||||
public class LevelComponent {
|
public class LevelComponent {
|
||||||
public enum TYPE {
|
public enum TYPE {
|
||||||
FLAT, PIPE_JUMP, PLATFORM_JUMP, MAZE
|
FLAT_HI, FLAT_LO, HI_LO, HI_PATH, LEVEL_SEGMENT, LEVEL, LO_HI, LO_PATH, PIPE_JUMP, PLATFORM_JUMP, MAZE
|
||||||
};
|
};
|
||||||
|
|
||||||
public enum MazeLevel {
|
public enum MazeLevel {
|
||||||
|
|||||||
@@ -182,9 +182,9 @@ public class PCGLevel extends Level {
|
|||||||
LevelComponent.TYPE lctype = lcomp.getType();
|
LevelComponent.TYPE lctype = lcomp.getType();
|
||||||
System.out.println("Building for: " + lcomp);
|
System.out.println("Building for: " + lcomp);
|
||||||
switch (lctype) {
|
switch (lctype) {
|
||||||
case FLAT:
|
case FLAT_LO:
|
||||||
length += buildStraight(length, lcomp.getEnd(),
|
case FLAT_HI:
|
||||||
random.nextBoolean());
|
length += buildStraight(length, lcomp.getEnd(), true);
|
||||||
break;
|
break;
|
||||||
case PIPE_JUMP:
|
case PIPE_JUMP:
|
||||||
length += buildPipeJump(length, width - 64 - length);
|
length += buildPipeJump(length, width - 64 - length);
|
||||||
|
|||||||
44
src/dk/itu/mario/level/grammar/AndClause.java
Normal file
44
src/dk/itu/mario/level/grammar/AndClause.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AndClause implements Clause {
|
||||||
|
List<Clause> subClauses = new ArrayList<Clause>();
|
||||||
|
|
||||||
|
public AndClause(Clause... subClauses) {
|
||||||
|
for (Clause clause : subClauses) {
|
||||||
|
this.subClauses.add(clause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clause makeRandomChoice() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumSubClauses() {
|
||||||
|
return subClauses.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clause getSubClause(int index) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return subClauses.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChoice() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isTerminal() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isVariable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/dk/itu/mario/level/grammar/Clause.java
Normal file
10
src/dk/itu/mario/level/grammar/Clause.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
|
public interface Clause {
|
||||||
|
public Clause getSubClause(int index);
|
||||||
|
public int getNumSubClauses();
|
||||||
|
public boolean isChoice();
|
||||||
|
public boolean isTerminal();
|
||||||
|
public boolean isVariable();
|
||||||
|
public Clause makeRandomChoice();
|
||||||
|
}
|
||||||
@@ -7,9 +7,9 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import dk.itu.mario.level.LevelComponent;
|
||||||
import dk.itu.mario.level.LevelComponent.TYPE;
|
import dk.itu.mario.level.LevelComponent.TYPE;
|
||||||
|
|
||||||
|
|
||||||
public class LevelGrammar {
|
public class LevelGrammar {
|
||||||
private Variable start;
|
private Variable start;
|
||||||
private Map<Variable, ProductionRule> ruleMap = new HashMap<Variable, ProductionRule>();
|
private Map<Variable, ProductionRule> ruleMap = new HashMap<Variable, ProductionRule>();
|
||||||
@@ -31,38 +31,41 @@ public class LevelGrammar {
|
|||||||
ruleMap.put(rule.getLHS(), rule);
|
ruleMap.put(rule.getLHS(), rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateRandom(long randomSeed) {
|
|
||||||
System.out.println("Generating random level parameters using seed: "
|
|
||||||
+ randomSeed);
|
|
||||||
List<Variable> startRuleRHS = getRule(getStart()).getRHS();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (Variable var : startRuleRHS) {
|
|
||||||
sb.append(var.toString());
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateRandom() {
|
|
||||||
System.out.println("Creating new random seed for LevelGrammar");
|
|
||||||
return generateRandom(new Random().nextLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: refactor to recursively add children to the current node based on production rule
|
|
||||||
public LevelParseTree generateRandomTree(long randomSeed, int width) {
|
public LevelParseTree generateRandomTree(long randomSeed, int width) {
|
||||||
System.out.println("Generating random level parameters using seed: "
|
System.out.println("Generating random level parameters using seed: "
|
||||||
+ randomSeed);
|
+ randomSeed);
|
||||||
List<Variable> startRuleRHS = getRule(getStart()).getRHS();
|
Variable startRuleLHS = getStart();
|
||||||
|
|
||||||
ParseNode rootNode = new ParseNode(TYPE.FLAT,1.0);
|
ParseNode rootNode = new ParseNode(startRuleLHS.getType(), 1.0);
|
||||||
|
generateRecursive(rootNode, getRule(startRuleLHS).getRHS(), 1.0);
|
||||||
LevelParseTree parseTree = new LevelParseTree(rootNode, 0, width);
|
LevelParseTree parseTree = new LevelParseTree(rootNode, 0, width);
|
||||||
|
|
||||||
for (Variable var : startRuleRHS) {
|
return parseTree;
|
||||||
if (var.isTerminal()) {
|
}
|
||||||
rootNode.addChild(new ParseNode(TYPE.FLAT,0.5));
|
|
||||||
|
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;
|
||||||
return parseTree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductionRule getRule(Variable var) {
|
public ProductionRule getRule(Variable var) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dk.itu.mario.level.grammar;
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
import dk.itu.mario.level.LevelArchetype;
|
import dk.itu.mario.level.LevelArchetype;
|
||||||
|
import dk.itu.mario.level.LevelComponent;
|
||||||
import dk.itu.mario.level.PlayerProfile;
|
import dk.itu.mario.level.PlayerProfile;
|
||||||
|
|
||||||
|
|
||||||
@@ -8,16 +9,61 @@ public class LevelGrammarFactory {
|
|||||||
public static LevelGrammar createGrammar(PlayerProfile playerProfile, LevelArchetype archetype) {
|
public static LevelGrammar createGrammar(PlayerProfile playerProfile, LevelArchetype archetype) {
|
||||||
LevelGrammar grammar = new LevelGrammar();
|
LevelGrammar grammar = new LevelGrammar();
|
||||||
|
|
||||||
Variable v_S = new Variable("S");
|
Variable v_START = new Variable("S", LevelComponent.TYPE.LEVEL);
|
||||||
Variable v_level_start = new Variable("level_start");
|
Variable v_LAND_SEGMENT = new Variable("HALF_LVL", LevelComponent.TYPE.LEVEL_SEGMENT);
|
||||||
Variable v_level_end = new Variable("level_end");
|
Variable v_LO_HI = new Variable("LO_HI", LevelComponent.TYPE.LO_HI);
|
||||||
|
Variable v_HI_LO = new Variable("HI_LO", LevelComponent.TYPE.HI_LO);
|
||||||
|
Variable v_LO_PATH = new Variable("LO_PATH", LevelComponent.TYPE.LO_PATH);
|
||||||
|
Variable v_HI_PATH = new Variable("HI_PATH", LevelComponent.TYPE.HI_PATH);
|
||||||
|
Variable v_lo_path = new Variable("lo_path", LevelComponent.TYPE.LO_PATH);
|
||||||
|
Variable v_hi_path = new Variable("hi_path", LevelComponent.TYPE.HI_PATH);
|
||||||
|
|
||||||
grammar.addVariable(v_S);
|
grammar.addVariable(v_START);
|
||||||
grammar.addVariable(v_level_start);
|
grammar.addVariable(v_LAND_SEGMENT);
|
||||||
grammar.addVariable(v_level_end);
|
grammar.addVariable(v_LO_HI);
|
||||||
|
grammar.addVariable(v_HI_LO);
|
||||||
|
grammar.addVariable(v_LO_PATH);
|
||||||
|
grammar.addVariable(v_HI_PATH);
|
||||||
|
|
||||||
grammar.addProductionRule(new ProductionRule(v_S,v_level_start,v_level_end));
|
grammar.addProductionRule(new ProductionRule(v_START,v_LAND_SEGMENT,v_LAND_SEGMENT));
|
||||||
grammar.setStart(v_S);
|
|
||||||
|
grammar.addProductionRule(
|
||||||
|
new ProductionRule(v_LAND_SEGMENT,
|
||||||
|
new OrClause( new double[] {0.25,0.65,0.10},
|
||||||
|
new AndClause(v_LO_HI,v_HI_LO),
|
||||||
|
v_LO_PATH,
|
||||||
|
new AndClause(v_LAND_SEGMENT,v_LAND_SEGMENT)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
grammar.addProductionRule(
|
||||||
|
new ProductionRule(v_LO_HI, v_LO_PATH, v_HI_PATH)
|
||||||
|
);
|
||||||
|
|
||||||
|
grammar.addProductionRule(
|
||||||
|
new ProductionRule(v_HI_LO, v_HI_PATH, v_LO_PATH)
|
||||||
|
);
|
||||||
|
|
||||||
|
grammar.addProductionRule(
|
||||||
|
new ProductionRule(v_HI_PATH,
|
||||||
|
new OrClause( new double[] {0.25,0.75},
|
||||||
|
new AndClause(v_HI_PATH,v_HI_PATH),
|
||||||
|
v_hi_path
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
grammar.addProductionRule(
|
||||||
|
new ProductionRule(v_LO_PATH,
|
||||||
|
new OrClause( new double[] {0.25,0.75},
|
||||||
|
new AndClause(v_LO_PATH,v_LO_PATH),
|
||||||
|
v_lo_path
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
grammar.setStart(v_START);
|
||||||
|
|
||||||
return grammar;
|
return grammar;
|
||||||
}
|
}
|
||||||
|
|||||||
59
src/dk/itu/mario/level/grammar/OrClause.java
Normal file
59
src/dk/itu/mario/level/grammar/OrClause.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OrClause implements Clause {
|
||||||
|
private double[] chances;
|
||||||
|
private List<Clause> subClauses = new ArrayList<Clause>();
|
||||||
|
|
||||||
|
public OrClause(double[] chances, Clause... subClauses) {
|
||||||
|
this.chances = chances;
|
||||||
|
double chanceTotal = 0.0;
|
||||||
|
for (double chance : chances) {
|
||||||
|
chanceTotal += chance;
|
||||||
|
}
|
||||||
|
if (Math.abs(chanceTotal - 1.0) > 0.01) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Total or-clause chances must sum to 1.0.");
|
||||||
|
}
|
||||||
|
for (Clause clause : subClauses) {
|
||||||
|
this.subClauses.add(clause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChoice() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTerminal() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Clause makeRandomChoice() {
|
||||||
|
double rand = Math.random();
|
||||||
|
for (int i = 0; i < chances.length; i++) {
|
||||||
|
if (rand < chances[i]) {
|
||||||
|
return subClauses.get(i);
|
||||||
|
}
|
||||||
|
rand -= chances[i];
|
||||||
|
}
|
||||||
|
return subClauses.get(chances.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumSubClauses() {
|
||||||
|
return subClauses.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clause getSubClause(int index) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVariable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
package dk.itu.mario.level.grammar;
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class ProductionRule {
|
public class ProductionRule {
|
||||||
private Variable lhs;
|
private Variable lhs;
|
||||||
private List<Variable> rhs;
|
private Clause rhs;
|
||||||
|
|
||||||
public ProductionRule(Variable lhs, Variable... rhs) {
|
public ProductionRule(Variable lhs, Clause... rhs) {
|
||||||
this.lhs = lhs;
|
this.lhs = lhs;
|
||||||
this.rhs = new ArrayList<Variable>();
|
if (rhs.length == 1) {
|
||||||
for (Variable var : rhs) {
|
this.rhs = rhs[0];
|
||||||
this.rhs.add(var);
|
} else {
|
||||||
|
this.rhs = new AndClause(rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +17,7 @@ public class ProductionRule {
|
|||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Variable> getRHS() {
|
public Clause getRHS() {
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
package dk.itu.mario.level.grammar;
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
public class Variable implements Comparable<Variable> {
|
import dk.itu.mario.level.LevelComponent;
|
||||||
|
|
||||||
|
public class Variable implements Clause, Comparable<Variable> {
|
||||||
private boolean terminal;
|
private boolean terminal;
|
||||||
|
private LevelComponent.TYPE type;
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public Variable(String value) {
|
public Variable(String value, LevelComponent.TYPE type) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.terminal = (value.toLowerCase().equals(value));
|
this.terminal = (value.toLowerCase().equals(value));
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LevelComponent.TYPE getType() {
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTerminal() {
|
public boolean isTerminal() {
|
||||||
@@ -23,5 +31,28 @@ public class Variable implements Comparable<Variable> {
|
|||||||
return this.value.compareTo(o.value);
|
return this.value.compareTo(o.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clause getSubClause(int index) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumSubClauses() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChoice() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clause makeRandomChoice() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVariable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user