I'm more or less new to Java.
I'm making a console-based connect 4 game in java and I'm pretty much done, I'm just struggling with how to check for a diagonal win (four pieces in a row diagonally). My vertical/horizontal win checkers are working fine, but I can't figure out how to do a similar thing for a diagonal-checker. The board is a 2d-array which is printed to the console, and to check for a win, I check for four of the same piece next to each other or above each other.
Here are the bits of board code:
private String board[][] = new String[8][8];
creates array
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
board[i][j] = "( )";
}
}
fills the board with blank slots
void displayBoard() {
for (int i = 1; i < 9; i++) {
System.out.print(" " + i + " ");
}
System.out.println();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
}
And here is the winchecker
boolean winCheck1() {
String p = "(" + piece1 + ")";
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 5; j++) {
if ((board[i][j].equals(p) && board[i][j + 1].equals(p)
&& board[i][j + 2].equals(p) && board[i][j + 3]
.equals(p))) {
this.win1();
return false;
}
}
}
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 5; j++) {
if ((board[j][i].equals(p) && board[j + 1][i].equals(p)
&& board[j + 2][i].equals(p) && board[j + 3][i]
.equals(p))) {
this.win1();
return false;
}
}
}
this.play2();
return false;
}
Any help would be appreciated. Thanks!
If you want to keep doing it your way:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if ((board[j][i].equals(p) && board[j + 1][i + 1].equals(p)
&& board[j + 2][i + 2].equals(p) && board[j + 3][i + 3]
.equals(p))) {
this.win1();
return false;
}
}
}
for (int i = 3; i < 8; i++) {
for (int j = 0; j < 5; j++) {
if ((board[j][i].equals(p) && board[j + 1][i - 1].equals(p)
&& board[j + 2][i - 2].equals(p) && board[j + 3][i - 3]
.equals(p))) {
this.win1();
return false;
}
}
}
However, it's probably better to do this with loops (iterate over directions).
Related
I seem to not be able to solve this java.lang.ArrayIndexOutOfBoundsException: 5
I understand the error, but the table is 5x5 and I think I have everything right for printing it.
public static int tulosta_matriisi(int[][] matriisi) {
int i=0, j=0;
for(i = 0; i <= 4; i++) {
for(j = 0; j <= 4; j++) {
if(j == 4 && i <= 4)
System.out.println(matriisi[i][j]);
else if(i <= 4 && j <= 4)
System.out.print(matriisi[i][j] +"\t");
}
}
return matriisi[i][j];
}
To avoid all this problem you have to use :
for(i = 0; i < matriisi.length; i++) {
for(j = 0; j < matriisi[i].length; j++) {
...
When you get out your loop, the i and j will be incremented so you should not return matriisi[i][j] this make this error java.lang.ArrayIndexOutOfBoundsException: 5, so instead you should to return matriisi[i-1][j-1] so in the end your program should look like this :
public static int tulosta_matriisi(int[][] matriisi) {
int i = 0, j = 0;
for (i = 0; i < matriisi.length; i++) {
for (j = 0; j < matriisi[i].length; j++) {
if (j == matriisi[i].length - 1 && i <= matriisi.length) {
System.out.println(matriisi[i][j]);
} else if (i <= matriisi.length && j <= matriisi[i].length) {
System.out.print(matriisi[i][j] + "\t");
}
}
}
return matriisi[i - 1][j - 1];
}
Good luck
I am currently working on a SudokuChecker I want to check the subfields [3x3] of the sudoku. The following code does this:
int[][] field = new field[9][9];
int wrongNumbers = 0;
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
// Check subfield by using an array
int arr[] = new int[10];
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
arr[field[i + k][j + l]]++;
}
}
for (int k = 1; k < arr.length; k++) {
wrongNumbers += arr[k] > 1 ? arr[k] - 1 : 0;
}
}
}
I want to know are there any improvements for the given code?
(I am not talking about making the 3, 9, etc. constant)
I found a very good answer in Codefights from thucnguyen:
boolean sudoku(int[][] grid) {
for (int i = 0; i <9; i++) {
int row = 0, col = 0, group = 0;
for (int j = 0; j <9; j++) {
// check for row i
row += grid[i][j];
// check for col i
col += grid[j][i];
// check for sub-grid i
group += grid[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3];
}
if (row != 45 || col != 45 || group != 45) return false;
}
return true;
}
I am doing my homework right now and have a question about refactoring my code in Java.
I am working on a Sudoku right now and I need to check if the 3x3 boxes are valid or not. To do that I create a one dimensional array with all the numbers of the boxes and later I compare the value of them. It is working right now but it really isn't refactored at all. I would really like to know if there is any way to reduce all this copy paste.
public static boolean validFieldParts() {
int counter = 0;
boolean isValid = false;
int[] copyArray1 = new int[field.length];
int[] copyArray2 = new int[field.length];
int[] copyArray3 = new int[field.length];
int[] copyArray4 = new int[field.length];
int[] copyArray5 = new int[field.length];
int[] copyArray6 = new int[field.length];
int[] copyArray7 = new int[field.length];
int[] copyArray8 = new int[field.length];
int[] copyArray9 = new int[field.length];
// copy the array
// 1 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray1[i * 3 + j] = field[i][j];
}
}
// 2 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 3; j < 6; j++) {
copyArray2[i * 3 + j - 3] = field[i][j];
}
}
// 3 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 6; j < 9; j++) {
copyArray3[i * 3 + j - 6] = field[i][j];
}
}
// 4 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray4[(i - 3) * 3 + j] = field[i][j];
}
}
// 5 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 3; j < 6; j++) {
copyArray5[(i - 3) * 3 + j - 3] = field[i][j];
}
}
// 6 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 6; j < 9; j++) {
copyArray6[(i - 3) * 3 + j - 6] = field[i][j];
}
}
// 7 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray7[(i - 6) * 3 + j] = field[i][j];
}
}
// 8 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 3; j < 6; j++) {
copyArray8[(i - 6) * 3 + j - 3] = field[i][j];
}
}
// 9 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 6; j < 9; j++) {
copyArray9[(i - 6) * 3 + j - 6] = field[i][j];
}
}
Arrays.sort(copyArray1);
Arrays.sort(copyArray2);
Arrays.sort(copyArray3);
Arrays.sort(copyArray4);
Arrays.sort(copyArray5);
Arrays.sort(copyArray6);
Arrays.sort(copyArray7);
Arrays.sort(copyArray8);
Arrays.sort(copyArray9);
for (int i = 1; i < copyArray1.length; i++) {
if (copyArray1[i] == copyArray1[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray2.length; i++) {
if (copyArray2[i] == copyArray2[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray3.length; i++) {
if (copyArray3[i] == copyArray3[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray4.length; i++) {
if (copyArray4[i] == copyArray4[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray5.length; i++) {
if (copyArray5[i] == copyArray5[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray6.length; i++) {
if (copyArray6[i] == copyArray6[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray7.length; i++) {
if (copyArray7[i] == copyArray7[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray8.length; i++) {
if (copyArray8[i] == copyArray8[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray9.length; i++) {
if (copyArray9[i] == copyArray9[i - 1])
counter++;
else
continue;
}
if (counter > 0)
isValid = false;
else
isValid = true;
return isValid;
}
Instead of using 9 different arrays and 9 different loops to represent each section of 9, I would have another nested for loop that iterates over each cluster using the same array.
//Iterate over each 'block'
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
//Iterate over each cell in the block
for (int i = row*3; i < (row+1)*3; i++) {
for (int j = col*3; j < (col+1)*3; j++) {
copyArray[(i - 3) * 3 + j - 3] = field[i][j];
}
}
//Sort array and do duplication check here - return false if dupe found
}
}
return true
This would cut down on the length of your code, although it may not be more efficient.
Instead of using a counter flag, it would be much faster to instead return false whenever you would have incremented the counter, and to return true at the end. This would prevent unnecessary code from running
Here a complete refactoring. Here the improuvements:
Created two new methods: createCopy and isValid
Deleted unused variables counter and isValid
Substituted 9 arrays with one two size array.
The code as not been tested, please take a bit careful attention on method createCopy in particular.
// Creates each block of 9 digits copying digits from field
// row, col are the block position, starting from upper left 0, 0 to
// last block 2, 2
public static int[] createCopy(int[] field, int row, int col) {
int[] copy = new int[9];
for (int i = 3 * row; i < 3 * row + 3; i++) {
for (int j = 3 * col; j < 3 * col + 3; j++) {
copy[(i - 3 * row) * 3 + j - 3 * col] = field[i][j];
}
}
return copy;
}
// Check if one block is valid
private static boolean isValid(int[] copyArray) {
Arrays.sort(copyArray);
for (int i = 1; i < copyArray.length; i++) {
if (copyArray[i] == copyArray[i - 1]) {
// Exit immediately if not valid
return false;
}
}
return true;
}
// Create blocks, then validate them
// At first not valid block return false
public static boolean validFieldParts() {
int[][] copyArrays = new int[3][3];
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
copyArrays[row][col] = createCopy(field, row, col);
}
}
for (int[] copyArray : copyArrays) {
if (!isValid(copyArray)) {
// Exit immediately if not valid
return false;
}
}
return true;
}
Check if the matrix is folded from.
The test should make:
image
The code always returns false and it is unclear to me why. What's wrong with the code?
the code:
public class test1 {
public static void main(String[] args) {
int[][] mat = { { 1, 7, 9 }, { 2, 9, 7 }, { 9, 2, 1 } };
boolean flag = true;
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat.length; j++) {
System.out.print("[" + mat[i][j] + "]");
}
System.out.println();
}
for (int i = mat.length - 1; i > -1; i--) {
for (int j = mat.length - 1; j > -1; j--) {
if (i == j) {
j--;
}
if (mat[i][j] != mat[j][i]) {
flag = false;
System.out.println("mat[i][j]" + mat[i][j] + " " + i + " "
+ j);
j = -1;
i = -1;
}
}
}
if (flag == false) {
System.out.println("Not first folded matrix");
} else {
System.out.println("First folded matrix");
}
}
}
thank you
You can use this function:
public static boolean isFolded(int[][] mat){
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat.length; j++) {
if (i == j) {
continue;
}
if (mat[i][j] != mat[mat.length - 1 - j][mat.length - 1 - i]) {
System.out.println("mat[i][j] " + mat[i][j] + " i:" + i + " j:"
+ j);
return false;
}
}
}
return true;
}
Call it in you main like:
flag = isFolded(mat);
Im working on a pyramid on Java. I did it with stars. But i want to do it with decreasing numbers. I'm using an input. Assume input is 5;
5
545
54345
5432345
543212345
My code is;
int size = 11;
for (int i = 1; i <= size; i=i+2) {
int spaceCount = (size - i)/2;
for(int j = 0; j< size; j++) {
if(j < spaceCount || j >= (size - spaceCount)) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
System.out.println();
}
I'm very glad to for your attention. Thanks a lot.
int size = 11;
for (int i = 1; i <= size; i=i+2) {
int spaceCount = (size - i)/2;
for(int j = 0; j< size; j++) {
if(j < spaceCount || j >= (size - spaceCount)) {
System.out.print(" ");
} else {
System.out.print(n);
}
}
System.out.println();
}
Something like this ?
But this only works for numbers of 1 - 9.
int h = 2;
String spacing = h == 1 ? "" : String.format("%" + (h - 1) + "s", "");
StringBuilder s = new StringBuilder(String.valueOf(h));
System.out.printf("%s%s\n", spacing, s);
for(int i = h; i > 1; --i){
System.out.print(spacing.substring(0, i - 2));
s.insert(s.length() / 2 + 1, String.valueOf(i - 1) + String.valueOf(i));
System.out.println(s.toString());
}