My homework challenge is to make a checkerboard using JavaFX based on the size the user inputs from a JOptionPane. I've done this and works perfectly only with odd numbers, how can I fix this so it works for both odd and evens correctly?
I'm assuming it's an issue with how I'm polling the color to use since with even numbers each row would be identical.
Color[] colors = {Color.BLACK, Color.WHITE};
int nextColor = 0;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
nextColor = (nextColor == 0) ? 1 : 0;
Rectangle rec = new Rectangle();
rec.setWidth(50);
rec.setHeight(50);
rec.setFill(colors[nextColor]);
GridPane.setRowIndex(rec, row);
GridPane.setColumnIndex(rec, col);
grid.getChildren().addAll(rec);
}
}
odd numbers
even numbers
If you're going through the board filling the fields with alternating colors, a even number of columns will result in the last field being colored with a different color than the first field in the row and thus the first field in the next row will have the same color than the field directly above.
To fix this you can simply add the column and row numbers and take the remainder of the division by 2 to determine the color:
Color[] colors = {Color.WHITE, Color.BLACK};
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
int nextColor = (row + col) % 2;
Rectangle rec = new Rectangle();
rec.setWidth(50);
rec.setHeight(50);
rec.setFill(colors[nextColor]);
GridPane.setRowIndex(rec, row);
GridPane.setColumnIndex(rec, col);
grid.getChildren().addAll(rec);
}
}
Another variant than what muzzlator proposes would be to set color by position alone, without storing some current alternate color. This is error-prone as you see.
Simply go with int color = (row + col) % 2;.
Related
This method is simple, there is 2D array, not a rectangle, the purpose is to check the values in each column whether they are increasing or not, if they are in an increasing order, return true, else return false.
The shape of the array is like the following, it is a Young Tableaux
{
[1,4,5,10,11],
[2,6,8],
[3,9,12],
[7]
}
The main properties of a young tableaux:
it consists of cells which are filled with integers, and arranged in
left-justified rows,
no row is longer than a preceding row,
from left to right in any row, and down any column the integers are increasing,
the set of integers used is {1, 2, . . . , n} where n is the number
of cells
How I solve it?
My approach is simple, first convert this 2D array into a rectangle matrix, if some position is empty, then filled it with 0.
Then check the column one by one, if found a error, then break, and return the result.
It works, I just wonder if there is a better apporach for this.
public static boolean columnValuesIncrease(int[][] t) {
//How many columns are there?
int columnCounts = t[0].length;
int rowCounts = t.length;
//create a rectangle matrix, fill 0 when outIndex
int[][] addZero = new int[rowCounts][columnCounts];
for (int row = 0; row < rowCounts; row++) {
for (int col = 0; col < t[0].length; col++) {
try {
addZero[row][col] = t[row][col];
} catch (IndexOutOfBoundsException e) {
addZero[row][col] = 0;
}
}
}
//Let's check the damn column!
boolean mark = true;
myLoop:
for (int col = 0; col < columnCounts; col++) {
for (int row = 0; row < rowCounts; row++) {
if (row + 1 < rowCounts && col + 1 < columnCounts) {
if (addZero[row + 1][col] != 0) {
mark = addZero[row][col] <
addZero[row + 1][col] ? true : false;
}
}
if (!mark) {
break myLoop;
}
}
}
return mark;
}
This approach takes a row. It considers 'this' row and the one after it. It considers N number of columns, where N is the minimum of the number of columns in this row and the row after. In math, if R is the number of rows in this 2D matrix, take some r1: r1 ∈ [0, R) and r2 = r1 + 1. Then, N = min{num_cols(r1), num_cols(r2)}.
In column n, where n ∈ [0, N], if the value at the column in the next row happens to be smaller than the value in the preceding row, it returns false. If everything else worked, it returns true.
public static boolean columnValuesIncrease(int[][] t) {
for(int i = 0 ; i < t.length - 1 ; i++)
for(int j = 0 ; j < Math.min(t[i].length, t[i+1].length) ; j++)
if(t[i][j] > t[i+1][j])
return false;
return true;
}
public static int[][] rotate(int[][] array){
int height = array.length;
int width = array[0].length;
int[][] rotatedArray = array;
for(int col = 0; col < width; col++){
for(int row = 0; row < height; row++){
rotatedArray[row][col] = array[col][row];
}
}
return rotatedArray;
}
This is my code as method to rotate image 90 degree counter-wise, but it doesn't work. I have no idea how to arrange new rows and columns and rotate it properly, how can I fix it? Thanks!
Try rotatedArray[row][col] = array[col][height - row - 1];.
Also, you need to define rotatedarray as a new array. Right now, you're assigning it array, which means they are both referencing the same data.
Here's how you can do it:
public static int[][] rotate(int[][] array) {
int height = array[0].length;
int width = array.length;
int[][] rotatedArray = new int[height][];
for(int row = 0; row < height; row++) {
rotatedArray[row] = new int[width];
for(int col = 0; col < width; col++) {
rotatedArray[row][col] = array[col][height - row - 1];
}
}
return rotatedArray;
}
Note that the height of the original array becomes the width of the new array and vice versa.
By transposing the row & column indices with rotatedArray[row][col] = array[col][row], you are mirroring the image along the diagonal, instead of rotating it. Think about it - any entry where both indices are matching such as array[0][0] or array[1][1] is unchanged. That's not what you want!
I would recommend drawing a picture to see what pattern you see. You can start with very small examples, 2-by-2 or 3-by-3.
I have problem how to start with this program.
I want to get 2d-array of pixel localization.
Then work on this array with bfs, dfs to get path from orange dot to green dot.
Draw grey pixel if visited.
Draw the path and save it to other image.
When i will handle with this i would like to change cost on each pixel (by drawing in paint something similar to walls but it could go throught by them with higher cost)
public int [][] gRGB(BufferedImage image)
{
int width = image.getWidth();
int height = image.getHeight();
int[][] result = new int[width][height];
for (int row = 0; row < width; row++) {
for (int col = 0; col < height; col++) {
result[row][col] = image.getRGB(row, col);
}
}
return result;
}
}
From this code i get 2d-array full of -1 value. Is there option to get color information as value (not rgb i would like to have it as one number not 4)
EDIT:
protected static int [][] convert(BufferedImage image)
{
int width = image.getWidth();
int height = image.getHeight();
int[][] result = new int [width][height];
for(int row = 0; row < height; row++)
for(int col = 0; col < width; col++)
{
Color c = new Color(image.getRGB(col, row));
String h = String.format("%02x%02x%02x", c.getRed(),c.getGreen(),c.getBlue());
if(h.equals("000000")) // black
{
result[col][row] = 0;
}
else if(h.equals("fe0000")) // red
{
result[col][row] = 5;
}
else if(h.equals("ffffff")) // white
{
result[col][row] = 1;
}
else if(h.equals("ff7d41")) // orange - start
{
result[col][row] = 10;
}
else if (h.equals("ff0078")) // pink - end
{
result[col][row] = 9;
}
else
{
result[col][row] = 3;
}
}
for(int row = 0; row < height; row++)
{
System.out.println();
for(int col = 0; col < width; col++)
System.out.print("\t" + result[col][row]);
}
return result;
}
So i have now the array of pixel value. Can someone explain me how to write DFS or BFS algorithm?? Where the cost is the value of pixel?
Black - walls, Orange dot - start, Green dot - end
For finding the path with minimum cost it is better to use algorithms such as UCS,A* or IDA* (It is very inefficient to use BFS or DFS to find shortest path on a weighted graph). My suggestion is to first implement UCS , then improve it with a simple heuristic such as manhattan distance to A*. For full explanation about UCS and A* please refer to these links:
Wikipedia A*
Wikipedia UCS
As for using these algorithms on your 2D-Array, you should consider every point a node and connect that node to every neighbor nodes. So every node is connected to its 4 non-wall neighbors ( or 8 non-wall neighbors if you can move diagonally ).
I'm trying to test each row in my array to see if they are even or odd. If the row is even i want to change the random value in the elements of the row to 0. If the row is odd i want to change the elements to 1. Ive been able to create the element and print it out but im stuck on how to test the rows. I know to test if a number is even you use (i % 2 == 0) but im not sure what coding i should use.
public static void main(String[] args) {
int[][] box;
box = new int[2][2];
int row;
int column;
for (row = 0; row < box.length; row++) {
for (column = 0; column < box[row].length; column++) {
box[row][column] = (int) (Math.random() * 100);
}
}
//where im having issues
// i get error 'bad operand types for binary operator'
if (box[row] % 2 == 0) {
for (row = 0; row< box.length;row++){
box[row][column] = [0][];
}
}
else{
for(row = 0; row < box.length; row++){
box[row][column] = [1][];
}
}
for (row = 0; row < box.length; row++) {
for (column = 0; column < box[row].length; column++) {
System.out.print(box[row][column] + " ");
}
System.out.println();
}
}
}
you can use Arrays built in function fill(int[],value) that takes two argument, First 1d array and second a value to fill
//also if you are checking is row is even or odd divide row not box[row]
if (row % 2 == 0) {
Arrays.fill(box[row],0);//set 0 to every element in this wor
}
else{
Arrays.fill(box[row],1);//set 1 to every element in this wor
}
I am trying to count the number of Space objects in a Space[][], of a particular colour. When I use this method to count the number of objects of a particular colour in a row, it works fine:
public int countRowWhite(Space[][] board, int row)//TESTED//when counting in a row, the columns go up the row stays the
//same,THIS GOES THROUGH THE ROW ADDING UP NUMBERS OF WHITES
{
int count = 0;
for(int column=0; column<board.length;column++)
{
if((board[row][column]).getColour().equals(spaceColour.White))
{
count+=1;
}
}
return count;
}
However when I try this method, to count the number of objects in a column, I get an exception:
public int countColumnWhite(Space[][] board, int column)//when counting in a row, the columns go up the row stays the
//same,THIS GOES THROUGH THE ROW ADDING UP NUMBERS OF WHITES
{
int count = 0;
for(int row =0; column<board.length;row++)
{
if((board[row][column]).getColour().equals(spaceColour.White))
{
count+=1;
}
}
return count;
}
I call both of these methods in the following test method:
public void testMethods()
{
Space[][] test = new Space[5][5];
for(int i = 0; i < test.length; i++){
for(int j = 0; j < test.length; j++){
test[i][j] = new Space(spaceColour.Null);
}
}
test[0][1].setColour(spaceColour.White);
test[0][2].setColour(spaceColour.Black);
test[2][1].setColour(spaceColour.Black);
test[2][2].setColour(spaceColour.Black);
System.out.println(countColumnWhite(test, 0));
for(int row= 0; row<test.length;row++)
{
for(int column = 0; column<test.length;column++)
{
if (test[row][column].getColour().equals(spaceColour.White))
{
System.out.println("Whites at row: " + row + " and Column: "+ column);
}
}
}
If it helps, the exception is always equal to the number of rows and columns the 2d array 'test' has
I imagine that this line:
for(int row =0; column<board.length;row++)
should be:
for(int row = 0; row < board.length; row++)
Your terminating condition was checking that column is lesser than board.length, when it should be checking that row is lesser than board.length. You keep incrementing row, but the termination condition is never true, so you end up going outside the bounds of the array.
Another thing is that your code implicitly assumes that you are working with a square matrix (i.e 2-d array same number of rows and columns). So if you have unequal rows and columns, you will run into the same issue. If your assumption is valid, then this is fine. I imagine this is some kind of game board that is supposed to be square.