in Minecraft/src/main/java/com/microsoft/Malmo/MissionHandlers/ClassroomDecoratorImplementation.java [305:426]
private ArrayList<Room> createRooms() throws DecoratorException
{
// we will set up the different building dimensions and then split them up sequentially
ArrayList<Thickness> widths = new ArrayList<Thickness>();
ArrayList<Thickness> lengths = new ArrayList<Thickness>();
ArrayList<Thickness> heights = new ArrayList<Thickness>();
widths.add(new Thickness(START_X, START_X + this.buildingWidth));
heights.add(new Thickness(START_Y, START_Y + ROOM_HEIGHT));
lengths.add(new Thickness(START_Z, START_Z + this.buildingLength));
// we will keep sampling the divisions until we are unable to accomplish the
// goal. This has the effect of making it so that we still see simpler structures even
// in more complex vectors and effectively keep sampling the larger space of buildings.
while(true){
Division div = Division.fromOrdinal(this.isSpec ? this.divisionTypeDist.take() : this.divisionTypeDist.sample());
if(div == Division.AboveBelow){
// floors are tricky as they have fixed height, so we just
// stack them on top of each other until we run out of room.
Thickness topFloor = heights.get(heights.size() - 1);
if(topFloor.end + FLOOR_HEIGHT + ROOM_HEIGHT > START_Y + this.buildingHeight){
break;
}
heights.add(new Thickness(topFloor.end + FLOOR_HEIGHT, topFloor.end + ROOM_HEIGHT + FLOOR_HEIGHT));
}else{
ArrayList<Thickness> thicknesses;
if(div == Division.SouthNorth){
thicknesses = lengths;
}else if(div == Division.EastWest){
thicknesses = widths;
}else{
throw new DecoratorException("Invalid division value: " + div);
}
// we need to see which thicknesses are able to be split. we then will
// performed a biased sample by potential split location.
int[] counts = new int[thicknesses.size()];
int sum = 0;
for(int i=0; i<counts.length; i++){
counts[i] = Math.max(0, thicknesses.get(i).getThickness() - (MIN_ROOM_SIZE * 2));
sum += counts[i];
}
if(sum == 0){
break;
}
Discrete dist = new Discrete(this.rand, counts);
int index = dist.sample();
Thickness start = thicknesses.get(index);
int thickness = this.isSpec ? MIN_ROOM_SIZE : MIN_ROOM_SIZE + this.rand.nextInt(Math.min(3, counts[index]));
Thickness end = new Thickness(start.start + thickness + 1, start.end);
start.end = end.start - 1;
thicknesses.add(index + 1, end);
}
}
// create rooms
ArrayList<Room> rooms = new ArrayList<Room>();
Room[][][] roomGrid = new Room[heights.size()][][];
for(int i=0; i<heights.size(); i++){
roomGrid[i] = new Room[widths.size()][];
Thickness height = heights.get(i);
for(int j=0; j<widths.size(); j++){
roomGrid[i][j] = new Room[lengths.size()];
Thickness width = widths.get(j);
for(int k=0; k<lengths.size(); k++){
Thickness length = lengths.get(k);
Room room = new Room(width.start, height.start, length.start,
width.getThickness(), height.getThickness(), length.getThickness());
roomGrid[i][j][k] = room;
rooms.add(room);
}
}
}
// set up walls
for(int i=0; i<roomGrid.length; i++){
for(int j=0; j<roomGrid[i].length; j++){
for(int k=0; k<roomGrid[i][j].length; k++){
Room room = roomGrid[i][j][k];
if(i == 0){
room.belowFloor = new Floor(room, null);
}
if(j == 0){
room.westWall = new EWWall(room, null);
}
if(k == 0){
room.northWall = new SNWall(room, null);
}
if(i < roomGrid.length - 1){
Room above = roomGrid[i+1][j][k];
room.aboveFloor = above.belowFloor = new Floor(above, room);
}else{
room.aboveFloor = new Floor(null, room);
}
if(j < roomGrid[i].length - 1){
Room east = roomGrid[i][j+1][k];
room.eastWall = east.westWall = new EWWall(east, room);
}else{
room.eastWall = new EWWall(null, room);
}
if(k < roomGrid[i][j].length -1){
Room south = roomGrid[i][j][k+1];
room.southWall = south.northWall = new SNWall(south, room);
}else{
room.southWall = new SNWall(null, room);
}
}
}
}
return rooms;
}