Game of Life Matrix copy - java

I'm working on a version of Conway's Game of Life and I've created the method for creating a new Generation, where I copy a matrix and look for nearby neighbors. I would however like to split this method in to two seperate methods. A copy method of the matrix and then the original newGeneration would call on copy() for help. This is how my newGeneration method looks like right now.
public void newGeneration() {
temp = new boolean[board.getRows()][board.getCols()];
for (int i = 0; i < board.getRows(); i++) {
for (int j = 0; j < board.getCols(); j++) {
if (board.get(i, j)==true) {
if (getNeighbours(board, i, j) > 3) {
temp[i][j] = false;
} else if (getNeighbours(board, i, j) < 2) {
temp[i][j] = false;
} else{
temp[i][j] = true;
}
} else if (board.get(i, j) == false) {
if (getNeighbours(board, i, j) == 3) {
temp[i][j] = true;
}
}
}
}
for (int i = 0; i < board.getRows(); i++) {
for (int j = 0; j < board.getCols(); j++) {
board.put(i, j, temp[i][j]);
}
}
I want to split this in to two methods, newGeneration() and copy(). I've been working on it for a while now but I seem to screw up with the variables i and j because theyre locally set in the loops. Any help with splitting this method up in to two will be appreciated, thanks!
EDIT:
From some sage advice recommending me of this post, I made something like this
public void newGeneration() {
boolean[][] tempCells = new boolean [board.getRows()][board.getCols()];
for (int row = 0; row < board.getRows(); row++) {
for (int col = 0; col < board.getCols(); col++) {
int n = getNeighbours(board,row,col);
if (n > 3 || n < 2)
tempCells[row][col] = false;
else if (n == 3)
tempCells[row][col] = true;
else
tempCells[row][col] = temp[board.getRows()][board.getCols()];
}
}
}
But it doesn't seem to work properly.

A simple way to get a copy of an array is to clone it. Since clone gives just a shallow copy, it requires explicit cloning for each additional dimension for multidimensional arrays:
public static boolean[][] copy(boolean[][] source) {
boolean[][] copy = source.clone();
for (int i=0; i<copy.length; ++i) {
copy[i] = copy[i].clone();
}
return copy;
}

Related

java processing shuffeling 2d array without classes

the school gave me an assignment. I have to make the memory cards game in processing using java.
I am not allowed to use classes. I already created the game and it works, but now I have to add death cards.
I am using a 2d array to load the cards. I have put the death cards in the third iteration of the array.
now the problem is, when I am trying to create a shuffle function, it will only shuffle the cards in its own iteration. so all the death cards will appear at the end.
anybody got any ideas?
for (int i=0; i<3; i++) {
if (i == 0 || i == 1) {
for (int j=0; j<aantalSetjes; j++) {
y[i][j] = yKaart;
x[i][j] = xKaart;
gekozenKaart[i][j] = teller;
teller +=1;
if (teller > aantalSetjes) {
teller = 1;
}
if (xKaart<=(kaartBreedte * getSpeelveldBreedteKeer())-kaartBreedte) {
xKaart += kaartBreedte;
} else if (xKaart>=(kaartBreedte * getSpeelveldBreedteKeer())-kaartBreedte) {
xKaart=15;
yKaart += kaartLengte;
}
}
} else if (i == 2) {
for (int j=0; j<getAantalDoodsKaarten(); j++) {
y[i-1][j+aantalSetjes] = yKaart;
x[i-1][j+aantalSetjes] = xKaart;
gekozenKaart[i][j] = teller;
teller +=1;
if (teller > getAantalDoodsKaarten()) {
teller = 1;
}
if (xKaart<=(kaartBreedte * getSpeelveldBreedteKeer())-kaartBreedte) {
xKaart += kaartBreedte;
} else if (xKaart>=(kaartBreedte * getSpeelveldBreedteKeer())-kaartBreedte) {
xKaart=15;
yKaart += kaartLengte;
}
}
}
}
shuffle()
}
void shuffle() {
int tijdelijk = 0;
int random = 0;
for (int i = 0; i < 3; i++) {
if (i == 0 || i == 1) {
for (int j = 0; j < aantalSetjes; j++) {
random = int(random(0, aantalSetjes));
tijdelijk = gekozenKaart[i][j];
gekozenKaart[i][j] = gekozenKaart[i][random];
gekozenKaart[i][random] = tijdelijk;
}
} else if (i == 2) {
for (int j = 0; j < getAantalDoodsKaarten(); j++) {
random = int(random(0, getAantalDoodsKaarten()));
tijdelijk = gekozenKaart[i][j];
gekozenKaart[i][j] = gekozenKaart[i][random];
gekozenKaart[i][random] = tijdelijk;
}
}
}
}
If it's the classic memory card game, you most probably don't want the data to be organized in the 2d array to begin with. Just combine all of them into one bigger 1d array first and then shuffle the 1d array. Then they will be all mixed through as you wanted.

