I have to write the code that sets an 8x8 matrix, a chessboard, and then asks the user what row and what column they want to place the queen on. I then have to put a * on each square to which the queen can move. Putting a * on the row and column the queen could move to wasn't difficult but I'm having trouble correctly labeling the diagonals to on which the queen can move. This is the code I have written so far to try and locate the diagonal:
char[][] chessboard = new char[8][8];
System.out.print("What row do you want to place the queen on? ");
int row = console.nextInt();
System.out.print("What column do you want to place the queen on? ");
int column = console.nextInt();
char queen = 'Q';
chessboard[row - 1][column - 1] = queen;
// column and rows
for (int i = 0; i < chessboard.length; i++) {
for (int j = 0; j < chessboard[0].length; j++) {
if ((i == 2 || j == 6) && chessboard[i][j] != queen) {
chessboard[i][j] = '*';
}
}
}
if ((row - 1) != 0) {
// left diagonal
for (int i = 0; i < row; i++) {
for (int j = (column - 1 - (row - 1)); ((column - 1) - (row - 1)) <= j && j < column; j++) {
if (chessboard[i][j] != queen) {
chessboard[i][j] = '*';
}
}
}
for (int i = (row - 1) + (8 - (column)); i >= row - 1; i--) {
for (int j = 7; j >= (column - 1); j--) {
if (chessboard[i][j] != queen) {
chessboard[i][j] = '*';
}
}
}
// right diagonal
for (int i = 7; i >= row - 1; i--) {
for (int j = (column - 1 - (row - 1)); 0 <= j && j < column; j--) {
if (chessboard[i][j] != queen) {
chessboard[i][j] = '*';
}
}
}
}
for (int i = 0; i < chessboard.length; i++) {
for (int j = 0; j < chessboard[0].length; j++) {
System.out.print(chessboard[i][j] + " ");
}
System.out.println();
}
}
When I put in experimental values, for example row 3 and column 7, I get a really messy output. For the numbers above, I get:
[][][][] * * * []
[][][][] * * * []
* * * * * * Q *
* * * * * [] * *
* * * * * [] * []
* * * * * [] * []
* * * * * [] * []
* * * * * [] * []
Could someone tell me where I'm going wrong?
* This is a homework question so code only in the answers, please. Thanks!
If it were me, I'd simply loop through each square of the chessboard and test the validity of each square as being one that the queen can move to, of the three possible rules, namely
square.x == queen.x ||
square.y == queen.y ||
|square.x - queen.x| == |square.y - queen.y|
If your square matches any of the above rules, then it's a valid square to move to, otherwise it's not. Omitting the square that the queen currently resides on, of course
square.x != queen.x && square.y != queen.y
Pseudocode:
for (int i = 0; i < chessboard.length; i++) {
for (int j = 0; j < chessboard[0].length; j++) {
// You could encapsulate these lines in a isValidSquareForQueenMove(x, y) method.
boolean isSquareValid = false;
isSquareValid = isSquareValid || x == queen.x;
isSquareValid = isSquareValid || y == queen.y;
isSquareValid = isSquareValid || Math.abs(queen.x - x) == Math.abs(queen.y - y);
isSquareValid = isSquareValid && x != queen.x && y != queen.y;
// Do stuff here.
}
}
Related
So I'm currently working on a personal project and I made a program that prints out star patterns. On one of the star patterns I want this output:
Figure
* *
** **
*** ***
**** ****
**********
So I made one method print out this:
Figure 1
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*" + " ");
}
System.out.println("");
}
*
**
***
****
*****
And another method print out this:
Figure 2
for (int i = 0; i < n; i++) {
for (int j = 2 * (n - i); j >= 0; j--) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
System.out.print("* ");
}
System.out.println();
}
*
**
***
****
*****
My question: How can I put the first method stars next to the other method stars?
This is what I got so far:
public static void printStarsVictory(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*" + " ");
}
System.out.println("");
}
for (int i = 0; i < n; i++) {
for (int j = 2 * (n - i); j >= 0; j--) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
System.out.print("* ");
}
System.out.println();
}
}
This is what is printing so far:
*
**
***
****
*****
*
**
***
****
*****
Any idea how to solve this?
I think you are on the right track you just need to combine your two programs into the inner for loop:
private static void printStarsVictory(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j < n * 2; j++) {
if (j <= i || j >= (n * 2 - i)) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
Example Usage printStarsVictory(5):
* *
** **
*** ***
**** ****
*********
Example Usage printStarsVictory(12):
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********** **********
*********** ***********
***********************
Each row has the increasing number of stars and decreasing number of spaces.
e.g. For n=5 first row has 2 stars at each side and 8 spaces.
At each iteration you can increase stars and decrease spaces and print them on the same line:
public static void printStarsVictory(int n) {
int sp = n * 2 - 2; // number of spaces
for (int i = 1; i <= n; i++) {
printStars(i); // print stars on the left side
int temp = sp;
while (temp > 0) {
System.out.print(" ");
temp--;
}
printStars(i); // // print stars on the right side
System.out.println("");
sp -= 2; // decrease spaces on each side
}
}
public static void printStars(int i) {
while(i>0) {
System.out.print("*");
i--;
}
}
Can you keep them in an array before printing to output:
public static void printStarsVictory(int n) {
StringBuilder[] lines = new StringBuilder[n + 1];
for (int i = 0; i < n; i++) {
lines[i] = new StringBuilder();
for (int j = 0; j <= i; j++) {
lines[i].append("*" + " ");
}
for (int j = 2 * (n - i - 1); j > 0; j--) {
lines[i].append(" ");
}
}
for (int i = 0; i < n; i++) {
for (int j = 2 * (n - i - 1); j > 0; j--) {
lines[i].append(" ");
}
for (int j = 0; j <= i; j++) {
lines[i].append("* ");
}
}
for (StringBuilder line : lines) {
System.out.println(line);
}
}
Well, System.out.println() prints only to the next row, not to the right. The only way is to create a new algorithm. You should put everything into single loop.
// loop starts from 0 and user counts from 1, so we wil decrement it by 1
n--;
// this loops moves pointer vertically
for (int i = 0; i < n; i++) {
// this loops moves pointer horisontally
for (int j = 0; j < n*2; j++) {
// here we choose what to print
if (j <= i || j >= n*2-i) {
System.out.print("*");
} else System.out.print(" ");
}
System.out.println();
}
You can visualize this figure as a matrix of numbers in a range: [-n, 0] inclusive vertically and [-n, n] inclusive horizontally, where each point is:
m[i][j] = Math.abs(i) - Math.abs(j);
If n = 4, then this matrix looks like this:
0 1 2 3 4 3 2 1 0
-1 0 1 2 3 2 1 0 -1
-2 -1 0 1 2 1 0 -1 -2
-3 -2 -1 0 1 0 -1 -2 -3
-4 -3 -2 -1 0 -1 -2 -3 -4
Try it online!
int n = 4;
IntStream.rangeClosed(-n, 0)
.map(Math::abs)
.peek(i -> IntStream.rangeClosed(-n, n)
.map(Math::abs)
.mapToObj(j -> i > j ? " " : "* ")
.forEach(System.out::print))
.forEach(i -> System.out.println());
Output:
* *
* * * *
* * * * * *
* * * * * * * *
* * * * * * * * *
See also: Making an hourglass using asterisks in java
Similar to this previous answer, you can use two nested for loops and one if else statement in the same way:
public static void main(String[] args) {
int n = 9;
for (int i = -n; i <= 0; i++) {
for (int j = -n; j <= n; j++)
if (Math.abs(i) <= Math.abs(j)
// in chessboard order
&& (i + j) % 2 == 0
// vertical borders
|| Math.abs(j) == n)
System.out.print("*");
else
System.out.print(" ");
System.out.println();
}
}
Output:
* *
** **
* * * *
** * * **
* * * * * *
** * * * * **
* * * * * * * *
** * * * * * * **
* * * * * * * * * *
** * * * * * * * **
See also:
• How to print a given diamond pattern in Java?
• Empty diamond shape with numbers
I am implementing the matlab 'bwmorph(img, 'thin')' algorithm in Java ImageJ. I've searched all over the net pretty much and found some similar implementations that work better, but I can't find the issue in my code. Any ideas?
My code:
public void run(ImageProcessor ip) {
MakeBinary(ip);
int sum2 = processThin(ip);
int sum = -1;
while (sum2 != sum) {
sum = sum2;
sum2 = processThin(ip);
}
}
public int processThin(ImageProcessor ipOriginal) {
int sum = 0;
// first iteration
ImageProcessor ip = ipOriginal.duplicate();
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
ip.putPixel(i,j, 0);
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
ip.putPixel(i,j, 0);
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (ip.getPixel(i,j) != 0) sum++;
ipOriginal.putPixel(i, j, ip.getPixel(i, j));
}
return sum;
}
private int G1(int[] input) {
int xh = 0;
for (int i = 1; i <= 4; i++) {
if (input[2 * i - 1] == 0 && (input[2 * i] == 1 || (2 * i + 1 <= 8 ? input[2 * i + 1] == 1 : input[1] == 1)))
xh += 1;
}
return xh;
}
private int G2(int[] input) {
int n1 = 0, n2 = 0;
n1 = toInt(toBool(input[4]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[2])) +
toInt(toBool(input[8]) || toBool(input[7])) + toInt(toBool(input[6]) || toBool(input[5]));
n2 = toInt(toBool(input[2]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[8])) +
toInt(toBool(input[6]) || toBool(input[7])) + toInt(toBool(input[4]) || toBool(input[5]));
return Math.min(n1,n2);
}
private int G3 (int[] input){
return toInt((toBool(input[2]) || toBool(input[3]) || !toBool(input[8])) && toBool(input[1]));
}
private int G3prime (int[] input){
return toInt((toBool(input[6]) || toBool(input[7]) || !toBool(input[4])) && toBool(input[5]));
}
private boolean toBool(int i ){
return i == 1;
}
private int toInt(boolean i) {
return i ? 1 : 0;
}
private int[] selectNeighbors(ImageProcessor ip, int i, int j) {
int[] result = new int[9];
result[1] = ip.getPixel(i+1,j);
result[2] = ip.getPixel(i+1,j+1);
result[3] = ip.getPixel(i,j+1);
result[4] = ip.getPixel(i-1,j+1);
result[5] = ip.getPixel(i-1,j);
result[6] = ip.getPixel(i-1,j-1);
result[7] = ip.getPixel(i,j-1);
result[8] = ip.getPixel(i+1,j-1);
for (int x = 0; x < result.length; x++)
if (result[x] != 0) result[x] = 1;
return result;
}
The main issue appears to be with the horizontal lines, but not only that.
Note: I've added the toBool and toInt methods to deal with convenient data types, the code was binary before and the result is the same apparently.
EDIT:
After editing the code and omitting doing modifications between two iterations, I ended up with this result now.
The code looks like this now.
public int processThin(ImageProcessor ip) {
int sum = 0;
// first iteration
int[][] mask = new int[ip.getWidth()][ip.getHeight()];
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
mask[i][j]++;
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
mask[i][j]++;
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (mask[i][j] != 0) sum++;
ip.putPixel(i, j, mask[i][j] > 0 ? 0 : ip.getPixel(i,j));
}
return sum;
}
The problem in your original code is that you write into your input image. In the very first iteration, moving left to right, you remove successive pixels because each has, after modifying the previous pixel, a background pixel as neighbor.
There are different ways to implement the thinning operation, but the simplest one that works in-place like your code does requires two passes through the image for each iteration of the thinning:
Go through the image and mark all candidate pixels. These are the pixels that have a background neighbor. Marking a pixel can be as simple as setting the pixel value to a given constant, for example 42 (assuming background is 0 and foreground is 1 or 255 or whatever you decided on).
Go through the image again and for each marked pixel, determine if removing it would change the geometry of the foreground. If not, remove it. In this test, take the marked pixels that haven't been removed yet as foreground.
I am having a little trouble with one shape I am currently trying to make here is my code currently:
import java.util.Scanner;
public class Problem2
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int n = 0;
do
{
System.out.print("Enter an odd integer greater than or equal to 5: ");
n = input.nextInt();
}while(n < 5 || n % 2 == 0);
boxWithMinorDiagonal(n);
rightTriangle(n);
printNLetter(n);
fancySquare(n);
}
public static void fancySquare(int n)
{
System.out.println();
int tempRow = 2;
int tempCol = 2;
int tempColDec = n - 2;
int tempRowInc = 2;
for(int row = 1; row <= n; row++)
{
for(int col = 1; col <= n; col++)
{
if(row == 1 || row == n || col == 1 || col == n)
{
if(row == 1 && col == 1 || row == 1 && col == n || row == n && col == 1 || row == n && col == n)
{
System.out.print("#");
}
else
{
System.out.print("*");
}
}
else if(tempRow == row && tempCol == col)
{
System.out.print("+");
tempCol++;
tempRow++;
}
else
{
System.out.print(" ");
}
if(row == tempRowInc && col == tempColDec)
{
System.out.print("+");
tempColDec--;
tempRowInc++;
}
}
System.out.println();
}
}
}
Everything works correctly except my last method "fancySquare" is not printing out how I would like it to. It is currently printing out this shape if the user input is 9:
#*******#
*+ + *
* + + *
* + + *
* ++ *
* + + *
* + + *
*+ +*
#*******#
It should look like this instead
#*******#
*+ +*
* + + *
* + + *
* # *
* + + *
* + + *
*+ +*
#*******#
Try to use named booleans for your checks to make it more understandable.
More common is to use zero based index, but i stick to your version to make it more similar and easier to match for you.
public static void fancySquare(int n) {
System.out.println();
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= n; col++) {
final boolean firstRow = row == 1;
final boolean lastRow = row == n;
final boolean firstCol = col == 1;
final boolean lastCol = col == n;
// calc the center
final boolean center = row == (n + 1) / 2 && col == (n + 1) / 2;
// calc the marker
final boolean marker = row == col || n - row + 1 == col;
// we need the # marker at the corners (1,1) || (1,n) || (n,1) || (n,n)
if ((firstRow || lastRow) && (firstCol || lastCol)) {
System.out.print("#");
// we need the * in the first & last column/row which is no corner
} else if (firstRow || lastRow || firstCol || lastCol) {
System.out.print("*");
// we need a # also in the center
} else if (center) {
System.out.print("#");
// we need the plus on the diagonals
} else if (marker) {
System.out.print("+");
// instead we need a space
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
Currently working on some extra problem sets and seem to be stuck with this one. I need to make the following output:
* *
* *
* * * * *
* *
* *
I've got the cross down but i'm having problems with the middle line and was hoping someone could help me figure it out. Heres my code so far (input is set to 5):
public static void drawPlusVersion3(int input){
if (input % 2 != 0) {
for(int c = 0; c < input; c++) {
for(int r = 0; r < input; r++) {
if((c == input / 2) || (r == input / 2))
System.out.print("*");
if ( c == r){
System.out.print("*");
}
else
System.out.print(" ");
System.out.print(" ");
}
System.out.println();
}
}
}
Current output:
* *
* *
* * ** * *
* *
* *
Thanks in advance!
You can try:
public static void drawPlusVersion3(int input){
if (input % 2 != 0) {
for(int c = 0; c < input; c++) {
for(int r = input - 1; r >= 0; r--) {
if((c == input / 2) || (r == input / 2) || c == r)
System.out.print("*");
else
System.out.print(" ");
System.out.print(" ");
}
System.out.println();
}
}
}
How about this:
for (int i = 0; i < input; i++) {
for (int j = 0; j < input; j++) {
if (j == input / 2 || i == input / 2 || i + j == input - 1) {
System.out.print("* ");
} else {
System.out.print(" ");
}
}
System.out.println();
}
*
*****
*********
*********
**** ***
**** ***
so far i only have this
for (int i=1; i<10; i += 4)
{
for (int j=0; j<i; j++)
{
System.out.print("*");
}
System.out.println("");
}
}
}
The simplest decision will be:
for (int y = 0; y < 6; y++) {
int shift = y < 2 ? 4 / (y + 1) : 0;
for (int x = 0; x < 9 - shift; x++) System.out.print(x >= shift && (y < 4 || (x < 4 || x > 5)) ? "*" : " ");
System.out.println();
}
I think Andre's answer is the most concise one, but if you want to have configurable home building you can use next one(try to change HEIGHT/WIDTH to see effect):
public class House {
public static void main(String[] args) {
final int HEIGHT = 6;
final int WIDTH = 9;
for (int i = 0; i < HEIGHT * 2; i += 2) {
for (int j = 0; j < WIDTH; j++) {// check for roof
if ((i + (i % 2) + (WIDTH) / 2) < j // right slope
|| (i + (i % 2) + j) < (WIDTH) / 2)// left slope
{
System.out.print(" ");
} else {
if ((i / 2 >= HEIGHT * 2 / 3) && (j >= WIDTH / 2) && j < WIDTH / 2 + HEIGHT / 3) {// check for door
System.out.print(" ");
} else {// solid then
System.out.print("*");
}
}
}
System.out.println();
}
}
}
EDIT - answer to comment:
Try to run next two example and compare output:
public static void main(String[] args) {
final int SIZE = 9;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
System.out.print(i < j ? "+" : "-");
}
System.out.println();
}
}
and
public static void main(String[] args) {
final int SIZE = 9;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
System.out.print(i < SIZE - j - 1 ? "+" : "-");
}
System.out.println();
}
}
First one will give you right slope and second left one. It all come from geometric properties of points. In first case all points will have bigger value on on x axis than on y axis. In second both x and y in sum won't exceed SIZE.
You can try to modify boolean expression inside of if() statement and see what happens, but I'd encourage you to get piece of paper and try to play with paper and pen and see what properties certain points have. Let me know if you need more explanation.
You could use a two-dimensional array like this:
char matrice [][]= {{' ',' ',' ',' ' '*', ' ',' ',' ',' '},
{' ',' ','*','*', '*', '*','*',' ',' '}};
(And so on). You basically draw your house using your array indexes.
Now you can parse each line using System.out.print() when you have to print a character, and System.out.println("") between each row.
It would look like this:
for(char[] line : house){
for(char d : line){
System.out.print(d);
}
System.out.println("");
}
You should take a look at the for-each statement documentation if you're not familiar with it.