start searching in a 2 dimensional array from a sertent element java - java

I am trying to write a code that searches through a 2 dimensional array and tries to find the closest element to "x" that is empty, if "x" has any data in. The elements' coordinates are given from another method. For example "x" is (3,2). If there's no empty element then the code must continue searching in the whole array.
public void find(int row, int column) {
for (int i = row - 1; i < row + 2; i++) {
for (int k = column - 1; k < column + 2; k++) {
if (this.arr[i][k].equals(" ")) {
System.out.println(i + "," + k + " is empty.");
return;
}
}
}
}
I am looking foreword for any helpful suggestions on how to code this method.
Thank you.

Under assumptions
this is matrix (each row has equal num of columns)
method arguments are valid: 0 <= row < numOfRows and 0 <= column < numOfColumns
this code will do search of 2 dimensional array around specified element in the way you've described.
Note that this is not clock direction round search around specified element, but search from top left corner to bottom right corner (from top to bottom and from left to right)
public void find(int row, int column) {
int distance = 1;
int numOfRows = arr.length;
int numOfColumns = 0;
if (arr.length > 0) {
numOfColumns = arr[0].length;
}
int maxDistance = Math.max(numOfRows, numOfColumns);
for (distance = 1; distance < maxDistance; distance ++) {
for (int i = Math.max(row - distance, 0); i <= Math.min(row + distance, numOfRows - 1); i++) {
if (Math.abs(i - row) == distance) {
// Check row
for (int k = Math.max(column - distance, 0); k <= Math.min(column + distance, numOfColumns - 1); k++) {
if (arr[i][k] == null || arr[i][k].trim().isEmpty()) {
System.out.println((i+1) + "," + (k+1) + " is empty.");
return;
} else {
System.out.println((i+1) + "," + (k+1) + " is not empty.");
}
}
} else {
// Check only edge elements
int k = column - distance;
if (k >= 0) {
if (arr[i][k] == null || arr[i][k].trim().isEmpty()) {
System.out.println((i+1) + "," + (k+1) + " is empty.");
return;
} else {
System.out.println((i+1) + "," + (k+1) + " is not empty.");
}
}
k = column + distance;
if (k < numOfColumns) {
if (arr[i][k] == null || arr[i][k].trim().isEmpty()) {
System.out.println((i+1) + "," + (k+1) + " is empty.");
return;
} else {
System.out.println((i+1) + "," + (k+1) + " is not empty.");
}
}
}
}
}
System.out.println("No empty elements");
}

Related

JavaFX Connect 4 game win method

I am creating a Connect 4 game in JavaFX here is my checkWin method. The way my game works is that every cell in board has a blank circle in it and only when user chooses a column does it then have setFill(Color.RED) (or blue depending on the player). Everything is working fine except this method.
public void checkWin(int row, int column, GridPane board) {
Circle piece = ((Circle)getNodeByRowColumnIndex(row, column, board));
// Horizontal check
if (column - 3 <= 0) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row, column + i, board)) ; i++) {
System.out.println("Checking : (" + (row) + " , " + (column + i) + ")");
if(i == 4) hasWon = true;
}
} else if (column + 3 > Columns) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row, column - i, board)) ; i++) {
System.out.println("Checking : (" + (row) + " , " + (column - i) + ")");
if(i == 4) hasWon = true;
}
}
// Vertical check
if (row - 3 <= 0) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row + i, column, board)) ; i++) {
System.out.println("Checking : (" + (row + i) + " , " + (column) + ")");
if(i == 4) hasWon = true;
System.out.println(i);
}
} else if (row + 3 > Rows) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row - i, column, board)) ; i++) {
System.out.println("Checking : (" + (row - i) + " , " + (column) + ")");
if(i == 4) hasWon = true;
}
}
// Ascending diagonal check
if (row - 3 <= 0 && column - 3 <= 0) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row + i, column + i, board)) ; i++) {
System.out.println("Checking : (" + (row + i) + " , " + (column + i) + ")");
if(i == 4) hasWon = true;
}
} else if (row + 3 > Rows && column + 3 > Columns) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row - i, column - i, board)) ; i++) {
System.out.println("Checking : (" + (row - i) + " , " + (column - i) + ")");
if(i == 4) hasWon = true;
}
}
// Descending diagonal check
if (row + 3 > Rows && column - 3 <= 0) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row - i, column + i, board)); i++) {
System.out.println("Checking : (" + (row - i) + " , " + (column + i) + ")");
if(i == 4) hasWon = true;
}
} else if (row - 3 <= 0 && column + 3 > Columns) {
for(int i = 1; piece.equals((Circle)getNodeByRowColumnIndex(row + i, column - i, board)); i++) {
System.out.println("Checking : (" + (row + i) + " , " + (column - i) + ")");
if(i == 4) hasWon = true;
}
}
}
First, and in general, try to separate your data from your representation. So keep some array or other data structure where you only store if there is a stone and what. Don't store circles
Second. The actual problem is closely related and shows why you should do so:
You only want to compare the colors of the circles. Not the circles themselves.
(I'm only guessing that these are JavaFX Circles because you don't show the complete code...)
Because every circle has a radius and a center. And every center is most probable different your equals method will always return false.
So compare only colors. Or better: separate data from representation.

