I have two arrays that I create like this:
public int GameBoard[][] = new int[30][14];
public int DirectionMap[][] = new int[30][14];
I then initialize the arrays like this:
for (int i = 0; i < GameBoard.length; i++)
{
for (int j = 0; j < GameBoard[i].length; j++)
{
GameBoard[i][j] = 0;
}
}
... //Same for DirectionMap
When I run the function:
DirectionMap = AStar(GameBoard);
To render the pathfinding map that my units will follow, DirectionMap is correctly set to the values generated based on my GameBoard. However GameBoard is set to the result as well. When I run the application in Debug Mode within Eclipse, I can see that the ID's of the two arrays are the same. For some reason they seem to be pointing to the memory space. My AStar function does not modify the GameBoard array at all. The only reference to it is int retVal[][] = GameBoard;
My function prototype is public int[][] AStar(int[][] Board); and it returns the int[][] retVal.
I have no idea why I cannot change the values of DirectionMap without GameBoard following. I have never had any issues like this before.
Any ideas are really appreciated. Thanks for your help.
public int[][] AStar(int[][] Board)
{
int retVal[][] = Board;
//Initialize All Needed Lists
int width = retVal.length;
int height = retVal[0].length;
int goalX = 0;
int goalY = 0;
//List<Node> fieldInfo = new ArrayList<Node>();
Node fieldArray[][] = new Node[width][height];
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
fieldArray[i][j] = new Node(i, j);
if (retVal[i][j] == 2)
{
fieldArray[i][j].setOpen(1);
fieldArray[i][j].setDirection(10); //Set as target
goalX = i;
goalY = j;
}
if (retVal[i][j] == 1)
{
fieldArray[i][j].setOpen(0);
fieldArray[i][j].setDirection(9); //Set as wall
}
}
}
//Add AStar Algorithm Here
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
if (fieldArray[i][j].getDirection() == 0)
{
//Occurs when node was never reached
int dX = i - goalX;
int dY = j - goalY;
if (dX < 0)
dX = -dX;
if (dY < 0)
dY = -dY;
if (dY > dX)
fieldArray[i][j].setDirection(1);
else
{
if (i > goalX)
fieldArray[i][j].setDirection(7);
if (i < goalX)
fieldArray[i][j].setDirection(3);
}
}
}
}
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
retVal[i][j] = fieldArray[i][j].getDirection();
}
}
return retVal;
}
Remember when you are passing an object to methods you are actually passing a copy of reference. So when you initialise retVal[][] = Board; you actually point Board using another reference retVal. And you are returning the same reference to DirectionMap. Hence same id's for Board and DirectionMap. Consider array copy instead.
I can see that the ID's of the two arrays are the same. For some
reason they seem to be pointing to the memory space
The int[] array in Java has 0's as default values.
int[] x = new int[2];
System.out.println(x[0]); // prints 0
System.out.println(x[1]); // prints 0
The only reference to it is int retVal[][] = GameBoard;
Java arrays are objects. If at any point you are setting array = array, you are setting one reference to point to the same object as the other.
Related
I'm trying to check whether an array of arrays has any duplicate values. The end goal would be an if statement saying:
if (arr does NOT have duplicate values) {continue code}
int [][] arr = new int[3][2];
int [] x = new int[1];
arr[0][0] = 1;
arr[0][1] = 1;
arr[1][0] = 1;
arr[1][1] = 2;
arr[2][0] = 1;
arr[2][1] = 2;
x = arr.getUnique(); /I assume it'll use getUnique() but I can't even get that to work
Any help would be awesome! Thanks
Java has a HashSet you can use to have a collection without duplicates.
Find a way to convert your array into a HashSet and compare the number of their elements. If they have the same number of elements, each element in your array is unique, if the HashSet is smaller, it means some duplicates have been removed.
You could create a helper function of your own like this:
private static boolean arrayHasDuplicates(int[][] arr) {
for (int i = 0; i < arr.length; i++)
{
for (int y = 0; y < arr.length; y++)
{
if (arr[i].length != arr[y].length) continue;
if (i == y) continue;
boolean same = true;
for (int x = 0; x < arr[y].length; x++)
{
if (arr[i][x] != arr[y][x]) {
same = false;
break;
}
}
if (same) return same;
}
}
return false;
}
I want to Fill a 2D-Array with Javafx Labels in Which I can change the Text when I click it.
This is my actual Code but it's returning a NullPointer Exception.
Blockquote
`public static Label[][] initWelt() {
Label[][] welt = new Label[DIM1][DIM2];
for (int x = 1; x < welt.length - 1; x++) {
for (int y = 1; y < welt.length - 1; y++) {
if (Math.random() > 0.4) {
welt[x][y].setText("X");
}
else{
welt[x][y].setText(" ");
}
}
}
return welt;
}`
it's returning a NullPointer Exception.
The only thing the below code does is initialise a two-dimensional array, it doesn't populate the two-dimensional array, hence the NullPointerException occurs.
Label[][] welt = new Label[DIM1][DIM2];
Basically you can't call this:
welt[x][y].setText("X");
without populating the two-dimensional array with object references.
to overcome the problem first populate the two dimensional array, something like below:
Label[][] welt = new Label[DIM1][DIM2];
for(int i = 0; i < DIM1; i++){
for(int j = 0; j < DIM2; j++){
welt[i][j] = new Label();
}
}
then you can proceed with your current task at hand.
so now your code becomes like this:
public static Label[][] initWelt() {
Label[][] welt = new Label[DIM1][DIM2];
for(int i = 0; i < DIM1; i++){ //populate the array
for(int j = 0; j < DIM2; j++){
welt[i][j] = new Label();
}
}
for (int x = 0; x < DIM1; x++) {
for (int y = 0; y < DIM2; y++) {
if (Math.random() > 0.4) {
welt[x][y].setText("X");
}
else{
welt[x][y].setText(" ");
}
}
}
return welt;
}
Note - personally I think it would be better to refactor the current method and insert the code that populates the two-dimensional array in a different method.
I'm supposed to create an image editor using 2D arrays. For this part I'm supposed to create code that creates a mirror of the image by flipping it left to right. Instead I'm flipping it upside down. What am I doing wrong?
public void mirror() {
// TODO Auto-generated method stub
int[] img;
int left = 0, right = data.length -1;
while (right >= left) {
img = data[left];
data[left++] = data[right];
data[right--] = img;
}
}
Multiple Problems:
1. You're using a 1D Array.
2. data.length on 1d array gives you number of rows.
3. Now when you use data.length for reversing, you end up revering rows instead of columns in 2d array.
Hence your logically incorrect output.
Use mirror method should be something like this -
public int[][] mirror(int[][] original) {
int[][] mirror = original;
for (int i=0; i<original.length; i++) {
original[i] = reverseArray(original[i]);
}
return mirror;
}
public int[] reverseArray(int[] array) {
for (i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
return array;
}
The problem is you were just mirroring the arrays that made up the matrix, rather than reversing the order of the arrays. Assuming data was in fact a 2D array to begin with, this should work for you.
public void mirror() {
for (int i = 0; i < data.length; i++){
for (int j = 0; j < data[i].length/2; j++){
int temp = data[i][j];
data[i][j] = data[i][data[i].length-j-1];
data[i][data[i].length-j-1] = temp;
}
}
}
A more simple way than the other answers in my opinion:
int[][] mirrored = new int[data.length][data[0].length];
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
mirrored[i][data[i].length - j - 1] = data[i][j];
}
}
So. I have a problem I simply cant get my head around.
I'm currently making a cellular automaton. (Java)
For this, I have 2 Arrays, one called cells[][] for current states,
and one called cellsX[][] for the temporary state inbetween steps.
at each update i do this:
public void updateCells() {
cellsX = cells;
for(int i = 0; i< Xsize; i++) {
for(int j = 0; j < Ysize; j++) {
cellsX[i][j].Update();
}
}
}
And later I render:
for(int i = 0; i< Xsize; i++) {
for(int j = 0; j < Ysize; j++) {
if(cells[i][j].isAlive()) {
int Colori[] = cells[i][j].GetColor();
g2d.setTransform(identity);
g2d.translate(0, 0);
g2d.setColor(new Color(Colori[0],Colori[1],Colori[2]));
g2d.drawRect((i*5)+20, (j*5)+20, 5, 5);
}
}
}
Right now, I would say nothing should happen, as I newer update cells[][]
but for some reason it do?
How can the cells[i][j] update, when the only cell I've given a command is cellsX[i][j]?
to show you the Update function in the Cell
public void Update() {
if(Info[0][0] > 0) {
Info[0][0] += 1;
Info[0][2] += rand.nextInt(2);
}
Info[1][0] ++;
if(Info[1][0] >255) Info[1][0] =0;
if(Info[0][0] > Info[0][1]) Info[0][0] = 0;
if(Info[0][2] <= 0) Info[0][0] = 0;
}
Its a void an no nothing to affect the outside world (Info[][] is an int array used to store data such as life and color (Info[1][0] is the red color)
I have no idea how the H. i can mess up. the creation of the cells and cellsX is
int Xsize = 100;
int Ysize = 100;
Cell[][] cells = new Cell[Xsize][Ysize];
Cell[][] cellsX = new Cell[Xsize][Ysize];
and initialized:
for(int i = 0; i< Xsize; i++) {
for(int j = 0; j < Ysize; j++) {
cellsX[i][j] = new Cell();
}
}
for(int i = 0; i< Xsize; i++) {
for(int j = 0; j < Ysize; j++) {
cells[i][j] = new Cell();
}
}
Sorry for the wall of text...
I just can't figure out how cells get's updated :S
From your comment -
"How should this not give me 2 2d arrays, one called cells and another
called cells X"
You do it's just that they equal each other here - cellsX = cells; Consider, and run/watch, this simple example...
public static void main(String[] args){
int size = 5;
int foo[][] = new int[size][size];
int bar[][] = new int[size][size];
for(int i = 0; i < size; ++i) {
for(int j =0; j < size; ++j) {
System.out.print(foo[i][j] + " ");
}
}
System.out.println();
foo = bar;
for(int i = 0; i < size; ++i) {
for(int j = 0; j < size; ++j) {
bar[i][j] = j;
}
}
for(int i = 0; i < size; ++i) {
for(int j =0; j < size; ++j) {
System.out.print(foo[i][j] + " ");
}
}
}//SSCCE1
Output:
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 1 2 3 4 0 1 2 3 4
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4
This shows that while I do have two 2D arrays they equal each other, they are not unique copies of each other. foo was a 2D array that was initialized by default to 0, but then we have foo reference bar. So the changes made to bar are reflected by foo. You want, I'm supposing, an independent copy initialized with the values of the other.
See that Arrays are Objects.
What you don't seem to understand is what the following line in your code does:
cellsX = cells;
Arrays in Java are objects. Variables hold references to objects. You just assigned the reference held in cells to cellsX. You now have two variables pointing to one array object. The array (and the arrays it contained) you originally instantiated and assigned to cellsX is gone; nothing references it and it will be garbage collected.
Consider the following:
public class Demo {
public static class MyPojo {
public int value;
public MyPojo(int value) {
this.value = value;
}
}
public static void main(String[] args) {
MyPojo pojoOne = new MyPojo(1);
MyPojo pojoTwo = new MyPojo(2);
System.out.println(pojoOne.value);
System.out.println(pojoTwo.value);
pojoTwo = pojoOne;
// You now have two variables holding a reference to
// a single instance of MyPojo. Changes made through
// either affect the same object. The object you
// originally instantiated and assigned to pojoTwo
// is no longer referenced by anything and will be
// garbage collected.
pojoOne.value = 3;
System.out.println(pojoTwo.value);
}
}
If in your code you're trying to copy the contents of the array referenced by cells to the array referenced by cellsX you would need to do so.
Since this is a multi-dimensional array you need to do a deep-copy; What you really have is an array of array references (since, again, arrays are objects in Java). This StackOverflow question covers that.
I've been lurking and found heaps of great information form here, however the last few days I have been stuck and haven't been able to find help with my issue so I thought id post.
I have some homework and I have to make the contents of my array drop down to the bottom row. If i rotate the grid the items should still drop down to the bottom row and if i eat an object from the bottom row, everything above it in that column should drop down too.
Any help is greatly appreciated.
Here is a demo video of what should happen:
http://youtu.be/CB07vN-C_-Y
This is what i have so far:
`public class Assignment
{
// This method should return a *new copy* of
// the 2D cell matrix, with entries rotated clockwise
// The original matrix should not be changed
public static int[][] rotateClockwise(int[][] cells)
{
int w = cells.length;
int h = cells[0].length;
int[][] matrix = new int[h][w];
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
matrix[i][j] = cells[j][h - i - 1];
}
}
return matrix;
}
// This method should return a *new copy* of
// the 2D cell matrix, with entries rotated anti-clockwise
// The original matrix should not be changed
public static int[][] rotateAnticlockwise(int[][] cells)
{
int w = cells.length;
int h = cells[0].length;
int[][] matrix = new int[h][w];
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
matrix[i][j] = cells[w - j - 1][i];
}
}
return matrix;
}
// This method should return a *new copy* of the array, except
// that if there is a 0 that has a non-zero in the preceding
// slot in the array, then those two entries should be swapped
// See ProgrammingProject.pdf for an example
// The original array should not be changed
public static int[] dropOne(int[] column)
{
return column; // this will compile but gives the wrong result
}
}`
I'd model a column as a Queue<Icon> col = new LinkedList<Icon>(); there's an outline here for Queue<Segment> and a complete example here for Queue<Bauble>. You can peek() at the head (bottom) of the queue; if it's empty, you remove() a block from the column and add() it to the tail (top).
Addendum: You might start with this example, drop the getGray(), change the layout to new GridLayout(0, 1). Then, instead of shuffle(list), you'd cycle the queue.
for(int i = 0; i < arrayWidth; i++) {
boolean reachedZero = false;
for( int j = 0; j < arrayHeight; j++) {
if(array[i][j] == 1 && reachedZero == true) {
while( j >=0 && array[i][j - 1] == 0) {
array[i][j-1] = array[i][j];
array[i][j] = 0;
j--;
reachedZero = false;
}
j--; // Maybe an error here, it's late
if( array[i][j] == 0) {
reachedZero = true;
}
}
}
This was posted by a lovely redditor (RankWeis) from the /learnprogramming sub-reddit.
http://www.reddit.com/r/learnprogramming/comments/126597/java_help_needed_on_adding_a_gravity_effect_to/