Implemented stub functionality for determining player Profile, level Archetype and generating Level Components using a simple grammar.
See new method calls in MyNewLevel for an example of this level creation pipeline.
This commit is contained in:
@@ -8,6 +8,13 @@ import dk.itu.mario.MarioInterface.LevelInterface;
|
|||||||
import dk.itu.mario.engine.DataRecorder;
|
import dk.itu.mario.engine.DataRecorder;
|
||||||
import dk.itu.mario.engine.sprites.Enemy;
|
import dk.itu.mario.engine.sprites.Enemy;
|
||||||
import dk.itu.mario.engine.sprites.SpriteTemplate;
|
import dk.itu.mario.engine.sprites.SpriteTemplate;
|
||||||
|
import dk.itu.mario.level.generator.ArchetypeMatcher;
|
||||||
|
import dk.itu.mario.level.generator.GrammarTuner;
|
||||||
|
import dk.itu.mario.level.generator.LevelArchetype;
|
||||||
|
import dk.itu.mario.level.generator.LevelGrammar;
|
||||||
|
import dk.itu.mario.level.generator.LevelGrammarFactory;
|
||||||
|
import dk.itu.mario.level.generator.PlayerProfile;
|
||||||
|
import dk.itu.mario.level.generator.ProfileMatcher;
|
||||||
|
|
||||||
public class MyNewLevel extends Level {
|
public class MyNewLevel extends Level {
|
||||||
public enum MazeLevel {
|
public enum MazeLevel {
|
||||||
@@ -51,6 +58,20 @@ public class MyNewLevel extends Level {
|
|||||||
System.out.println("Generating level based on previous GamePlay AND DataRecorder metrics.");
|
System.out.println("Generating level based on previous GamePlay AND DataRecorder metrics.");
|
||||||
this.dataRecorder = dataRecorder;
|
this.dataRecorder = dataRecorder;
|
||||||
|
|
||||||
|
PlayerProfile profile = ProfileMatcher.getMatchingProfile(playerMetrics, dataRecorder);
|
||||||
|
System.out.println("PlayerProfile: " + profile);
|
||||||
|
|
||||||
|
LevelArchetype archetype = ArchetypeMatcher.getMatchingArchetype(playerMetrics, dataRecorder);
|
||||||
|
System.out.println("LevelArchetype: " + archetype);
|
||||||
|
|
||||||
|
System.out.println("Creating level grammar");
|
||||||
|
LevelGrammar grammar = LevelGrammarFactory.createGrammar(profile, archetype);
|
||||||
|
|
||||||
|
System.out.println("Tuning grammar for PlayerProfile & LevelArchetype using RETE");
|
||||||
|
grammar = GrammarTuner.tune(grammar,profile, archetype);
|
||||||
|
|
||||||
|
System.out.println("Sample level parameters: "
|
||||||
|
+ grammar.generateRandom(seed));
|
||||||
create(seed, difficulty, type);
|
create(seed, difficulty, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/dk/itu/mario/level/generator/ArchetypeMatcher.java
Normal file
12
src/dk/itu/mario/level/generator/ArchetypeMatcher.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
import dk.itu.mario.MarioInterface.GamePlay;
|
||||||
|
import dk.itu.mario.engine.DataRecorder;
|
||||||
|
import dk.itu.mario.level.generator.LevelArchetype.TYPE;
|
||||||
|
|
||||||
|
public class ArchetypeMatcher {
|
||||||
|
public static LevelArchetype getMatchingArchetype(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
||||||
|
System.out.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
|
||||||
|
return new LevelArchetype(TYPE.OVERGROUND,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/dk/itu/mario/level/generator/GrammarTuner.java
Normal file
7
src/dk/itu/mario/level/generator/GrammarTuner.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
public class GrammarTuner {
|
||||||
|
public static LevelGrammar tune(LevelGrammar grammar, PlayerProfile profile, LevelArchetype archetype) {
|
||||||
|
return grammar;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/dk/itu/mario/level/generator/LevelArchetype.java
Normal file
31
src/dk/itu/mario/level/generator/LevelArchetype.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
public class LevelArchetype {
|
||||||
|
public static final int MAX_DIFFICULTY_LEVEL = 10;
|
||||||
|
//The canonical Super Mario level types.
|
||||||
|
public enum TYPE {OVERGROUND, UNDERGROUND, CASTLE}
|
||||||
|
|
||||||
|
private int difficultyLevel;
|
||||||
|
private TYPE type;
|
||||||
|
|
||||||
|
public LevelArchetype(TYPE type, int difficultyLevel) {
|
||||||
|
if (difficultyLevel < 1 || difficultyLevel > MAX_DIFFICULTY_LEVEL) {
|
||||||
|
throw new IllegalArgumentException("DifficultyLevel must be in the range [1.." + MAX_DIFFICULTY_LEVEL +"]");
|
||||||
|
}
|
||||||
|
this.difficultyLevel = difficultyLevel;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDifficultyLevel() {
|
||||||
|
return difficultyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TYPE getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return type + " (Difficulty " + difficultyLevel + "/" + MAX_DIFFICULTY_LEVEL+")";
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/dk/itu/mario/level/generator/LevelGrammar.java
Normal file
58
src/dk/itu/mario/level/generator/LevelGrammar.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class LevelGrammar {
|
||||||
|
private Variable start;
|
||||||
|
private Map<Variable, ProductionRule> ruleMap = new HashMap<Variable, ProductionRule>();
|
||||||
|
private Set<Variable> variables = new TreeSet<Variable>();
|
||||||
|
|
||||||
|
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 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductionRule getRule(Variable var) {
|
||||||
|
return ruleMap.get(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart(Variable start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/dk/itu/mario/level/generator/LevelGrammarFactory.java
Normal file
21
src/dk/itu/mario/level/generator/LevelGrammarFactory.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
|
||||||
|
public class LevelGrammarFactory {
|
||||||
|
public static LevelGrammar createGrammar(PlayerProfile playerProfile, LevelArchetype archetype) {
|
||||||
|
LevelGrammar grammar = new LevelGrammar();
|
||||||
|
|
||||||
|
Variable v_S = new Variable("S");
|
||||||
|
Variable v_level_start = new Variable("level_start");
|
||||||
|
Variable v_level_end = new Variable("level_end");
|
||||||
|
|
||||||
|
grammar.addVariable(v_S);
|
||||||
|
grammar.addVariable(v_level_start);
|
||||||
|
grammar.addVariable(v_level_end);
|
||||||
|
|
||||||
|
grammar.addProductionRule(new ProductionRule(v_S,v_level_start,v_level_end));
|
||||||
|
grammar.setStart(v_S);
|
||||||
|
|
||||||
|
return grammar;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/dk/itu/mario/level/generator/PlayerProfile.java
Normal file
29
src/dk/itu/mario/level/generator/PlayerProfile.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
public class PlayerProfile {
|
||||||
|
//From Bartle/Yee models of player psychology: achiever, killer, explorer, manipulator
|
||||||
|
public enum TYPE { RUNNER, SHOOTER, JUMPER, BUMPER}
|
||||||
|
//Dreyfus model of skill acquisition:
|
||||||
|
public enum SKILL_LEVEL { NOVICE, BEGINNER, COMPETENT, PROFICIENT, EXPERT}
|
||||||
|
|
||||||
|
private SKILL_LEVEL skillLevel;
|
||||||
|
private TYPE type;
|
||||||
|
|
||||||
|
public PlayerProfile(SKILL_LEVEL skillLevel, TYPE type) {
|
||||||
|
this.skillLevel = skillLevel;
|
||||||
|
this .type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SKILL_LEVEL getSkillLevel() {
|
||||||
|
return skillLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TYPE getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return skillLevel + " " + type;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/dk/itu/mario/level/generator/ProductionRule.java
Normal file
25
src/dk/itu/mario/level/generator/ProductionRule.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProductionRule {
|
||||||
|
private Variable lhs;
|
||||||
|
private List<Variable> rhs;
|
||||||
|
|
||||||
|
public ProductionRule(Variable lhs, Variable... rhs) {
|
||||||
|
this.lhs = lhs;
|
||||||
|
this.rhs = new ArrayList<Variable>();
|
||||||
|
for (Variable var : rhs) {
|
||||||
|
this.rhs.add(var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getLHS() {
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Variable> getRHS() {
|
||||||
|
return rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/dk/itu/mario/level/generator/ProfileMatcher.java
Normal file
13
src/dk/itu/mario/level/generator/ProfileMatcher.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
import dk.itu.mario.MarioInterface.GamePlay;
|
||||||
|
import dk.itu.mario.engine.DataRecorder;
|
||||||
|
import dk.itu.mario.level.generator.PlayerProfile.SKILL_LEVEL;
|
||||||
|
import dk.itu.mario.level.generator.PlayerProfile.TYPE;
|
||||||
|
|
||||||
|
public class ProfileMatcher {
|
||||||
|
public static PlayerProfile getMatchingProfile(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
||||||
|
System.out.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
|
||||||
|
return new PlayerProfile(SKILL_LEVEL.NOVICE, TYPE.RUNNER);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dk/itu/mario/level/generator/Variable.java
Normal file
27
src/dk/itu/mario/level/generator/Variable.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package dk.itu.mario.level.generator;
|
||||||
|
|
||||||
|
public class Variable implements Comparable<Variable> {
|
||||||
|
private boolean terminal;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Variable(String value) {
|
||||||
|
this.value = value;
|
||||||
|
this.terminal = (value.toLowerCase().equals(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTerminal() {
|
||||||
|
return terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Variable o) {
|
||||||
|
return this.value.compareTo(o.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user