Two dimensional array input from user in java from a sequence of lines, ending with a line input "end"

Here is my code. I think that there is much better way to fill matrix with integers from String lines. My output shows correct output, but it is too complicated. How to make it less complex?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int [][]matrix = new int [7777][7777];
int counter = 0;
int counter1 = 0;
for (int i = 0; i < 7777; i++) {
String s = scanner.nextLine();
if (!"end".equals(s)) {
counter++;
String s1[] = s.split(" ");
for (int j = 0; j < s1.length; j++) {
matrix[i][j] = Integer.parseInt(s1[j]);
counter1++;
}
} else {
break;
}
}
int v = counter;
int h = counter1/counter;
for (int i = 0; i < v; i++) {
for (int j = 0; j < h; j++) {
if (v == 1 || h == 1) {
System.out.print(matrix[i][j]*4 + " ");
} else if (i == 0){
if (j == 0){
System.out.print(matrix[v-1][j] + matrix[i+1][j] + matrix[i][h-1] + matrix[i][j+1] + " ");
} else if (j != h-1){
System.out.print(matrix[v-1][j] + matrix[i+1][j] + matrix[i][j-1] + matrix[i][j+1] + " ");
} else {
System.out.print(matrix[v-1][j] + matrix[i+1][j] + matrix[i][j-1] + matrix[i][0] + " ");
}
} else if (j == 0 && i != v-1){
System.out.print(matrix[i-1][j] + matrix[i+1][j] + matrix[i][h-1] + matrix[i][j+1] + " ");
} else if (j != 0 && j != h-1 && i != v-1) {
System.out.print(matrix[i-1][j] + matrix[i+1][j] + matrix[i][j-1] + matrix[i][j+1] + " ");
} else if (j == h-1 && i != v-1){
System.out.print(matrix[i-1][j] + matrix[i+1][j] + matrix[i][j-1] + matrix[i][0] + " ");
} else if (i == v-1) {
if (j == 0) {
System.out.print(matrix[i-1][j] + matrix[0][j] + matrix[i][h-1] + matrix[i][j+1] + " ");
} else if (j != h-1) {
System.out.print(matrix[i-1][j] + matrix[0][j] + matrix[i][j-1] + matrix[i][j+1] + " ");
} else {
System.out.print(matrix[i-1][j] + matrix[0][j] + matrix[i][j-1] + matrix[i][0] + " ");
}
}
}
System.out.println();
}
}
}
Here is the task assignment.
Write a program, which inputs the rectangular matrix from a sequence of lines, ending with a line, containing the only word "end" (without the quotation marks).
The program should output the matrix of the same size, where each elements in the position (i, j) is equal to the sum of the elements from the first matrix on the positions (i-1, j), (i+1, j), (i, j-1), (i, j+1). Boundary elements have neighbours on the opposite side of the matrix. In the case with one row or column, the element itself maybe its neighbour.
Sample Input:
9 5 3
0 7 -1
-5 2 9
end
Sample Output:
3 21 22
10 6 19
20 16 -1
Yes this code could be simplified.
Starting off, using array is not the best choice for containing the input because you don't know the input size. Using a List that can expand to fit the data will be easier. Further, using the Stream api, we can convert the input into a List<List<Integer>> fairly easily.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
List<List<Integer>> matrix = reader.lines()
.takeWhile(line -> !line.equals("end"))
.map(line -> Arrays.stream(line.split(" "))
.map(Integer::valueOf)
.collect(Collectors.toList()))
.collect(Collectors.toList());
Now that we have the data in our list we will compute the size of the width and height.
int height = matrix.size();
int width = matrix.get(0).size();
Computing the locations of (i-1, j), (i+1, j), (i, j-1), (i, j+1) without an IndexOutOfBoundsException is a little more tricky, however you can use this modulo formula. As long as the offset isn't negatively larger than the size this will work. You can also that the modulo of the offset if that is a concern
(size + index + offset) % size
// or
(size + index + (offset % size)) % size
To add the strings together with a space you can use a StringJoiner.
for (int i = 0; i < height; i++) {
StringJoiner joiner = new StringJoiner(" ");
for (int j = 0; j < width; j++) {
int value = matrix.get((height + i - 1) % height).get(j)
+ matrix.get((height + i + 1) % height).get(j)
+ matrix.get(i).get((width + j - 1) % width)
+ matrix.get(i).get((width + j + 1) % width);
joiner.add(String.valueOf(value));
}
System.out.println(joiner.toString());
}

Java: Do-while loop executing even if condition is false

