private ArrayList createRooms()

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;
    }