Merge branch 'master' of woodyfolsom.net:/opt/git/cs8803p3

This commit is contained in:
Woody Folsom
2012-03-17 16:46:18 -04:00
2 changed files with 250 additions and 77 deletions

View File

@@ -1,30 +1,40 @@
package dk.itu.mario.level; package dk.itu.mario.level;
public class LevelComponent { public class LevelComponent {
public enum TYPE { FLAT, PIPES, MAZE}; public enum TYPE {
FLAT, PIPE_JUMP, PLATFORM_JUMP, MAZE
};
public enum MazeLevel {
BOT, MID, TOP
}
public enum PlatformLevel {
BOT, MID_D, MID_U, TOP
}
private TYPE type; private TYPE type;
private int start; private int start;
private int end; private int end;
public LevelComponent(TYPE type, int start, int end) { public LevelComponent(TYPE type, int start, int end) {
this.type = type; this.type = type;
this.end = end; this.end = end;
this.start = start; this.start = start;
} }
public TYPE getType() { public TYPE getType() {
return type; return type;
} }
public int getStart() { public int getStart() {
return start; return start;
} }
public int getEnd() { public int getEnd() {
return end; return end;
} }
@Override @Override
public String toString() { public String toString() {
return type + "[" + start + ".." + end + "]"; return type + "[" + start + ".." + end + "]";

View File

@@ -43,8 +43,8 @@ public class PCGLevel extends Level {
super(width, height); super(width, height);
} }
public PCGLevel(int width, int height, long seed, int difficulty, public PCGLevel(int width, int height, long seed, int difficulty, int type,
int type, GamePlay playerMetrics) { GamePlay playerMetrics) {
this(width, height); this(width, height);
System.out System.out
@@ -54,8 +54,8 @@ public class PCGLevel extends Level {
generateLevel(seed, playerMetrics); generateLevel(seed, playerMetrics);
} }
public PCGLevel(int width, int height, long seed, int difficulty, public PCGLevel(int width, int height, long seed, int difficulty, int type,
int type, GamePlay playerMetrics, DataRecorder dataRecorder) { GamePlay playerMetrics, DataRecorder dataRecorder) {
this(width, height); this(width, height);
System.out System.out
@@ -128,42 +128,48 @@ public class PCGLevel extends Level {
System.out.println("Generating level for component list: "); System.out.println("Generating level for component list: ");
LevelParseTree parseTree = grammar.generateRandomTree(seed, width); LevelParseTree parseTree = grammar.generateRandomTree(seed, width);
List<LevelComponent> levelTemplate = parseTree.getLevelTemplate(); List<LevelComponent> levelTemplate = parseTree.getLevelTemplate();
int length = 0; int length = 0;
for (LevelComponent lcomp : levelTemplate) { for (LevelComponent lcomp : levelTemplate) {
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:
while (length < Math.min(width-64,lcomp.getEnd())) { length += buildStraight(length, lcomp.getEnd(), true);
length += buildStraight(length, lcomp.getEnd(), true);
}
break; break;
default : case PIPE_JUMP:
System.out.println("Cannot build level segment for unrecognized LevelComponent type: " + type); length += buildPipeJump(length, width-64-length);
break;
case PLATFORM_JUMP:
length += buildPlatformJump(length, width-64-length);
break;
case MAZE:
length += buildMaze(length, width-64-length);
break;
default:
System.out
.println("Cannot build level segment for unrecognized LevelComponent type: "
+ type);
} }
} }
System.out.println("Total length built: " + length);
/* Original non-PCG code:
// create the start location
int length = buildStraight(0, width, true);
length += buildPipeJump(length, width - length);
// length += buildMaze(length, width - length);
// create all of the medium sections System.out.println("Total length built: " + length);
while (length < width - 64) {
length += buildStraight(length, width - length, true); /*
} * Original non-PCG code: // create the start location int length =
*/ * buildStraight(0, width, true); length += buildPipeJump(length, width
* - length); // length += buildMaze(length, width - length);
*
* // create all of the medium sections while (length < width - 64) {
* length += buildStraight(length, width - length, true); }
*/
// set the end piece // set the end piece
int floor = height - 1 - random.nextInt(4); int floor = height - 1 - random.nextInt(4);
xExit = length + 8; xExit = length + 8;
yExit = floor; yExit = floor;
fillEndPiece(length, floor); fillEndPiece(length, floor);
} }
@@ -196,6 +202,7 @@ public class PCGLevel extends Level {
fixWalls(); fixWalls();
} }
private void addEnemyLine(int x0, int x1, int y) { private void addEnemyLine(int x0, int x1, int y) {
for (int x = x0; x < x1; x++) { for (int x = x0; x < x1; x++) {
if (random.nextInt(35) < difficulty + 1) { if (random.nextInt(35) < difficulty + 1) {
@@ -310,36 +317,42 @@ public class PCGLevel extends Level {
private int buildMaze(int xo, int maxLength) { private int buildMaze(int xo, int maxLength) {
int length = random.nextInt(maxLength - 19) + 20; int length = random.nextInt(maxLength - 19) + 20;
int soFar = 0; int soFar = 6;
int next; int next;
// MazeLevel last = MazeLevel.BOT; // boolean skipUp = false;
// boolean skipDown = false;
class Stretch { class Stretch {
public int len; public int len;
public PCGLevel.MazeLevel lvl; public LevelComponent.MazeLevel lvl;
public Stretch(int lngth) { public Stretch(int lngth) {
len = lngth; len = lngth;
switch (random.nextInt(3)) { switch (random.nextInt(3)) {
case 0: case 0:
lvl = MazeLevel.TOP; lvl = LevelComponent.MazeLevel.TOP;
break; break;
case 1: case 1:
lvl = MazeLevel.MID; lvl = LevelComponent.MazeLevel.MID;
break; break;
default: default:
lvl = MazeLevel.BOT; lvl = LevelComponent.MazeLevel.BOT;
} }
} }
} }
ArrayList<Stretch> maze = new ArrayList<Stretch>(); ArrayList<Stretch> maze = new ArrayList<Stretch>();
while (soFar < length - 3) { loop: while (soFar < length) {
next = random.nextInt(length / 2) + 1; if (soFar + 3 > length) {
length = soFar;
break loop;
}
if (soFar + next > length - 3) { next = random.nextInt(18) + 5;
if (soFar + next > length) {
next = length - soFar; next = length - soFar;
} }
@@ -348,54 +361,104 @@ public class PCGLevel extends Level {
soFar += next; soFar += next;
} }
soFar = 0;
setBlock(xo, this.height - 1, Level.GROUND); setBlock(xo, this.height - 1, Level.GROUND);
setBlock(xo + 1, this.height - 1, Level.GROUND); setBlock(xo + 1, this.height - 1, Level.GROUND);
setBlock(xo + 2, this.height - 1, Level.GROUND); setBlock(xo + 2, this.height - 1, Level.GROUND);
soFar = 3;
Stretch str;
// Stretch nxt;
boolean stretchEnd;
boolean midLine;
for (int i = 0; i < maze.size(); i++) {
str = maze.get(i);
// if (i < maze.size() - 1) {
// nxt = maze.get(i + 1);
// } else {
// nxt = null;
// }
// if (nxt != null) {
// skipUp = ((nxt.lvl != MazeLevel.TOP) && (str.lvl ==
// MazeLevel.TOP))
// || ((nxt.lvl == MazeLevel.TOP) && (str.lvl != MazeLevel.TOP));
//
// skipDown = ((nxt.lvl != MazeLevel.BOT) && (str.lvl ==
// MazeLevel.BOT))
// || ((str.lvl != MazeLevel.BOT) && (nxt.lvl == MazeLevel.BOT));
// }
//
// else {
// skipUp = false;
// skipDown = false;
// }
for (Stretch str : maze) {
for (int x = 0; x < str.len; x++) { for (int x = 0; x < str.len; x++) {
setBlock(xo + 3 + soFar + x, this.height - 1, Level.GROUND);
setBlock(xo + 3 + soFar + x, this.height - 4, Level.BLOCK_EMPTY);
setBlock(xo + 3 + soFar + x, this.height - 7, Level.BLOCK_EMPTY);
if (x == str.len / 2) { setBlock(xo + soFar + x, this.height - 1, Level.GROUND);
if (str.lvl != MazeLevel.BOT) { // skipUp = (skipUp && (x == str.len - 2))
setBlock(xo + 3 + soFar + x, this.height - 2, // || (str.len >= 5 && x == (str.len / 2));
Level.BLOCK_EMPTY); // skipDown = (skipDown && (x == str.len - 2))
setBlock(xo + 3 + soFar + x, this.height - 3, // || (str.len >= 5 && x == (str.len / 2));
Level.BLOCK_EMPTY); midLine = (str.len >= 5 && x == (str.len / 2) - 1);
} stretchEnd = (x == str.len - 1);
if (str.lvl != MazeLevel.MID) {
setBlock(xo + 3 + soFar + x, this.height - 5, if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.BOT)
Level.BLOCK_EMPTY); // ||
setBlock(xo + 3 + soFar + x, this.height - 6, (midLine && str.lvl != LevelComponent.MazeLevel.BOT) // )
Level.BLOCK_EMPTY); {
} setBlock(xo + soFar + x, this.height - 2, Level.BLOCK_EMPTY);
if (str.lvl != MazeLevel.TOP) { setBlock(xo + soFar + x, this.height - 3, Level.BLOCK_EMPTY);
setBlock(xo + 3 + soFar + x, this.height - 8, }
Level.BLOCK_EMPTY); if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.MID)
setBlock(xo + 3 + soFar + x, this.height - 9, // ||
Level.BLOCK_EMPTY); (midLine && str.lvl != LevelComponent.MazeLevel.MID)// )
setBlock(xo + 3 + soFar + x, this.height - 10, {
Level.BLOCK_EMPTY); setBlock(xo + soFar + x, this.height - 5, Level.BLOCK_EMPTY);
setBlock(xo + 3 + soFar + x, this.height - 11, setBlock(xo + soFar + x, this.height - 6, Level.BLOCK_EMPTY);
Level.BLOCK_EMPTY); }
setBlock(xo + 3 + soFar + x, this.height - 12, if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.TOP)
Level.BLOCK_EMPTY); // ||
setBlock(xo + 3 + soFar + x, this.height - 13, (midLine && str.lvl != LevelComponent.MazeLevel.TOP)// )
Level.BLOCK_EMPTY); {
setBlock(xo + 3 + soFar + x, this.height - 14, setBlock(xo + soFar + x, this.height - 8, Level.BLOCK_EMPTY);
Level.BLOCK_EMPTY); setBlock(xo + soFar + x, this.height - 9, Level.BLOCK_EMPTY);
} setBlock(xo + soFar + x, this.height - 10,
Level.BLOCK_EMPTY);
setBlock(xo + soFar + x, this.height - 11,
Level.BLOCK_EMPTY);
setBlock(xo + soFar + x, this.height - 12,
Level.BLOCK_EMPTY);
setBlock(xo + soFar + x, this.height - 13,
Level.BLOCK_EMPTY);
setBlock(xo + soFar + x, this.height - 14,
Level.BLOCK_EMPTY);
setBlock(xo + soFar + x, this.height - 15,
Level.BLOCK_EMPTY);
}
if (!stretchEnd) {
setBlock(xo + soFar + x, this.height - 7, Level.BLOCK_EMPTY);
}
if (!stretchEnd) {
setBlock(xo + soFar + x, this.height - 4, Level.BLOCK_EMPTY);
} }
} }
soFar += str.len;
} }
setBlock(xo + length - 1, this.height - 1, Level.GROUND);
setBlock(xo + length - 2, this.height - 1, Level.GROUND);
setBlock(xo + length - 3, this.height - 1, Level.GROUND);
return length; return length;
} }
private int buildPipeJump(int xo, int maxLength) { private int buildPipeJump(int xo, int maxLength) {
int numPipes = 4; int numPipes = 4;
int length = numPipes * 2; int length = numPipes * 2;
@@ -461,6 +524,106 @@ public class PCGLevel extends Level {
return length; return length;
} }
private int buildPlatformJump(int xo, int maxLength) {
int length = 0;
int numPlatforms = random.nextInt((maxLength - 3) / 8);
if (numPlatforms > 1) {
boolean found = false;
MazeLevel nextDir = MazeLevel.TOP;
LevelComponent.PlatformLevel last;
LevelComponent.PlatformLevel next;
ArrayList<LevelComponent.PlatformLevel> jumps = new ArrayList<LevelComponent.PlatformLevel>();
int heightMod;
jumps.add(random.nextBoolean() ? LevelComponent.PlatformLevel.BOT
: LevelComponent.PlatformLevel.MID_D);
for (int i = 1; i < numPlatforms; i++) {
last = jumps.get(i - 1);
found = false;
while (!found) {
switch (random.nextInt(5)) {
case 0:
case 1:
nextDir = MazeLevel.BOT;
break;
case 2:
case 3:
nextDir = MazeLevel.TOP;
break;
default:
nextDir = MazeLevel.MID;
}
found = !((last == LevelComponent.PlatformLevel.TOP && nextDir == MazeLevel.TOP) || (last == LevelComponent.PlatformLevel.BOT && nextDir == MazeLevel.BOT));
}
if ((last == LevelComponent.PlatformLevel.BOT && nextDir == MazeLevel.MID)
|| (last == LevelComponent.PlatformLevel.MID_D && nextDir == MazeLevel.BOT)) {
next = LevelComponent.PlatformLevel.BOT;
}
else if ((last == LevelComponent.PlatformLevel.MID_D && nextDir == MazeLevel.MID)
|| (last == LevelComponent.PlatformLevel.MID_U && nextDir == MazeLevel.BOT)
|| (last == LevelComponent.PlatformLevel.BOT && nextDir == MazeLevel.TOP)) {
next = LevelComponent.PlatformLevel.MID_D;
}
else if ((last == LevelComponent.PlatformLevel.MID_U && nextDir == MazeLevel.MID)
|| (last == LevelComponent.PlatformLevel.TOP && nextDir == MazeLevel.BOT)
|| (last == LevelComponent.PlatformLevel.MID_D && nextDir == MazeLevel.TOP)) {
next = LevelComponent.PlatformLevel.MID_U;
}
else // if ((last == PlatformLevel.TOP && nextDir ==
// MazeLevel.MID)
// || (last == PlatformLevel.MID_U && nextDir ==
// MazeLevel.TOP))
{
next = LevelComponent.PlatformLevel.TOP;
}
jumps.add(next);
}
setBlock(xo, this.height - 1, Level.GROUND);
setBlock(xo + 1, this.height - 1, Level.GROUND);
setBlock(xo + 2, this.height - 1, Level.GROUND);
length = 3;
for (int x = 0; x < jumps.size(); x++) {
switch (jumps.get(x)) {
case TOP:
heightMod = 12;
break;
case MID_U:
heightMod = 9;
break;
case MID_D:
heightMod = 6;
break;
default:
heightMod = 3;
}
setBlock(xo + length, this.height - heightMod,
Level.BLOCK_EMPTY);
setBlock(xo + length + 1, this.height - heightMod,
Level.BLOCK_EMPTY);
setBlock(xo + length + 2, this.height - heightMod,
Level.BLOCK_EMPTY);
setBlock(xo + length + 3, this.height - heightMod,
Level.BLOCK_EMPTY);
length += 8;
}
}
return length;
}
private int buildStraight(int xo, int maxLength, boolean safe) { private int buildStraight(int xo, int maxLength, boolean safe) {
int length = random.nextInt(10) + 2; int length = random.nextInt(10) + 2;