JavaFX Connect 4 game win method - java

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.

Related

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());
}

Get sum of integers with old numbers 1 + (1 + 2) + (1 + 2 + 3) + ... + (1 + 2 + 3 + ... + n)

I'm trying to reach this :
1 + (1 + 2) + (1 + 2 + 3) + ... + (1 + 2 + 3 + ... + n)
I'm already getting this result:-
(1 + 2) + (2 + 3)
with this code :
int n = 8;
for (int i = 1; i < n; i++){
int j = i + 1;
System.out.print("(" + i + " + " + j + ")");
}
How can I achieve the top result ?
You need two loops like this :
int n = 8;
String del;
String del2 = "";
for (int i = 1; i <= n; i++) {
System.out.print(del2 + "(");
del = "";
for (int j = 1; j <= i; j++) {
System.out.print(del + j);
del = " + ";
}
System.out.print(")");
del2 = " + ";
}
code demo
Move the declaration of j before the loop and initialize it with 0, then just add the current i to j.
That would solve what? – AKSW
This would calculate the sum of the equation.
To print the equation you also need one loop only:
int n = 8;
StringBuilder equation = new StringBuilder("1");
StringBuilder equationGroup = new StringBuilder("1");
for (int i = 2; i < n; i++) {
equationGroup.append(" + ");
equationGroup.append(i);
equation.append(" + (");
equation.append(equationGroup.toString());
equation.append(")");
}
System.out.println(equation.toString());
Well, thanks #YCF_L for your answer it's the correct one, but this complete one after edit, i posted it in case some one need the complete solution:
int n = 8;
String del;
String delPlus = "";
String rightPract = "", leftPract = "";
for (int i = 2; i < n; i++) {
System.out.print(delPlus + rightPract);
del = "";
for (int j = 1; j < i; j++) {
System.out.print(del + j);
del = " + ";
}
System.out.print(leftPract);
delPlus = " + ";
rightPract = "(";
leftPract = ")";
}
Now the result is :-
1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4 + 5) + (1 + 2 + 3 + 4 + 5 + 6)
If you take the recursion approach you have to think of it as a recursion inside another recursion. add(i,n) generates 1 and (1+2) and (1+2+3) up to (1+2+3...n). then the sum(i,n) recursively sum them together
public static int add(int i, int n){
if(i == n){
return n;
}
return i + add(i+1,n);
}
public static int sum(int i, int n){
if(i == n){
return add(0,n);
}
return add(0, i) + sum(i+1,n);
}
public static void main(String[] args){
int n = 8;
System.out.print(sum(0, n));
}

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.

start searching in a 2 dimensional array from a sertent element 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");
}

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