This is a word search program. The text it searches through is input and turned into a 2D array in another class.
This is the text the program is searching through:
10 //rows
15 //columns
fqexfecmxdvjlgu
cxomfslieyitqtz
nucatfakuxofegk
hfytpnsdlhcorey
pgrhdqsypyscped
ckadhyudtioapje
yerjodxnqzztfmf
hypmmgoronkzhuo
hdskymmpkzokaao
amuewqvtmrlglad
For some reason even if my terminating string end is typed in, it always goes into my checkDown() method and creates an out of bounds error. If I comment out that method and just execute the checkRight() and checkDiagonal() methods, everything seems to work fine.
This is my code:
import java.util.Scanner;
public class WordSearch
{
private char[][] array;
private String targetWord;
private int rowLocation;
private int colLocation;
public WordSearch(char[][] inArray)
{
array = inArray;
}
public void play()
{
do{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
System.out.print(array[row][col]);
}
System.out.println();
}
System.out.println();
Scanner input = new Scanner(System.in);
System.out.println("What word would you like to search for? Type end to quit: ");
targetWord = input.nextLine();
System.out.println("Typed in: " + targetWord);
System.out.println();
compareFirst(targetWord);
} while (!targetWord.equals("end"));
}
public void compareFirst(String inWord)
{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
if(array[row][col] == inWord.charAt(0))
{
rowLocation = row;
colLocation = col;
suspectAnalysis();
}
}
}
}
public void suspectAnalysis()
{
checkRight();
checkDown();
checkDiagonal();
}
public void checkRight()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(colLocation + i > array[0].length - 1)
{
return;
}
else if(array[rowLocation][colLocation + i] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found horizontally at row " + rowLocation + " and column " + colLocation);
System.out.println();
return;
}
public void checkDown()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(rowLocation + i > array.length - 1 && colLocation + i > array[0].length - 1)
{
return;
}
else if(array[rowLocation + i][colLocation] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found vertically at row " + rowLocation + " and column " + colLocation);
System.out.println();
}
public void checkDiagonal()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(colLocation + i > array[0].length - 1 || rowLocation + i > array.length - 1)
{
return;
}
else if(array[rowLocation + i][colLocation + i] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found diagonally at row " + rowLocation + " and column " + colLocation);
System.out.println();
}
}
Why doesn't this happen when I comment out the checkDown() method? How can I fix it?
I'd appreciate any help. Thank you!
there a three circumstances which cause the fail:
Cause you use the do-while-loop, which checks his condition on the end of your loop, the programm is looking for the word "end before finishing
Your last row has an "e" (and thats your luck ;-) ). So your Analysis starts
with row 9, col 3.
this condition:
if(rowLocation + i > array.length - 1 && colLocation + i > array[0].length - 1)
akaif(9 + 1 > 9 && 3 + 1 > 14)
gives back true && false => false
causing an out of bounce in your next condition:
else if(array[rowLocation + i][colLocation] != targetWord.charAt(i))
aka
else if(array[9 + 1][3] != targetWord.charAt(i))
So change && to ||...
If you dont wont to check the word "end" exchange your do-while with a while(true) and check via
if(!targetword.equals("end"))
break;
immediately after the scanner.

Sorted Matrix Search

I keep receiving an ArrayIndexOutOfBounds on the line directly after the for loop. I would also wondering how I could continue to loop the matrix to iterate the row or column until the target is reached.
In the given matrix, I want to start in the bottom left hand corner. If the target value is less than the selected number then the row moves up. If the target value is greater than the selected number then column moves one to the right.
public static void optimizedSearch(int matrix[][], int array_size, int target) {
int row = 0;
int col = array_size-1;
boolean found = false;
int comparison_counter = 0;
int end = array_size * 2;
//while (!found) {
for (int i = 0; i < 100 && !found; i++) {
if (matrix[row][col] < target ) {
row++;
comparison_counter++;
} else if (matrix[row][col] > target) {
col--;
comparison_counter++;
} else if (matrix[row][col] == target) {
found = true;
} else if ((i == end) && (found == false)) {
found=false;
}
}// end for loop
if (found == true) {
System.out.println(target + " found in " + comparison_counter + " number of comparisons using optimized search");
} else
System.out.println(target + " not found in " + comparison_counter + " number of comparisons using optimized search");
} //end optimizedSearch

java, for statement: access incremented value outside the loop

for(int i = 0 ; i < Tri.length; i++)
for(int v = 1; v < Tri.length; v++)
{
boolean plz = Tri[i].compareColors(Tri[v]);
if (v == i)
continue;
if (plz == true)
System.out.println("Triangle " + i + " is equal to Triangle " + v + " " + plz);
}
i need to use the value of i outside of the loop.Currently the print statement is being looped 21 X more than what i need. Is there any way i can access 'i' with having all my code in a for loop
To access i outside of the loop, change the first line to this:
int i = 0;
for(; i < Tri.length; i++)
You could use a while loop
int i = 0;
int v = 1;
while (i < Tri.length) {
while (v < Tri.length) {
boolean plz= Tri[i].compareColors(Tri[v]);
if(v==i)
continue;
if(plz == true )
System.out.println("Triangle " + i + " is equal to Triangle "+ v+ " "+ plz);
v++;
}
i++;
}

Categories

Resources