How to get data slice in matrix

I want to take slices of data from the "MatrixEgoNetwork" matrix with "MatrixIndirectNode", but here I find difficulties, can you help me?
I tried to use retainAll() but I still couldn't
public double countSimilarity(double[][] matrixEgoNetwork, double[][] matrixIndirectNode, int index) {
if (matrixIndirectNode == null) {
return this.countDirectSimilarity(matrixEgoNetwork, index);
}
double sim = 0;
for (int i = 0; i < matrixEgoNetwork.length; i++) {
for (int j = 0; j < matrixEgoNetwork[0].length ; j++) {
matrixEgoNetwork[i][j].retainAll(matrixIndirectNode[i][index]) //"I tried to Use retainAll() but an error appeared Cannot resolve method"
if (matrixEgoNetwork[i][0] == matrixEgoNetwork[i][index] && matrixEgoNetwork[i][j]!=0) {
sim++;
}
}
}
return sim;
}
private double countDirectSimilarity(double[][] matrixEgoNetwork, int index) {
double sim = 0;
for (int i = 0; i < matrixEgoNetwork.length; i++) {
for (int j = 0; j < matrixEgoNetwork[0].length ; j++) {
if (matrixEgoNetwork[i][0]== matrixEgoNetwork[i][index] && matrixEgoNetwork[i][j]!=0) {
sim++;
}
}
}
return sim;
}
the output I want to produce is the amount of data obtained from the slice between the matrices, the error is Cannot resolve method when i use a retainAll to get data slice between the matrix, can you help me fix that?

How to check if two matrices have an identical row?

