Rete-based rule system (Drools) correctly fires the appropriate actions when Player's Profile meets certain criteria, based on the rules in rules/LevelTunerRules.drl.
This commit is contained in:
@@ -1,7 +0,0 @@
|
|||||||
package org.drools.examples.simple;
|
|
||||||
rule "Account balance is less than 100"
|
|
||||||
when
|
|
||||||
$account : Account( balance < 100 ) // condition
|
|
||||||
then
|
|
||||||
System.out.println("Account number: " + $account.getId() + " is below 100"); // consequence
|
|
||||||
end
|
|
||||||
17
rules/LevelTunerRules.drl
Normal file
17
rules/LevelTunerRules.drl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package dk.itu.mario.level;
|
||||||
|
|
||||||
|
rule "NoviceJumper"
|
||||||
|
when
|
||||||
|
playerProfile : PlayerProfile( jumpSkill <= 20 ) // condition
|
||||||
|
then
|
||||||
|
System.out.println("PlayerProfile indicates NoviceJumper. Disabling Pipe challenge."); // consequence
|
||||||
|
playerProfile.setDisabled(LevelComponent.TYPE.PIPE_JUMP);
|
||||||
|
end
|
||||||
|
|
||||||
|
rule "BeginnerJumper"
|
||||||
|
when
|
||||||
|
playerProfile : PlayerProfile( jumpSkill > 20 ) // condition
|
||||||
|
then
|
||||||
|
System.out.println("PlayerProfile indicates Beginner (or better) Jumper. Pipe challenge enabled!"); // consequence
|
||||||
|
playerProfile.setEnabled(LevelComponent.TYPE.PIPE_JUMP);
|
||||||
|
end
|
||||||
@@ -13,7 +13,7 @@ public class ParsedArgs {
|
|||||||
private boolean custom = false;
|
private boolean custom = false;
|
||||||
private boolean videoCaptureEnabled = false;
|
private boolean videoCaptureEnabled = false;
|
||||||
private int levelRandSeed = (int) (Math.random() * Integer.MAX_VALUE);
|
private int levelRandSeed = (int) (Math.random() * Integer.MAX_VALUE);
|
||||||
private String generatorClass = "MyLevel";
|
private String generatorClass = "PCGLevel";
|
||||||
private String videoFileName = "LevelGenerator";
|
private String videoFileName = "LevelGenerator";
|
||||||
|
|
||||||
public LevelGenerator createLevelGenerator() {
|
public LevelGenerator createLevelGenerator() {
|
||||||
@@ -22,7 +22,7 @@ public class ParsedArgs {
|
|||||||
}
|
}
|
||||||
if ("MyLevel".equals(generatorClass)) {
|
if ("MyLevel".equals(generatorClass)) {
|
||||||
return new MyLevelGenerator();
|
return new MyLevelGenerator();
|
||||||
} else if ("MyNewLevel".equals(generatorClass)) {
|
} else if ("PCGLevel".equals(generatorClass)) {
|
||||||
return new PCGLevelGenerator();
|
return new PCGLevelGenerator();
|
||||||
} else if ("CustomizedLevel".equalsIgnoreCase(generatorClass)) {
|
} else if ("CustomizedLevel".equalsIgnoreCase(generatorClass)) {
|
||||||
return new CustomizedLevelGenerator();
|
return new CustomizedLevelGenerator();
|
||||||
|
|||||||
54
src/dk/itu/mario/level/GrammarTuner.java
Normal file
54
src/dk/itu/mario/level/GrammarTuner.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package dk.itu.mario.level;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import org.drools.KnowledgeBase;
|
||||||
|
import org.drools.KnowledgeBaseFactory;
|
||||||
|
import org.drools.builder.KnowledgeBuilder;
|
||||||
|
import org.drools.builder.KnowledgeBuilderFactory;
|
||||||
|
import org.drools.builder.ResourceType;
|
||||||
|
import org.drools.io.ResourceFactory;
|
||||||
|
import org.drools.runtime.StatefulKnowledgeSession;
|
||||||
|
|
||||||
|
import dk.itu.mario.level.PlayerProfile;
|
||||||
|
import dk.itu.mario.level.grammar.LevelGrammar;
|
||||||
|
|
||||||
|
public class GrammarTuner {
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void tune(LevelGrammar levelGrammar, PlayerProfile playerProfile, LevelArchetype archetype) {
|
||||||
|
KnowledgeBase knowledgeBase = createKnowledgeBase();
|
||||||
|
|
||||||
|
try {
|
||||||
|
StatefulKnowledgeSession session = knowledgeBase
|
||||||
|
.newStatefulKnowledgeSession();
|
||||||
|
session.insert(playerProfile);
|
||||||
|
session.fireAllRules();
|
||||||
|
} catch (RuntimeException rte) {
|
||||||
|
System.out
|
||||||
|
.println("Unable to initialize StatefulKnowledgeSession for Rete grammar tuning - all challenges will be enabled! Exception: ");
|
||||||
|
rte.printStackTrace(System.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KnowledgeBase createKnowledgeBase() {
|
||||||
|
KnowledgeBuilder builder = KnowledgeBuilderFactory
|
||||||
|
.newKnowledgeBuilder();
|
||||||
|
|
||||||
|
File accountRules = new File("rules/LevelTunerRules.drl");
|
||||||
|
builder.add(ResourceFactory.newFileResource(accountRules),
|
||||||
|
ResourceType.DRL);
|
||||||
|
|
||||||
|
if (builder.hasErrors()) {
|
||||||
|
throw new RuntimeException(builder.getErrors().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
|
||||||
|
|
||||||
|
// Add to Knowledge Base packages (rules from the drl file).
|
||||||
|
knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
|
||||||
|
|
||||||
|
return knowledgeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package dk.itu.mario.level.matcher;
|
package dk.itu.mario.level;
|
||||||
|
|
||||||
import dk.itu.mario.MarioInterface.LevelInterface;
|
import dk.itu.mario.MarioInterface.LevelInterface;
|
||||||
|
|
||||||
@@ -9,13 +9,10 @@ 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.grammar.GrammarTuner;
|
|
||||||
import dk.itu.mario.level.grammar.LevelGrammar;
|
import dk.itu.mario.level.grammar.LevelGrammar;
|
||||||
import dk.itu.mario.level.grammar.LevelGrammarFactory;
|
import dk.itu.mario.level.grammar.LevelGrammarFactory;
|
||||||
import dk.itu.mario.level.grammar.LevelParseTree;
|
import dk.itu.mario.level.grammar.LevelParseTree;
|
||||||
import dk.itu.mario.level.matcher.ArchetypeMatcher;
|
import dk.itu.mario.level.matcher.ArchetypeMatcher;
|
||||||
import dk.itu.mario.level.matcher.LevelArchetype;
|
|
||||||
import dk.itu.mario.level.matcher.PlayerProfile;
|
|
||||||
import dk.itu.mario.level.matcher.ProfileMatcher;
|
import dk.itu.mario.level.matcher.ProfileMatcher;
|
||||||
|
|
||||||
public class PCGLevel extends Level {
|
public class PCGLevel extends Level {
|
||||||
@@ -81,7 +78,7 @@ public class PCGLevel extends Level {
|
|||||||
|
|
||||||
System.out
|
System.out
|
||||||
.println("Tuning grammar for PlayerProfile & LevelArchetype using RETE");
|
.println("Tuning grammar for PlayerProfile & LevelArchetype using RETE");
|
||||||
grammar = GrammarTuner.tune(grammar, profile, archetype);
|
GrammarTuner.tune(grammar, profile, archetype);
|
||||||
|
|
||||||
System.out.println("Creating level.");
|
System.out.println("Creating level.");
|
||||||
create(seed, profile, archetype, grammar);
|
create(seed, profile, archetype, grammar);
|
||||||
|
|||||||
70
src/dk/itu/mario/level/PlayerProfile.java
Normal file
70
src/dk/itu/mario/level/PlayerProfile.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package dk.itu.mario.level;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
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 Set<LevelComponent.TYPE> enabledComponents = new HashSet<LevelComponent.TYPE>();
|
||||||
|
|
||||||
|
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 int getJumpSkill() {
|
||||||
|
switch (type) {
|
||||||
|
case JUMPER :
|
||||||
|
switch (skillLevel) {
|
||||||
|
case NOVICE :
|
||||||
|
return 20;
|
||||||
|
case BEGINNER :
|
||||||
|
return 40;
|
||||||
|
case COMPETENT :
|
||||||
|
return 60;
|
||||||
|
case PROFICIENT :
|
||||||
|
return 80;
|
||||||
|
case EXPERT :
|
||||||
|
return 100;
|
||||||
|
default :
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TYPE getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisabled(LevelComponent.TYPE type) {
|
||||||
|
if (enabledComponents.contains(type)) {
|
||||||
|
System.out.println("Component type disabled: " + type);
|
||||||
|
enabledComponents.remove(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(LevelComponent.TYPE type) {
|
||||||
|
if (!enabledComponents.contains(type)) {
|
||||||
|
System.out.println("Component type enabled: " + type);
|
||||||
|
enabledComponents.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return skillLevel + " " + type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package dk.itu.mario.level.grammar;
|
|
||||||
|
|
||||||
import dk.itu.mario.level.matcher.LevelArchetype;
|
|
||||||
import dk.itu.mario.level.matcher.PlayerProfile;
|
|
||||||
|
|
||||||
public class GrammarTuner {
|
|
||||||
public static LevelGrammar tune(LevelGrammar grammar, PlayerProfile profile, LevelArchetype archetype) {
|
|
||||||
return grammar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package dk.itu.mario.level.grammar;
|
package dk.itu.mario.level.grammar;
|
||||||
|
|
||||||
import dk.itu.mario.level.matcher.LevelArchetype;
|
import dk.itu.mario.level.LevelArchetype;
|
||||||
import dk.itu.mario.level.matcher.PlayerProfile;
|
import dk.itu.mario.level.PlayerProfile;
|
||||||
|
|
||||||
|
|
||||||
public class LevelGrammarFactory {
|
public class LevelGrammarFactory {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package dk.itu.mario.level.matcher;
|
|||||||
|
|
||||||
import dk.itu.mario.MarioInterface.GamePlay;
|
import dk.itu.mario.MarioInterface.GamePlay;
|
||||||
import dk.itu.mario.engine.DataRecorder;
|
import dk.itu.mario.engine.DataRecorder;
|
||||||
import dk.itu.mario.level.matcher.LevelArchetype.TYPE;
|
import dk.itu.mario.level.LevelArchetype;
|
||||||
|
import dk.itu.mario.level.LevelArchetype.TYPE;
|
||||||
|
|
||||||
public class ArchetypeMatcher {
|
public class ArchetypeMatcher {
|
||||||
public static LevelArchetype getMatchingArchetype(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
public static LevelArchetype getMatchingArchetype(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package dk.itu.mario.level.matcher;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,13 @@ package dk.itu.mario.level.matcher;
|
|||||||
|
|
||||||
import dk.itu.mario.MarioInterface.GamePlay;
|
import dk.itu.mario.MarioInterface.GamePlay;
|
||||||
import dk.itu.mario.engine.DataRecorder;
|
import dk.itu.mario.engine.DataRecorder;
|
||||||
import dk.itu.mario.level.matcher.PlayerProfile.SKILL_LEVEL;
|
import dk.itu.mario.level.PlayerProfile;
|
||||||
import dk.itu.mario.level.matcher.PlayerProfile.TYPE;
|
import dk.itu.mario.level.PlayerProfile.SKILL_LEVEL;
|
||||||
|
import dk.itu.mario.level.PlayerProfile.TYPE;
|
||||||
|
|
||||||
public class ProfileMatcher {
|
public class ProfileMatcher {
|
||||||
public static PlayerProfile getMatchingProfile(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
public static PlayerProfile getMatchingProfile(GamePlay playerMetrics, DataRecorder detailedInfo) {
|
||||||
System.out.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
|
System.out.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
|
||||||
return new PlayerProfile(SKILL_LEVEL.NOVICE, TYPE.RUNNER);
|
return new PlayerProfile(SKILL_LEVEL.BEGINNER, TYPE.JUMPER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package org.drools.examples.simple;
|
|
||||||
|
|
||||||
public class Account {
|
|
||||||
private int balance;
|
|
||||||
private String Id;
|
|
||||||
public int getBalance() {
|
|
||||||
return balance;
|
|
||||||
}
|
|
||||||
public void setBalance(int balance) {
|
|
||||||
this.balance = balance;
|
|
||||||
}
|
|
||||||
public String getId() {
|
|
||||||
return Id;
|
|
||||||
}
|
|
||||||
public void setId(String id) {
|
|
||||||
Id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package org.drools.examples.simple;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import org.drools.KnowledgeBase;
|
|
||||||
import org.drools.KnowledgeBaseFactory;
|
|
||||||
import org.drools.builder.KnowledgeBuilder;
|
|
||||||
import org.drools.builder.KnowledgeBuilderFactory;
|
|
||||||
import org.drools.builder.ResourceType;
|
|
||||||
import org.drools.io.ResourceFactory;
|
|
||||||
import org.drools.runtime.StatefulKnowledgeSession;
|
|
||||||
import org.drools.runtime.StatelessKnowledgeSession;
|
|
||||||
|
|
||||||
public class DroolsExample {
|
|
||||||
/**
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
//Create KnowledgeBase...
|
|
||||||
KnowledgeBase knowledgeBase = createKnowledgeBase();
|
|
||||||
//Create a statefull session
|
|
||||||
StatefulKnowledgeSession session = knowledgeBase.newStatefulKnowledgeSession();
|
|
||||||
|
|
||||||
//Create Facts - two ban accounts
|
|
||||||
Account account = new Account();
|
|
||||||
account.setBalance(10);
|
|
||||||
account.setId("N1");
|
|
||||||
|
|
||||||
Account account2 = new Account();
|
|
||||||
account2.setBalance(120);
|
|
||||||
account2.setId("N2");
|
|
||||||
|
|
||||||
//Insert the bank account facts into a State full session
|
|
||||||
session.insert(account);
|
|
||||||
session.insert(account2);
|
|
||||||
|
|
||||||
//Note that at this point, afetr fact insertation the Agenda has one activation ready to be fired.
|
|
||||||
//Account1 is less than 100.
|
|
||||||
|
|
||||||
//Only now we will fire the rules which are already in the agenda
|
|
||||||
session.fireAllRules();
|
|
||||||
|
|
||||||
//A message of N1 is less than 100 will be printed to stdout.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create new knowledge base
|
|
||||||
*/
|
|
||||||
private static KnowledgeBase createKnowledgeBase() {
|
|
||||||
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
|
|
||||||
//Add drl file into builder
|
|
||||||
File accountRules = new File("rules/BasicAccountRule.drl"); //Where the account rule is.
|
|
||||||
builder.add(ResourceFactory.newFileResource(accountRules), ResourceType.DRL);
|
|
||||||
if (builder.hasErrors()) {
|
|
||||||
throw new RuntimeException(builder.getErrors().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
|
|
||||||
|
|
||||||
//Add to Knowledge Base packages from the builder which are actually the rules from the drl file.
|
|
||||||
knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
|
|
||||||
|
|
||||||
return knowledgeBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user