Looping through a 3x3 cube - java

I am coding a mod for minecraft, and was confronted by a confusing math problem.
I want to find the ID of all blocks around a center block.
To do this I wanted to loop through a 3x3 square of blocks and return which ones are the blocks I want.
The parameters I have to work with are the X, Y and Z coords.
I'm guessing the best bet would be to use 3 for loops, one for each axis, right?

for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
for(int k = 0; k < 3; k++){
//do something
}
}
}

Related

Java for loops while keeping variable within a range

Im trying to run a two for loops that iterate over something like colored large square (for example 300x300) and replacing it with the colors(or pixels) of a smaller square (say 100x100) which is what k and l represent.
Essentially, I was wondering how to keep k and l running between 0-100 and restarting once it hits 100, but also keep i and j running the whole time. I tried used 4 nested for loops but it did not work properly, although I'm starting to think that may be a solution, but that would be very inefficient.
Please let me know if this sounds a little confusing I will try my best to explain more clearly, thanks.
excuse the psuedocode
for (i=0; i < width; i++)
for (j=0; i< height; j++)
set(i, j , pixel(k,l));
The problem seems to be to tile an image onto another image. You have width and height for the target image's dimensions, so let's say sourceWidth and sourceHeight are the source image's dimensions (100 by 100, in your example).
To tile an image, you want k == i % sourceWidth and l == j % sourceHeight, so that the pixel you read from the source image "wraps around" the boundaries. These should be invariant conditions. The simplest way to satisfy them is to declare them that way directly:
for(int i = 0; i < width; ++i) {
int k = i % sourceWidth;
for(int j = 0; j < height; ++j) {
int l = j % sourceHeight;
set(i, j, pixel(k, l));
}
}
This does a lot of % operations, which could be quite inefficient, but it gives us a correct piece of code to transform. If we are incrementing k and l, then there are two properties needed to maintain the invariants:
k and i are incremented in unison; and l and j are incremented in unison.
When k reaches sourceWidth it must wrap back to 0, likewise for l and sourceHeight.
for(int i = 0, k = 0; i < width; ++i, ++k) {
if(k == sourceWidth) { k = 0; }
for(int j = 0, l = 0; j < height; ++j, ++l) {
if(l == sourceHeight) { l = 0; }
set(i, j, pixel(k, l));
}
}
Note that the for loop initialiser and stepper now declare and update two variables, for both loops. This is allowed in Java.
This is likely to be faster than doing a lot of % operations, but note that branching with if statements can also slow down an algorithm, so you may want to benchmark it to be sure.
In the special case where source image's dimensions are powers of two, we can achieve the same result with a fast bitwise operation: i % sourceWidth will be equivalent to i & (sourceWidth - 1):
// special case: sourceWidth and sourceHeight are powers of 2
int wMask = sourceWidth - 1, hMask = sourceHeight - 1;
for(int i = 0, k = 0; i < width; ++i, ++k) {
for(int j = 0, l = 0; j < height; ++j, ++l) {
set(i, j, pixel(i & wMask, j & hMask));
}
}
It could be done by something like this:
for (i = 0; i < width; i++) {
for (j = 0; j < height; j++) {
if(k > 100) {
k = 0;
}
if(l > 100) {
l = 0;
}
k++;
l++;
set(i, j , pixel(k,l));
}
}

Trouble filling 2D array with values obtained from method

I'm having trouble filling a matrix with values I get by iterating through a method. I want to use a 3x3 matrix and then fill it with the values I obtain by iterating my method from 0 to 8. My idea was a for-loop but it does not work unfortunately. I would be glad if someone could help or has a link where I can look that up.
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++){
for (int j = 0; j < matrix[i].length; j++){
for(int a = 0; a < 9; a++) {
matrix[i][j] = fields.get(a).getSign().getFieldValue();
}
}
}
Correct me if I'm wrong.
The way I understood your question was you want to fill the matrix like this:
012
345
678
In that case you can do the first 2 forloops and add some maths, to get the correct numbers on every position:
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = i * matrix[i].length + j;
}
}
The way this works is for every row (i) you multiply the rownumber by the rows length (the number of columns) and add the current column to it
To iterate through a two dimensional field (e.g. a matrix), you can use two for loops:
int dimension = 3;
int [][] matrix = new int [dimension][dimension];
for (int i = 0; i < dimension; i++){
for ( int j = 0; j < dimension; j++){
matrix[i][j] = fields.get(i).get(j);
}
}
I don't exactly know how you want to retrieve the values, but your current call looks suspicious to say the least :-)
It will simply assign the same value to all ints in column j.
If you simulate your loop, this is what it looks like
i -> 0
j -> 0
matrix[0][0] -> loop over all values from field
this way you would be putting the fields.get(8) into each index in your matrix.
#Alan's answers show how to properly loop and fill a 2d matrix from a 1d matrix