I'm trying to develop an algorithm in Java, which, given two matrices (let's say a and b), returns true if at least one row is identical in a and b.
Here's my attempt of method:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b[0].length; j++){
if(a[i][j] == b[i][j])
check = true;
}
}
return check;
}
And here's a simple main:
public static void main(String[] args){
int a[][] = {{1,2}, {3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(check_row(a, b));
}
Here I get true because first row of both matrices is the same.
But if I change the matrices initialization to this:
int a[][] = {{1,2}, {3,4}};
int b[][] = {{5,6}, {1,2}};
I get false, even though the first row of a and the second row of b are identical.
How should I modify the method in order to get true in both cases?
Your condition is too simple... High level idea is, that for each row from a and b pick a row and then identify whether it is the same, so you need 3 loops...
code:
public class SameRowFinder {
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(hasSameRow(a, b));
int aa[][] = {{1,2},{3,4}};
int bb[][] = {{5,6}, {1,2}};
System.out.println(hasSameRow(aa, bb));
}
private static boolean hasSameRow(int[][] a, int[][] b) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (isSameRow(a[i], b[j])) {
System.out.printf("Same rows are %d and %d (0-based).%n", i, j);
return true;
}
}
}
return false;
}
private static boolean isSameRow(int[] row1, int[] row2) {
if (row1.length != row2.length) {
throw new IllegalArgumentException("rows with different length");
}
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
}
Also you do not need to write your own function for array compare, but use Arrays.equal(int[], int[]), but it will just hide 3rd loop. Method above throws runtime exception in case of different length of arrays. It's definitelly worth look at Arrays.equal(int[], int[]) implementation for some tips (check for equality + null checks).
You have an error in your 2nd loop.
Change:
for(int j = 0; j < b[0].length; j++)
to
for(int j = 0; j < b.length; j++){
Further, the issue is that you cannot compare the rows like you do it.
You have to check that the rows have the same length and finally compare the rows. You will need an additional for loop for comparing the rows.
This one will do the trick:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b.length; j++){
if (compareRows(a[i], b[j]))
check = true;
}
}
return check;
}
private static boolean compareRows(int[] row1, int[] row2) {
if (row1.length == row2.length) {
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
return false;
}
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{5,6}, {1,2}};
System.out.println(check_row(a, b));
}
In the example provided by OP, the loop over rows in b matrix was missing.
When learning, the algorithm can be written as follows:
public static boolean check_row(int a[][], int b[][]) {
int row_size = a[0].length;
for (int i = 0; i < a.length; i++) {
b: for (int j = 0; j < b.length; j++) {
for (int k = 0; k < row_size; k++) {
if (a[i][k] != b[j][k])
continue b; // move to next row in 'b' matrix
}
return true; // all elements in row were equal if we reached this point
}
}
return false;
}
In real life it would probably look like this:
public static boolean check_row(int[][] a, int[][] b) {
return Arrays.stream(b)
.anyMatch(rowB -> Arrays.stream(a).anyMatch(rowA -> Arrays.equals(rowA, rowB)));
}
i hope this code can help you
public static boolean check_row(int a[][], int b[][])
{
boolean check = false;
for(int i = 0; i < a.length; i++)
{
for(int k = 0 ; k< b.length ; k++)
{
for(int j = 0 ; j<b[0].length ; j++)
{
if(a[i][j]!=b[k][j])
{
break;
}//if even one cell were not similar in both a and b break
else
{
if(j==b[0].length-1)
{
check = true;
}//if you haven't broken the loop yet and if j went till the end
}//else if they are equal
}//j to go through columns
if(check == true)
{
break;
}//for bringing down the time complexity
}//k to go through b rows
if(check == true)
{
break;
}//for bringing down the time complexity
}//i
return check;
}

duplicating a 2D array in a loop using basic commands

public static int[][] copyMatrix(int[][] matrix)
{
for (int i = 0; (i < matrix.length); i++)
{
int[][] duplicateMatrix = new int[matrix.length][matrix[i].length];
for (int j = 0; (j < matrix[i].length); j++)
{
duplicateMatrix[i][j] = matrix[i][j];
}
}
return duplicateMatrix;
}
hello all, this specific function doesnt seem to work since duplicateMatrix isnt initialized as a variable, but I cant seem to initialize since its being created in the loop, I cant find a way to generate the amount of cells need in a column.
help will be appreciated. thanks.
You should initialize the array before the loops, since you only want to initialize it once.
public static int[][] copyMatrix(int[][] matrix)
{
if (matrix.length < 1) {
return new int[0][0];
}
int[][] duplicateMatrix = new int[matrix.length][matrix[0].length];
for (int i = 0; (i < matrix.length); i++)
{
for (int j = 0; (j < matrix[i].length); j++)
{
duplicateMatrix[i][j] = matrix[i][j];
}
}
return duplicateMatrix;
}
This code assumes that all the rows in your input array have the same number of elements (which is true for matrices).
You can relax this assumption if you remember that a 2-dimentional array is simply an array of arrays :
public static int[][] copyMatrix(int[][] matrix)
{
int[][] duplicateMatrix = new int[matrix.length][];
for (int i = 0; (i < matrix.length); i++)
{
duplicateMatrix[i] = new int[matrix[i].length];
for (int j = 0; (j < matrix[i].length); j++)
{
duplicateMatrix[i][j] = matrix[i][j];
}
}
return duplicateMatrix;
}
A two-dimensional array is an array of arrays. You must first create the two-dimensional array, and then each one of its element individually:
public static int[][] copyMatrix(int[][] matrix)
{
int[][] duplicateMatrix = new int[matrix.length][];
for (int i = 0; (i < matrix.length); i++)
{
duplicateMatrix[i] = new int[matrix[i].length];
for (int j = 0; (j < matrix[i].length); j++)
{
duplicateMatrix[i][j] = matrix[i][j];
}
}
return duplicateMatrix;
}

