- Implemented the reward weighting.

- Fixed a balance issue with the blocks and coins on straight stretches of even length.
This commit is contained in:
Marshall
2012-03-18 13:42:59 -04:00
parent 4ce414408e
commit bc45062ad8
2 changed files with 111 additions and 69 deletions

View File

@@ -17,9 +17,9 @@ import dk.itu.mario.level.matcher.ArchetypeMatcher;
import dk.itu.mario.level.matcher.ProfileMatcher; import dk.itu.mario.level.matcher.ProfileMatcher;
public class PCGLevel extends Level { public class PCGLevel extends Level {
public static double POWERUP_PROBABILITY = .1; public double powerupProbability;
public static double BLOCKS_PROBABILITY = .3; public double blocksProbability;
public static double COINS_PROBABILITY = .5; public double coinsProbability;
public static int COIN_REWARD = 1; public static int COIN_REWARD = 1;
public static int POWERUP_REWARD = 2; public static int POWERUP_REWARD = 2;
@@ -103,6 +103,13 @@ public class PCGLevel extends Level {
GrammarTuner.tune(grammar, profile, archetype); GrammarTuner.tune(grammar, profile, archetype);
System.out.println("Creating level."); System.out.println("Creating level.");
// TODO Refactor into a probability setter function so that we can set
// the challenge probabilities, too.
blocksProbability = profile.getProbability(TYPE.BLOCKS);
coinsProbability = profile.getProbability(TYPE.COINS);
powerupProbability = profile.getProbability(TYPE.POWER_UP);
create(seed, profile, archetype, grammar); create(seed, profile, archetype, grammar);
} }
@@ -134,7 +141,8 @@ public class PCGLevel extends Level {
private void create(long seed, PlayerProfile profile, private void create(long seed, PlayerProfile profile,
LevelArchetype archetype, LevelGrammar grammar) { LevelArchetype archetype, LevelGrammar grammar) {
System.out.println("PlayerProfile.getProbability(COINS): " + profile.getProbability(TYPE.COINS)); System.out.println("PlayerProfile.getProbability(COINS): "
+ profile.getProbability(TYPE.COINS));
if (dataRecorder == DataRecorder.BLANK_RECORD) { if (dataRecorder == DataRecorder.BLANK_RECORD) {
System.out System.out
@@ -486,7 +494,7 @@ public class PCGLevel extends Level {
setBlock( setBlock(
xo + x, xo + x,
floor - 6, floor - 6,
(random.nextDouble() <= POWERUP_PROBABILITY) ? Level.BLOCK_POWERUP (random.nextDouble() <= powerupProbability) ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
} }
@@ -539,7 +547,7 @@ public class PCGLevel extends Level {
setBlock( setBlock(
xo + x, xo + x,
floor - 7, floor - 7,
random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
} }
} }
@@ -681,9 +689,9 @@ public class PCGLevel extends Level {
private int shouldAddReward() { private int shouldAddReward() {
double guess = random.nextDouble(); double guess = random.nextDouble();
if (guess < COINS_PROBABILITY) { if (guess < coinsProbability) {
return 1; return 1;
} else if (guess < COINS_PROBABILITY + BLOCKS_PROBABILITY) { } else if (guess < coinsProbability + blocksProbability) {
return 2; return 2;
} else { } else {
return 0; return 0;
@@ -1079,12 +1087,12 @@ public class PCGLevel extends Level {
setBlock( setBlock(
xo + length + 1, xo + length + 1,
this.height - heightMod - 3, this.height - heightMod - 3,
random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + length + 2, xo + length + 2,
this.height - heightMod - 3, this.height - heightMod - 3,
random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
} }
@@ -1152,7 +1160,8 @@ public class PCGLevel extends Level {
else { else {
setSpriteTemplate(xo + (length / 2), floor - 1, setSpriteTemplate(xo + (length / 2), floor - 1,
new SpriteTemplate(enemyType, shouldAddChallenge(ChallengeType.HARDER_ENEMY))); new SpriteTemplate(enemyType,
shouldAddChallenge(ChallengeType.HARDER_ENEMY)));
} }
} }
@@ -1175,32 +1184,34 @@ public class PCGLevel extends Level {
xo + (start - 2), xo + (start - 2),
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + (start - 1), xo + (start - 1),
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + start, xo + start,
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN);
setBlock(
xo + (start + 2),
floor - 3,
coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + (start + 1), xo + (start + 1),
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
if (length % 2 != 0) {
setBlock(
xo + (start + 2),
floor - 3,
coins ? Level.COIN
: random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN);
}
} }
else if (length >= 5) { else if (length >= 5) {
@@ -1211,19 +1222,19 @@ public class PCGLevel extends Level {
xo + (start - 1), xo + (start - 1),
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + start, xo + start,
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
setBlock( setBlock(
xo + (start + 1), xo + (start + 1),
floor - 3, floor - 3,
coins ? Level.COIN coins ? Level.COIN
: random.nextDouble() < POWERUP_PROBABILITY ? Level.BLOCK_POWERUP : random.nextDouble() < powerupProbability ? Level.BLOCK_POWERUP
: Level.BLOCK_COIN); : Level.BLOCK_COIN);
} }
} }

View File

@@ -7,10 +7,16 @@ import java.util.Set;
import dk.itu.mario.level.matcher.ProfileMatcher.SKILL; import dk.itu.mario.level.matcher.ProfileMatcher.SKILL;
public class PlayerProfile { public class PlayerProfile {
//From Bartle/Yee models of player psychology: achiever, killer, explorer, manipulator // From Bartle/Yee models of player psychology: achiever, killer, explorer,
public enum TYPE { BUMPER, COLLECTOR, RUNNER, SHOOTER, JUMPER} // manipulator
public enum TYPE {
BUMPER, COLLECTOR, RUNNER, SHOOTER, JUMPER
}
// Dreyfus model of skill acquisition: // Dreyfus model of skill acquisition:
public enum SKILL_LEVEL { NOVICE, BEGINNER, COMPETENT, PROFICIENT, EXPERT} public enum SKILL_LEVEL {
NOVICE, BEGINNER, COMPETENT, PROFICIENT, EXPERT
}
private Set<LevelComponent.TYPE> enabledComponents = new HashSet<LevelComponent.TYPE>(); private Set<LevelComponent.TYPE> enabledComponents = new HashSet<LevelComponent.TYPE>();
@@ -18,7 +24,8 @@ public class PlayerProfile {
private Map<SKILL, Integer> skillVector; private Map<SKILL, Integer> skillVector;
private TYPE type; private TYPE type;
public PlayerProfile(SKILL_LEVEL skillLevel, TYPE type, Map<SKILL,Integer> skillVector) { public PlayerProfile(SKILL_LEVEL skillLevel, TYPE type,
Map<SKILL, Integer> skillVector) {
this.skillLevel = skillLevel; this.skillLevel = skillLevel;
this.type = type; this.type = type;
this.skillVector = skillVector; this.skillVector = skillVector;
@@ -61,13 +68,37 @@ public class PlayerProfile {
if (!isEnabled(type)) { if (!isEnabled(type)) {
return 0.0; return 0.0;
} }
// SKILLs: { BUMP, COLLECT, JUMP, RUN, SHOOT, STOMP }
// TYPEs: { BUMPER, COLLECTOR, RUNNER, SHOOTER, JUMPER}
switch (type) { switch (type) {
case BLOCKS: case BLOCKS:
return 0.3; return (.5) * (skillVector.get(SKILL.BUMP) / 100.0);
case COINS: case COINS:
return 0.5; return (.5) * (skillVector.get(SKILL.COLLECT) / 100.0);
case POWER_UP: case POWER_UP:
return 0.1; double skillMod = 0;
switch (skillLevel) {
case BEGINNER:
skillMod = .8;
break;
case COMPETENT:
skillMod = .6;
break;
case PROFICIENT:
skillMod = .4;
break;
case EXPERT:
skillMod = .2;
break;
default:
skillMod = 1;
}
skillMod = (skillMod + (skillVector.get(SKILL.SHOOT) / 100.0)) / 2.0;
return (.3) * skillMod;
default: default:
return 0.1; return 0.1;
} }