Resizing a 2D array of objects

Hi

For my game’s map system I have a 2D array of [icode]Block[/icode] objects. I would like to resize/trim the array of null/empty rows and columns. Here is my current code, which doesn’t work :confused:


   Block[][] clone = worldBlocks.clone();
		int maxX = 0, maxY = 0;
		for(Block[] row : clone){
			if(row != null){
				maxX = 0;
				for(Block block : row){
					if(block != null){
						maxX++;
					}
				}
				maxY++;
			}
		}
		Block[][] refreshed = new Block[maxY][maxX];
		for(int y = 0; y < maxY; y++){
			for(int x = 0; x < maxX; x++){
				refreshed[y][x] = clone[y][x];
			}
		}
		worldBlocks = refreshed.clone();

This code should remove any null rows and columns, but it doesn’t :slight_smile: Any thoughts or fixes would be appreciated :slight_smile:

CopyableCougar4

refreshed[ y ][ x ] = clone[ y ][ x ];

I think this is where your issues is, you are not ‘skipping’ your initial blank positions.

I will try and give you an example,

You have a single dimension array of 1s, 0s.

Like {0,0,1,1,0,0,1}

What you work out in your code is the number of 1s. So 3 in this example, then what you are currently doing is getting the first 3 entries in your code. So you will end up with,

{0,0,1}. Which is not what you seem to want.

Hi

I should probably explain more.

I create an array 10x10 just so that I won’t run out of room, and then I want to shrink it so that there are no empty elements. Initially the array looks like this:


1 1 1 1 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0

But I want it to be like this:


1 1 1 1
1 1 1 1

Hope this makes it more clear :slight_smile:

CopyableCougar4

I have a feeling you’re doing something kinda hacky elsewhere if this is how you’re setting up your block objects.

But, you can try this hacky code here:

byte [][] oldArray = new byte[10][10]
int rows = 0;
int col = 0;

for (int x = 0; x < oldArray.length; x++) {
	for (int y = 0; y < oldArray[x].length; y++) {
		if (oldArray[x][y] == 1){
			row = x;
			col = y;
		}
	}
}

byte[][] newArray = new byte[row][col];
for (int x = 0; x < newArray[].length; x++) {
	Arrays.fill(newArray[], 1);
}

Totally untested code (and really hacky, you shouldn’t really be doing this at all), but in theory it’ll output a new array full of 1s, in the new size. Keep in mind it will only work for rectangle shapes.

Do you want to trim the array, or remove all nulls?

Hi

This is how I read in my map data:


   public WorldReader(File file){
		ArrayList<String> lines = readFileToList(file);
@@		world = new World(10, 10); // Allocate space for 100 blocks
		int y = 0, x = 0;
		Block activeBlock = null;
		int blockX = -1, blockY = -1, width = -1, height = -1;
		Tile[][] tilemap = null;
		loop:
		for(String line : lines){
			if(line.startsWith("-------")){
				if(activeBlock != null){
					activeBlock.setTilemap(tilemap);
					world.setBlock(blockX, blockY, activeBlock);
					activeBlock = null;
				}
				String blockInfo = line.substring(7, line.length());
				if(blockInfo.length() <= 0){
					break loop;
				}
				String[] blockData = blockInfo.split(",");
				String blockName = blockData[0];
				blockX = Integer.parseInt(blockData[1]);
				blockY = Integer.parseInt(blockData[2]);
				width = Integer.parseInt(blockData[3]);
				height = Integer.parseInt(blockData[4]);
				tilemap = new Tile[height][width];
				activeBlock = new Block(blockName);
				continue loop;
			}
			x = 0;
			for(String statement : line.split(" ")){
				String layer1 = statement.substring(0, 1);
				int tileID = Integer.parseInt(layer1);
				Tile tile = TileRegistry.getMap().get(tileID);
				tilemap[y][x] = tile;
				x++;
			}
			y++;
		}
@@		world.trim(); // Trim null rows and columns
		System.out.println(world.getWidth() + "x" + world.getHeight());
	}

This is why I have to have hacky world code, because I don’t know how big the array will be until AFTER the whole file has been read/parsed.

CopyableCougar4

Simple: change your file format to include a header row that tells you the dimensions, and walk away from all this hackiness.

Hi

I suppose that would work :stuck_out_tongue:

CopyableCougar4

That, or even use a List<List> as you parse, and use toArray() when done filling it with blocks.

Hi

So I added that one line about the block dimensions and it solved my problem :slight_smile: Why do the easiest solutions evade me so often? :slight_smile:

CopyableCougar4