Finding uniques integers in an array

i have an array of integers like this one :
A={1,1,4,4,4,1,1}
i want to count the each number once , for this example the awnser is 2 becuase i want to count 1 once and 4 once
i dont want to use sorting methods
i am unable to find a way to solve it using java.
i did this but it gives me 0
public static void main(String args[]) {
int a[] = { 1,1,4,4,4,4,1,1};
System.out.print(new Test4().uniques(a));
}
public int uniques(int[] a) {
int unique = 0;
int tempcount = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i] == a[j]) {
tempcount++;
}
}
if (tempcount <= 2) {
unique=a[i];
}
tempcount = 0;
}
return unique;
}
the purpose of the question is to understand the logic of it but not solving it using ready methods or classes
This one should work. I guess this might be not the most elegant way, but it is pretty straightforward and uses only simple arrays. Method returns number of digits from array, but without counting duplicates - and this I believe is your goal.
public int uniques(int[] a) {
int tempArray[] = new int[a.length];
boolean duplicate = false;
int index = 0;
int digitsAdded = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < tempArray.length; j++) {
if (a[i] == tempArray[j]) {
duplicate = true;
}
}
if(!duplicate) {
tempArray[index] = a[i];
index++;
digitsAdded++;
}
duplicate = false;
}
//this loop is needed if you have '0' in your input array - when creating temp
//array it is filled with 0s and then any 0 in input is treated as a duplicate
//again - not most elegant solution, maybe I will find better later...
for(int i = 0; i < a.length; i++) {
if(a[i] == 0) {
digitsAdded++;
break;
}
}
return digitsAdded;
}
Okay first of all in your solution you are returning the int unique, that you are setting as the value that is unique a[i]. So it would only return 1 or 4 in your example.
Next, about an actual solution. You need to check if you have already seen that number. What you need to check is that for every number in the array is only appears in front of your position and not before. You can do this using this code below.
public int uniques(int[] a) {
int unique = 1;
boolean seen = false;
for (int i = 1; i < a.length; i++) {
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
seen = true;
}
}
if (!seen) {
unique++;
}
seen = false;
}
return unique;
}
In this code you are iterating over the number you have seen and comparing to the number you are checking (a[i]). You know that for it to be unique you cant have seen it before.
I see two possible solutions:
using set
public int unique(int[] a) {
Set<Integer> set = new HashSet<>();
for (int i : a) {
set.add(i);
}
return set.size();
}
using quick sort
public int unique(int[] a) {
Arrays.sort(a);
int cnt = 1;
int example = a[0];
for (int i = 1; i < a.length; i++) {
if (example != a[i]) {
cnt++;
example = a[i];
}
}
return cnt;
}
My performance tests say that second solution is faster ~ 30%.
if restricted to only arrays, consider trying this:
Lets Take a temporary array of the same size of orignal array, where we store each unique letter and suppose a is your orignal array,
int[] tempArray= new int[a.length];
int tempArraycounter = 0;
bool isUnique = true;
for (int i = 0; i < a.length; i++)
{
isUnique = true;
for (int j = 0; j < tempArray.length; j++)
{
if(tempArray[j] == a[i])
isUnique = false;
}
if(isUnique)
{
tempArray[tempArraycounter] = a[i];
tempArraycounter++;
isUnique = false;
}
}
now tempArraycounter will be your answer ;)
Try Following code:
int test[]={1,1,4,4,4,1,1};
Set<Integer> set=new LinkedHashSet<Integer>();
for(int i=0;i<test.length;i++){
set.add(test[i]);
}
System.out.println(set);
Output :
[1, 4]
At the end set would contain unique integers.

Categories

Resources