Matrix -> blocks division

I want to load some matrix into my program and then I want to divide it into smaller blocks.
What I want exactly can be seen on an image below:
http://postimg.org/image/aki19hjx9/ba463111/
In red squares are 3 examples of my "blocks" in which I would like to divide whole matrix. In this case each block should be (smaller) 3x3 matrix. I know how to load it into 2d array, but what should I do then?
int[][] bigMatrix = new int[9][9];
// initialize bigMatrix
int[][][] smallMatrices = new int[3][3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
smallMatrices[i][j][k] = bigMatrix[3*i+j][3*i+k];
}
}
}
// The submatrices are now in smallMatrices[i], 0 <= i < 3

2D array printing letters in middle of grid in forward direction

public void fill(ArrayList<String> a1) {
int i = 0;
while (i < a1.size()) {
if (i == 0) {
for (int j = 0; j < a1.get(i).length(); j++)
crossword[ROWS / 2][(COLUMNS / 4) + j] = a1.get(i)
.charAt(j);
i++;
}
if (i == 1) {
outerloop: for (int t = 0; t < ROWS; t++)
for (int s = 0; s < COLUMNS; s++)
for (int j = 0; j < a1.get(i).length(); j++)
if (crossword[t][s] == a1.get(i).charAt(j)) {
for (int z = 0; z < j; z++)
crossword[t - z - 1][s] = a1.get(i).charAt(
z);
for (int h = j + 1; h < a1.get(i).length(); h++)
crossword[t + h - j][s] = a1.get(i).charAt(
h);
crossword[t][s] = a1.get(i).charAt(j);
break outerloop;
}
i++;
}
}
}
The above is my method to make the first two words of a list of words intersect each other on a crossword puzzle board. My question is for the part:
for (int z = 0; z < j; z++)
crossword[t - z - 1][s] = a1.get(i).charAt(z);
It takes the letters in front of the intersection point and prints them backwards above the intersection row. My brain is overloaded with different things right now and I can't seem to understand how to make the letters go in the right order. I can't attach an image to display my problem but for example the vertical word "throwing" which intersects with horizontal word "clowning" at the letter "o" prints out "rht" before the o (when it should be printing out "thr"). Could someone help? Would be much appreciated!
This will do the trick:
for (int z = 0; z < j; z++)
crossword[t - j + z][s] = a1.get(i).charAt(z);
P.S. This question hasn't been closed yet (even though you did respond to your question). You should flag this answer (or, if you don't feel like giving me points, an answer that you put in) as correct, so that the question doesn't remain in the unanswered section!

Java loop over half of array

I would like to loop over half of an array in Java; this is because the matrix will be completely symmetric. If I loop throw i columns and j rows, every time I do an operation of matrix[i][j] I will do the exact same operation to matrix[j][i]. I should be able to save time by not looping over half of the matrix. Any ideas on the easiest way to do this?
If you're trying to get a triangle:
for(int i=0; i<array.length; i++){
for(int j=0; j<=i; j++){
..do stuff...
}
}
for (i = 0;i < size; ++i) {
for (j = 0; j < i; ++j) {
result = do_operation(i,j);
matrix[i][j] = result;
matrix[j][i] = result ;
}
}
So you invoke the operation method do_operation only once for each pair.
for(int i = 0; i<array.length; i++){
for(int j = 0; j < array[i].length - i; j++){
// operation here
}
}
Maybe I'm missing something here, but let's say you have two arrays representing your rows and columns respectively, and assuming that it's symmetric (as you say):
int dimension = rows.Length;
for(int i=0; i<dimension; i++)
{
int j = (dimension-1) - i; //need dimension-1 to avoid an off-by-one error
DoSomething(matrix[i][j]);
DoSomehting(matrix[j][i]);
}
This solution has the runtime complexity benefit of only iterating over one loop as opposed to two.

Categories