2D Array flip vertically and horizontally - java

I have this method that's able to rotate the array by 90 degrees. I want to be to flip vertically and horizontally (I'm binding them with different buttons). Here's the method.
private void Rotate90() {
String[][] temp = new String[totalX][totalY];
for (int y = 0; y < totalY; y++) {
for (int x = 0; x < totalX; x++) {
temp[x][y] = fields[x][y].getText();
}
}
for (int y = 0; y < totalY; y++) {
for (int x = 0; x < totalX; x++) {
fields[x][y].setText(temp[y][x]);
}
}
Draw();
}

#khriskooper code contains an obvious bug: it flips array twice i.e. effectively does nothing. To flip array you should iterate only half of the indices. Try something like this:
private void flipHorizontally() {
for (int y = 0; y < totalY; y++) {
for (int x = 0; x < totalX/2; x++) {
String tmp = fields[totalX-x-1][y].getText();
fields[totalX-x-1][y].setText(fields[x][y].getText());
fields[x][y].setText(tmp);
}
}
}
private void flipVertically() {
for (int x = 0; x < totalX; x++) {
for (int y = 0; y < totalY/2; y++) {
String tmp = fields[x][totalY - y - 1].getText();
fields[x][totalY - y - 1].setText(fields[x][y].getText());
fields[x][y].setText(tmp);
}
}
}

Related

How would i iterate over a 2d array of varying size in Java?

I'm currently creating a brickbreaker (or breakout, like atari breakout) and for the bricks im using a 2d array:
private Brick bricks[][] = new Brick[10][41];
To destroy a specific Brick (for whatever reason i have to destroy that), i created a method:
public void destroyBrick(Brick brick) {
for(int x = 0; x < bricks[x].length; x++) {
for(int y = 0; y < bricks[y].length; y++) {
if (bricks[x][y].equals(brick)) {
bricks[x][y] = null;
}
}
}
}
The way the array is created is the following:
for(int j=0; j<bricks[0].length; j++){
for(int i=0; i<bricks.length; i++){
bricks[i][j]=new Brick(game,10,Color.GREEN,j*margin,i*margin);
}
}
Now for some reason the counter for x eventually reaches 10 and the counter for y reaches 0 where it crashes, and i can't figure out why.
Is there a different way of iterating a 2d array that has different values for columns and rows?
note
The reason the formatting and my spelling is so rubbish is, that im writing this on the app version. Feel free to correct any mistakes or formatting errors, before i can.
You are referencing y in the loop that iterates on it. This compiles correctly, because y is defined at the point of reference, but it does not do what you need. In addition, the outer loop should stop upon reaching bricks.length, not bricks[x].length.
These two lines
for(int x = 0; x < bricks[x].length; x++) {
for(int y = 0; y < bricks[y].length; y++) {
should be
for(int x = 0; x < bricks.length; x++) {
// ^
for(int y = 0; y < bricks[x].length; y++) {
// ^
The first int x doesn't refer to what you need, I think.
x ranges from 0 to the length of the array indexed with x, that is 41.
for (int x = 0; x < bricks.length; x++)
for (int y = 0; y < bricks[x].length; y++)
Should work (at least I wrote this without testing)
Try iterating with any of this
public void destroyBrick(Brick brick) {
for(int x = 0; x < bricks.length; x++) {
for(int y = 0; y < bricks[0].length; y++) {
if (bricks[x][y].equals(brick)) {
bricks[x][y] = null;
}
}
}
}
or
public void destroyBrick(Brick brick) {
for(int x = 0; x < bricks.length; x++) {
for(int y = 0; y < bricks[x].length; y++) {
if (bricks[x][y].equals(brick)) {
bricks[x][y] = null;
}
}
}
}
if there's any other error, use your debugger to find out where exactly

Average value of bytes

I have such a problem. I want to make "average" image from the few diffirent. my idea was to load them to BufferImage sequentially, sum values in each bit, and than just divide by number of photos. The problem is that i can't divide byte[][] by number. What am i doing wrong, or what is the proper way to do this?
File[] others = getOtherImageFiles(file);
byte[][] pixels = new byte[300][];
List<byte[][]> pixelsList = new ArrayList<byte[][]>();
for (int i = 0; i < others.length; i++) {
try {
img = ImageIO.read(others[i]);
} catch (IOException e) {
}
for (int x = 0; x < img.getWidth(); x++) {
pixels[x] = new byte[img.getHeight()];
for (int y = 0; y < img.getHeight(); y++) {
pixels[x][y] = (byte) (img.getRGB(x, y));
}
}
pixelsList.add(pixels);
}
byte[][] pixelsSum = new byte[300][];
for (int i = 0; i < pixelsList.size(); i++) {
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
pixelsSum[x][y] += pixelsList.get(i)[x][y];
}
}
}
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
pixelsSum[x][y]/10;
}
}
}
i want to use them as a face comparer and the point is to create a scheme of faces.
You're close. You did the division by 10, but you never wrote the result back into the pixelsSum array, so the result is lost. You need to do:
pixelsSum[x][y] = pixelsSum[x][y] / 10;
or in shorthand:
pixelsSum[x][y] /= 10;
Another problem you will run into is that each byte in Java (or any other language) can only hold values between 0 and 255. So if you have a bytes x = 255, y = 1, x + y will turn out to be 0. When you add up 10 images, it will almost certainly go over the 255 limit. I suggest changing pixelsSum from byte[][] to int[][], and then turn it back to bytes after you do the division.
Instead of this set of loops:
for (int i = 0; i < pixelsList.size(); i++) {
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
pixelsSum[x][y] += pixelsList.get(i)[x][y];
}
}
}
you should put the pixelsList reference in the middle:
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
for (int i = 0; i < pixelsList.size(); i++) {
pixelsSum[x][y] += pixelsList.get(i)[x][y];
}
pixelsSum[x][y] /= pixelsList.size();
}
}
This should calculate the average immediately rather than looping through the pixelsSum array again. Note also the use of the /= operator which performs both division and assignment compared with the / operator which is limited to division in the context of numbers.

