Functional context-free grammar! Worked first time! Well... almost.

This commit is contained in:
Woody Folsom
2012-03-18 08:09:53 -04:00
parent 9ce8685b74
commit b431d5efeb
5 changed files with 63 additions and 91 deletions

View File

@@ -21,7 +21,8 @@ public class PCGLevel extends Level {
public static int COIN_REWARD = 1;
public static int POWERUP_REWARD = 2;
public static boolean TESTING = true;
// disable TESTING - enable grammar-based level generation
public static boolean TESTING = false;
public static long lastSeed;
private static Random levelSeedRandom = new Random();
@@ -181,38 +182,32 @@ public class PCGLevel extends Level {
for (LevelComponent lcomp : levelTemplate) {
LevelComponent.TYPE lctype = lcomp.getType();
System.out.println("Building for: " + lcomp);
switch (lctype) {
case FLAT_LO:
case FLAT_HI:
length += buildStraight(length, lcomp.getEnd(), true);
break;
case PIPE_JUMP:
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);
while (length < Math.min(width - 64, lcomp.getEnd())) {
switch (lctype) {
case FLAT_LO:
case FLAT_HI:
length += buildStraight(length, lcomp.getEnd(), true);
break;
case PIPE_JUMP:
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 while (length < width - 64) {
* length += buildStraight(length, width - length, true); }
*/
// set the end piece
int floor = height - 1 - random.nextInt(4);
@@ -1187,71 +1182,10 @@ public class PCGLevel extends Level {
: Level.BLOCK_COIN);
}
}
// if (!safe) {
// if (length > 5) {
// decorate(xo, xo + length, floor);
// }
// }
return length;
}
// private void decorate(int xStart, int xLength, int floor) {
// // if its at the very top, just return
// if (floor < 1)
// return;
//
// // boolean coins = random.nextInt(3) == 0;
// boolean rocks = true;
//
// // add an enemy line above the box
// addEnemyLine(xStart + 1, xLength - 1, floor - 1);
//
// int s = random.nextInt(4);
// int e = random.nextInt(4);
//
// if (floor - 2 > 0) {
// if ((xLength - 1 - e) - (xStart + 1 + s) > 1) {
// for (int x = xStart + 1 + s; x < xLength - 1 - e; x++) {
// setBlock(x, floor - 2, COIN);
// COINS++;
// }
// }
// }
//
// s = random.nextInt(4);
// e = random.nextInt(4);
//
// // this fills the set of blocks and the hidden objects inside them
// if (floor - 4 > 0) {
// if ((xLength - 1 - e) - (xStart + 1 + s) > 2) {
// for (int x = xStart + 1 + s; x < xLength - 1 - e; x++) {
// if (rocks) {
// if (x != xStart + 1 && x != xLength - 2
// && random.nextInt(3) == 0) {
// if (random.nextInt(4) == 0) {
// setBlock(x, floor - 4, BLOCK_POWERUP);
// BLOCKS_POWER++;
// } else { // the fills a block with a hidden coin
// setBlock(x, floor - 4, BLOCK_COIN);
// BLOCKS_COINS++;
// }
// } else if (random.nextInt(4) == 0) {
// if (random.nextInt(4) == 0) {
// setBlock(x, floor - 4, (byte) (2 + 1 * 16));
// } else {
// setBlock(x, floor - 4, (byte) (1 + 1 * 16));
// }
// } else {
// setBlock(x, floor - 4, BLOCK_EMPTY);
// BLOCKS_EMPTY++;
// }
// }
// }
// }
// }
// }
private void fixWalls() {
boolean[][] blockMap = new boolean[width + 1][height + 1];

View File

@@ -41,4 +41,19 @@ public class AndClause implements Clause {
public boolean isVariable() {
return false;
}
@Override
public String toString() {
if (subClauses.size() == 0) {
return "(Empty AND clause)";
}
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0; i < subClauses.size() - 1; i ++) {
sb.append(subClauses.get(i).toString());
sb.append(" AND ");
}
sb.append(subClauses.get(subClauses.size()-1).toString());
sb.append(")");
return sb.toString();
}
}

View File

@@ -15,8 +15,8 @@ public class LevelGrammarFactory {
Variable v_HI_LO = new Variable("HI_LO", LevelComponent.TYPE.HI_LO);
Variable v_LO_PATH = new Variable("LO_PATH", LevelComponent.TYPE.LO_PATH);
Variable v_HI_PATH = new Variable("HI_PATH", LevelComponent.TYPE.HI_PATH);
Variable v_lo_path = new Variable("lo_path", LevelComponent.TYPE.LO_PATH);
Variable v_hi_path = new Variable("hi_path", LevelComponent.TYPE.HI_PATH);
Variable v_lo_path = new Variable("lo_path", LevelComponent.TYPE.FLAT_LO);
Variable v_hi_path = new Variable("hi_path", LevelComponent.TYPE.FLAT_HI);
grammar.addVariable(v_START);
grammar.addVariable(v_LAND_SEGMENT);

View File

@@ -56,4 +56,21 @@ public class OrClause implements Clause {
public boolean isVariable() {
return false;
}
@Override
public String toString() {
if (subClauses.size() == 0) {
return "(Empty OR clause)";
}
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0; i < subClauses.size() - 1; i ++) {
sb.append(subClauses.get(i).toString());
sb.append(" OR ");
}
sb.append(subClauses.get(subClauses.size()-1).toString());
sb.append(")");
return sb.toString();
}
}

View File

@@ -1,11 +1,13 @@
package dk.itu.mario.level.grammar;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import dk.itu.mario.level.LevelComponent;
public class ParseNode {
private static final DecimalFormat FORMATTER = new DecimalFormat("###.00");
private LevelComponent.TYPE levelCompType;
private double percentLength;
private List<ParseNode> children = new ArrayList<ParseNode>();
@@ -59,4 +61,8 @@ public class ParseNode {
public void setPercentLength(double percentLength) {
this.percentLength = percentLength;
}
public String toString() {
return levelCompType + " (" + FORMATTER.format(percentLength * 100) + "%)";
}
}