Fixed NPE when the default player.txt does not exist. Fixed bug when requesting PowerUp component of invalid length. Change default lives to 1.

This commit is contained in:
Woody Folsom
2012-03-18 18:14:11 -04:00
parent 0619f95f33
commit 18643d17e4
8 changed files with 176 additions and 81 deletions

View File

@@ -9,12 +9,14 @@ import dk.itu.mario.level.PlayerProfile;
import dk.itu.mario.level.PlayerProfile.SKILL_LEVEL;
public class ProfileMatcher {
public enum SKILL { BUMP, COLLECT, JUMP, RUN, SHOOT, STOMP }
private static Map<PlayerProfile.TYPE, Map<SKILL,Integer>> referenceMetrics = new HashMap<PlayerProfile.TYPE, Map<SKILL,Integer>>();
public enum SKILL {
BUMP, COLLECT, JUMP, RUN, SHOOT, STOMP
}
private static Map<PlayerProfile.TYPE, Map<SKILL, Integer>> referenceMetrics = new HashMap<PlayerProfile.TYPE, Map<SKILL, Integer>>();
static {
Map<SKILL,Integer> canonicalVector = new HashMap<SKILL,Integer>();
Map<SKILL, Integer> canonicalVector = new HashMap<SKILL, Integer>();
canonicalVector.put(SKILL.BUMP, 100);
canonicalVector.put(SKILL.COLLECT, 50);
canonicalVector.put(SKILL.JUMP, 50);
@@ -22,17 +24,17 @@ public class ProfileMatcher {
canonicalVector.put(SKILL.SHOOT, 0);
canonicalVector.put(SKILL.STOMP, 0);
referenceMetrics.put(PlayerProfile.TYPE.BUMPER, canonicalVector);
canonicalVector = new HashMap<SKILL,Integer>();
canonicalVector = new HashMap<SKILL, Integer>();
canonicalVector.put(SKILL.BUMP, 50);
canonicalVector.put(SKILL.COLLECT, 100);
canonicalVector.put(SKILL.JUMP, 50);
canonicalVector.put(SKILL.RUN, 0);
canonicalVector.put(SKILL.SHOOT, 0);
canonicalVector.put(SKILL.STOMP, 0);
canonicalVector.put(SKILL.STOMP, 0);
referenceMetrics.put(PlayerProfile.TYPE.COLLECTOR, canonicalVector);
canonicalVector = new HashMap<SKILL,Integer>();
canonicalVector = new HashMap<SKILL, Integer>();
canonicalVector.put(SKILL.BUMP, 50);
canonicalVector.put(SKILL.COLLECT, 0);
canonicalVector.put(SKILL.JUMP, 100);
@@ -40,17 +42,17 @@ public class ProfileMatcher {
canonicalVector.put(SKILL.SHOOT, 0);
canonicalVector.put(SKILL.STOMP, 0);
referenceMetrics.put(PlayerProfile.TYPE.JUMPER, canonicalVector);
canonicalVector = new HashMap<SKILL,Integer>();
canonicalVector = new HashMap<SKILL, Integer>();
canonicalVector.put(SKILL.BUMP, 0);
canonicalVector.put(SKILL.COLLECT, 0);
canonicalVector.put(SKILL.JUMP, 25);
canonicalVector.put(SKILL.RUN, 100);
canonicalVector.put(SKILL.SHOOT, 25);
canonicalVector.put(SKILL.STOMP, 0);
canonicalVector.put(SKILL.STOMP, 0);
referenceMetrics.put(PlayerProfile.TYPE.RUNNER, canonicalVector);
canonicalVector = new HashMap<SKILL,Integer>();
canonicalVector = new HashMap<SKILL, Integer>();
canonicalVector.put(SKILL.BUMP, 0);
canonicalVector.put(SKILL.COLLECT, 0);
canonicalVector.put(SKILL.JUMP, 25);
@@ -59,73 +61,90 @@ public class ProfileMatcher {
canonicalVector.put(SKILL.STOMP, 0);
referenceMetrics.put(PlayerProfile.TYPE.SHOOTER, canonicalVector);
}
public static PlayerProfile getMatchingProfile(GamePlay playerMetrics, DataRecorder detailedInfo) {
System.out.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
public static PlayerProfile getMatchingProfile(GamePlay playerMetrics,
DataRecorder detailedInfo) {
System.out
.println("Selecting PlayerProfile based on GamePlay metrics, DataRecorder logs.");
int bumperScore = 0;
int collectorScore = 0;
int jumperScore = 0;
int runnerScore = 0;
int shooterScore = 0;
int stomperScore = 0;
bumperScore += playerMetrics.percentageBlocksDestroyed * 20;
bumperScore += playerMetrics.percentageCoinBlocksDestroyed * 20;
bumperScore += playerMetrics.percentageEmptyBlockesDestroyed * 20;
bumperScore += playerMetrics.percentagePowerBlockDestroyed * 20;
bumperScore += 4 * Math.min(5, playerMetrics.kickedShells);
collectorScore += playerMetrics.coinsCollected / 35.0;
jumperScore = Math.min(100, playerMetrics.jumpsNumber);
runnerScore = playerMetrics.timeRunningRight / playerMetrics.totalTime;
shooterScore += 10 * Math.min(10, playerMetrics.enemyKillByFire / 10.0);
stomperScore += Math.min(100, 2 * (playerMetrics.GoombasKilled + playerMetrics.GreenTurtlesKilled + playerMetrics.RedTurtlesKilled));
if (playerMetrics == GamePlay.DEFAULT_PROFILE) {
bumperScore = 50;
collectorScore = 50;
jumperScore = 50;
runnerScore = 50;
shooterScore = 50;
stomperScore = 50;
} else {
bumperScore += playerMetrics.percentageBlocksDestroyed * 20;
bumperScore += playerMetrics.percentageCoinBlocksDestroyed * 20;
bumperScore += playerMetrics.percentageEmptyBlockesDestroyed * 20;
bumperScore += playerMetrics.percentagePowerBlockDestroyed * 20;
bumperScore += 4 * Math.min(5, playerMetrics.kickedShells);
collectorScore += playerMetrics.coinsCollected / 35.0;
jumperScore = Math.min(100, playerMetrics.jumpsNumber);
runnerScore = playerMetrics.timeRunningRight
/ playerMetrics.totalTime;
shooterScore += 10 * Math.min(10,
playerMetrics.enemyKillByFire / 10.0);
stomperScore += Math
.min(100,
2 * (playerMetrics.GoombasKilled
+ playerMetrics.GreenTurtlesKilled + playerMetrics.RedTurtlesKilled));
}
clampToPercentRange(bumperScore);
clampToPercentRange(collectorScore);
clampToPercentRange(jumperScore);
clampToPercentRange(runnerScore);
clampToPercentRange(shooterScore);
clampToPercentRange(stomperScore);
System.out.println("bumperScore: " + bumperScore);
System.out.println("collectorScore: " + collectorScore);
System.out.println("jumperScore: " + jumperScore);
System.out.println("shooterScore: " + shooterScore);
System.out.println("stomperScore: " + stomperScore);
Map<SKILL,Integer> playerProfileVector = new HashMap<SKILL,Integer>();
Map<SKILL, Integer> playerProfileVector = new HashMap<SKILL, Integer>();
playerProfileVector.put(SKILL.BUMP, bumperScore);
playerProfileVector.put(SKILL.COLLECT, collectorScore);
playerProfileVector.put(SKILL.JUMP, jumperScore);
playerProfileVector.put(SKILL.RUN, runnerScore);
playerProfileVector.put(SKILL.SHOOT, shooterScore);
playerProfileVector.put(SKILL.STOMP, stomperScore);
double minDist = Double.MAX_VALUE;
PlayerProfile.TYPE closestMatch = PlayerProfile.TYPE.RUNNER;
for (PlayerProfile.TYPE type : PlayerProfile.TYPE.values()) {
Map<SKILL,Integer> canonicalVector = ProfileMatcher.referenceMetrics.get(type);
Map<SKILL, Integer> canonicalVector = ProfileMatcher.referenceMetrics
.get(type);
double distance = 0.0;
for (SKILL skill : SKILL.values()) {
distance += Math.pow(canonicalVector.get(skill) - playerProfileVector.get(skill), 2);
distance += Math.pow(canonicalVector.get(skill)
- playerProfileVector.get(skill), 2);
}
if (distance < minDist) {
minDist = distance;
closestMatch = type;
}
}
SKILL_LEVEL skillLevel;
int keyScore = getKeyScore(playerProfileVector, closestMatch);
if (keyScore <= 20) {
skillLevel = SKILL_LEVEL.NOVICE;
} else if (keyScore <= 40) {
@@ -137,29 +156,32 @@ public class ProfileMatcher {
} else {
skillLevel = SKILL_LEVEL.EXPERT;
}
System.out.println("Skill level for this " + closestMatch + " is " + skillLevel + " (based on a score of " + keyScore + " out of 100.)");
System.out.println("Skill level for this " + closestMatch + " is "
+ skillLevel + " (based on a score of " + keyScore
+ " out of 100.)");
return new PlayerProfile(skillLevel, closestMatch, playerProfileVector);
}
private static int getKeyScore(Map<SKILL, Integer> playerProfileVector, PlayerProfile.TYPE playerProfileType) {
private static int getKeyScore(Map<SKILL, Integer> playerProfileVector,
PlayerProfile.TYPE playerProfileType) {
switch (playerProfileType) {
case BUMPER :
case BUMPER:
return playerProfileVector.get(SKILL.BUMP);
case COLLECTOR :
case COLLECTOR:
return playerProfileVector.get(SKILL.COLLECT);
case JUMPER :
case JUMPER:
return playerProfileVector.get(SKILL.JUMP);
case RUNNER :
case RUNNER:
return playerProfileVector.get(SKILL.RUN);
case SHOOTER :
case SHOOTER:
return playerProfileVector.get(SKILL.SHOOT);
default :
default:
return 0;
}
}
private static int clampToPercentRange(int value) {
if (value < 0) {
return 0;