Having problems with a 2d terrain generator in Java

For some reason the blocks keep being rendered in the same position. Can anybody help me?
Block[][] chunk = new Block[Chunk.CHUNK_WIDTH_BLOCKS][Chunk.CHUNK_HEIGHT_BLOCKS];
float[][] positions = new float[Chunk.CHUNK_WIDTH_BLOCKS][Chunk.CHUNK_HEIGHT_BLOCKS];
float frequency = 1.0f / (float) chunk.length;
for (int x = 0; x < chunk.length - 1; x++)
{
for (int y = 0; y < chunk[x].length - 1; y++)
{
positions[x][y] = SimplexNoise.Generate((float) x * frequency, (float) y * frequency);
g.drawRect(positions[x][0], positions[0][y], Block.BLOCK_WIDTH, Block.BLOCK_HEIGHT);
}
}
for (int x = 0; x < Chunk.CHUNK_WIDTH_BLOCKS; x++)
{
for (int y = 0; y < Chunk.CHUNK_HEIGHT_BLOCKS; y++)
{
if (positions[x][y] < 0f)
chunk[x][y] = new Block();
if (positions[x][y] >= -0f)
chunk[x][y] = new Block();
}
}
You have multiple problems with your code. For instance:
for (int x = 0; x < chunk.length - 1; x++)
That should be:
for (int x = 0; x < chunk.length; x++)
Also, consider the following:
g.drawRect(positions[x][0], positions[0][y], Block.BLOCK_WIDTH, Block.BLOCK_HEIGHT);
That will not use all values in "positions[x][y]".... I think that what you will want is for the array to be 3d... for instance:
float[][][] positions = new float[Chunk.CHUNK_WIDTH_BLOCKS][Chunk.CHUNK_HEIGHT_BLOCKS][2];
That way: posistions[x][y][0] is the value for x, and positions[x][y][1] is the value for y....
g.drawRect(positions[x][y][0], positions[x][y][1], Block.BLOCK_WIDTH, Block.BLOCK_HEIGHT);
I am not sure I understand your code exactly, but it does seem to have issues.

2D game design - y variable not resolved?

I have my code as the following.
package net.ferrell.wrathoftuemdaym;
import java.awt.*;
public class Level {
public Block[][] block = new Block[50][50];
public Level() {
for(int x = 0; x < block.length; x++) {
for(int y = 0; y < block[0].length; y++);
block[x][y] = new Block(new Rectangle(x * Tile.tileSize, y * Tile.tileSize, Tile.tileSize, Tile.tileSize), Tile.air);
}
}
public void generateLevel() {
for(int x = 0; x < block.length; x++) {
for(int y = 0; y < block[0].length; y++);
if(x == 0 || y == 0 || x == block.length-1 || y == block[0].length-1) {
block[x][y].id = Tile.earth;
}
}
}
public void tick() {
}
public void render(Graphics g) {
for(int x = 0; x < block.length; x++) {
for(int y = 0; y < block[0].length; y++);
block[x][y].render(g);
}
}
}
In a line that says " block[x][y] ", y cannot be resolved to a variable. I do not know the fix for this and it is only in this class that the problem exists. Please help me. I do not understand because the x CAN be resolved...
this is your culprit
for(int y = 0; y < block[0].length; y++);
it should be
for(int y = 0; y < block[0].length; y++)
Personally I always put braces in code blocks even if it is just one line.

Turning a 1-D Array into a 2-D Array

I am trying to take an array that contains 400 integers, and split it into a 20x20 2-D array. I thought I had the right algorithm, but the sum of the 1-D array does not match the sum of the 2-D array, so I’m obviously doing something wrong. Here is my code:
private static void processArray(int[] inArray)
{
int[][] array = new int[20][20];
for (int x = 0; x < 20; x++)
{
for (int y = 0; y < 20; y++)
{
for (int z = 0; z < 400; z++)
{
array[x][y] = inArray[z];
}
}
}
}
What am I doing wrong?
For each pair of x and y, your code assigns every value from inArray to array[x][y]. This is clearly incorrect.
Here is one way to fix the code:
private static void processArray(int[] inArray)
{
int[][] array = new int[20][20];
for (int x = 0, z = 0; x < 20; x++)
{
for (int y = 0; y < 20; y++)
{
array[x][y] = inArray[z++];
}
}
}
You're assigning the last element in the input array to every element in the output array. The inner loop over the input array must be changed into a single assignment that picks the correct input element.
private static void processArray(int[] inArray)
{
int[][] array = new int[20][20];
for (int x = 0; x < 20; x++)
{
for (int y = 0; y < 20; y++)
{
array[x][y] = inArray[x * 20 + y]; // or devise your own calculation
}
}
}
The current approach will assign each element in the array with the last element in the original.
You should not iterate z but use it as a counter, in the same loops.
int z = 0;
for (int x = 0; x < 20; x++)
{
for (int y = 0; y < 20; y++)
{
array[x][y] = inArray[z++];
}
}
You're basically assigning array[x][y] equal to inArray[0], then inArray[1], then inArray[2], all the way to [400].
I would do something like
private static void processArray(int[] inArray)
{
int[][] array = new int[20][20];
for (int x = 0; x < 20; x++)
{
for (int y = 0; y < 20; y++)
{
array[x][y] = inArray[x * 20 + y];
}
}
}

Categories