Stuck on this bit of code - java

What I am doing is creating a command line "game" where there is a 3x3 grid (Array) where you can move a "1" through it by typing the direction (up, down, left, right).
For example:
0 0 0
0 1 0
0 0 0
I've made it so if the 1 is on the edge of the array it is not allowed to move out of the boundaries (read: resulting in an out of index error).
I'm completely lost as whenever I try to move right, I receiving the following:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Logic.setMove(Logic.java:87)
at Logic.getMove(Logic.java:10)
at GridGameMain.main(GridGameMain.java:13)
Here's my code:
public class GridGameMain {
static int[][] board = new int[3][3];
public static void main(String[] args){
board[(int) (Math.random() * 2.5)][(int) (Math.random() * 2.5)] = 1;
for (int i =0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" " + board[j][i]);
}
System.out.println("");
}
Logic l = new Logic();
l.getMove();
}
}
import java.util.Scanner;
public class Logic extends GridGameMain{
void getMove(){ //takes user input then calls setMove
String direction; //string to hold the direction
Scanner user_input = new Scanner(System.in);
direction = user_input.next();
Logic l = new Logic();
l.setMove(direction);
}
void setMove(String direction){ //called when user presses enter upon typing a move
Logic l = new Logic();
if(direction.equals("up")){
if(board[0][0] == 1 || board[1][0] == 1 || board[2][0] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a][b-1] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved up");
l.getMove();
}
}
if(direction.equals("down")){
if(board[0][2] == 1 || board[1][2] == 1 || board[2][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a][b+1] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved down");
l.getMove();
}
}
if(direction.equals("left")){
if(board[0][0] == 1 || board[0][1] == 1 || board[0][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a-1][b] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved left");
l.getMove();
}
}
if(direction.equals("right")){
if(board[2][0] == 1 || board[2][1] == 1 || board[2][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved right");
l.getMove();
}
}
}
void printBoard(){
for (int i =0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" " + board[j][i]);
}
System.out.println("");
}
}
}
I'm just not sure why I can't move right when I can move up, down, and left just fine. Please tell me I'm not crazy!

I think the trouble is, you check to make sure the 1 is not on the far right, and then you start shifting things right. That means that, if your 1 was on the column 0, it's moved to column 2, then at the next and last iteration, it's moved to column 3.
Also, are you sure this doesn't happen when you go down?
This doesn't happen going down because, as #Keppil says, you break out of the "rows" (relevant) loop, while going right, you break out of the columns one, which is not what you wanted.
Also, you can use tags to break out of whatever loop you want. Here's how.

The problem is that you are moving the "1" from left to right, so since you break the first for, you don't break the second one, so it keep moving the "1", until it is put outside the array (ArrayIndexOutOfBoundsException).
An example to solve it:
boolean found = false;
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1;
board[a][b] = 0;
found = true;
break;
}
if(found){
break;
}
}
}

On your move right:
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1; // what if a is 2??
board[a][b] = 0;
break;
}
}
When a is 2, accessing board[a+1][b] is accessing board[3][b]. On a 3*3 board, that's beyond bounds.
Edit: the problem is due to the fact that after you move the 1, you continue the outer loop - but without the initial bounds check. So after the 1 is moved from the central column to the right one, you try to move it again. This only happens on a right move due to the why you loop.
There are two easy solutions:
Use some flag to make sure you break out of the outer loop as well, or better yet -
Change the bounds of the fors according to what you're actually going to check. If you're not going to move a 1 that is on column #2, you can have a loop between 0 and 1. No reason to go up to 2, if you're never going to make it move from that point. Same goes to all other moves - change the appropriate bounds from < 3 to < 2.

The break; inside your for-loops seems to interrupt only the inner for-loop. after breaking the for(int b = 0; b < 3; b++){ .. }, there is no reason for the outer loop to stop.
Your loop finds the 1 at [1][1] and shifts it to the right. then it breaks the inner loop. Nevertheless it calls the inner loop for a=2, where your 1 is now. He tries to shift again.. and fails with exception.

I believe you should be getting an error when you go to the right. The reason is because when you shift one to the right, you break and then you increment a, but you do not check that it went out of bounds again. Once the 'b' loop finishes and then increments 'a' then it will register it as having a value of 1 and move it once more to the right. This keeps going until it is out of bounds. An easy way to correct your code is to just reverse your loops so the outer loop is incrementing 'b' and the inner loop is incrementing 'a'.

Related

Check if a char is in a 2D array in java

I have been working on my homework of creating a simple chess program.
The chessboard is a 2D array, named board. The pieces are all single chars like R,Q,K, and empty space is filled with a ' ' char, so a space.
public static char[][] board;
The method get should return the char or whatever is there on the coordinate (x,y).
public char get(int x, int y) {
if(x < board[0].length && x >= 0 && y < board.length && y >= 0){
return board[x][y];
}
else
return '\0';
}
And the problem is that my program of evaluating who is the winner is not working as expected.
This program checks whether the king of each team is still in the chessboard, so the board array.
It should return 0 if both are still alive, 1, if only the white king is alive, and 2 if only the black king is alive.
I have made a program, or at least tried to make one, that goes through each coordinate and checks if there is a character 'K', which represents the white king, and 'S', the black king.
I have set the boolean kingIsAlive to false, so that if there is no K or S found in the array, it remains false.
Though, my code at the bottom, with the if and else that returns 0,1 or2, has the error, that kingWhiteIsAlive is always false and kingBlackIsAlive is always false.
So, I think my program of turning the kingIsAlive boolean to true is not working at all....
The errors I got is:
White should have won => expected: <1> but was: <-1>
No one should have won => expected: <0> but was: <1>
And after a couple of hours trying, I gave up and decided to ask here.
public int decideWinner(){
boolean kingWhiteIsAlive = false;
boolean kingBlackIsAlive = false;
for(int y = 0; y < board.length;y++){
for(int x = 0;x < board[0].length;x++){
if(get(x,y) == 'K'){
kingWhiteIsAlive = true;
}
}
}
for(int j = 0; j < board.length;j++){
for(int i = 0;i < board[0].length;i++){
if(get(i,j) == 'S'){
kingBlackIsAlive = true;
}
}
}
if(kingWhiteIsAlive && kingBlackIsAlive){
return 0;
}
else if(kingWhiteIsAlive && !kingBlackIsAlive){
return 1;
}
else if(!kingWhiteIsAlive && kingBlackIsAlive){
return 2;
}
else
return -1;
}
return -1 is for a test case that there are no kings from both teams.
I've tested your code & it's running perfectly, perhaps the problem is in your board initialization?
Try to debug your code by showing the actual content of the array at the beginning of decideWinner function.
I've used this initialization for the board, if it might help.
public void initBoard() {
board = new char[8][8];
// Init pawns
for (int j = 0; j < board.length; j++) {
board[j][1] = 'P';
board[j][6] = 'P';
}
// Rooks
board[0][0] = 'R';
board[7][0] = 'R';
board[0][7] = 'R';
board[7][7] = 'R';
// Knights
board[1][0] = 'N';
board[6][0] = 'N';
board[1][7] = 'N';
board[6][7] = 'N';
// Bishops
board[2][0] = 'B';
board[5][0] = 'B';
board[2][7] = 'B';
board[5][7] = 'B';
// Queens
board[3][0] = 'Q';
board[4][7] = 'Q';
// Kings
board[4][0] = 'K'; // White
board[3][7] = 'S'; // Black
// Empty space
for (int y = 0; y < board.length; y++) {
for (int x = 2; x < 6; x++) {
board[y][x] = ' ';
}
}
}
If you find a king, you need to interrupt your search. You can do it by a break statement.
for(int y = 0; y < board.length;y++){
for(int x = 0;x < board[0].length;x++){
if(get(x,y) == 'K'){
kingWhiteIsAlive = true;
break;
}
}
}
for(int j = 0; j < board.length;j++){
for(int i = 0;i < board[0].length;i++){
if(get(i,j) == 'S'){
kingBlackIsAlive = true;
break;
}
}
}

For-loop involved in Diagonal Check for Connect Four

So I am currently coding Connect 4 on Netbeans. I have the vertical and horizontal check already made but I am having trouble with the diagonal check, specifially the for loops. Currently my code for this,
public static boolean checkDiagnol(String[][] board, int counter, String playerMoving, int lastPlacedTileRow, int col) {
for (int i = lastPlacedTileRow-1; q = col-1; i >= 0, q >=0; i--,q--){
if (board[i][q] == playerMoving) {
counter += 1;
} else {
break;
}
if (counter > 4) {
return true;
}
}
for (int i = lastPlacedTileRow + 1, q = col +1; i < board.length, q < board[0].length; i++,q++) {
if (board[i][q] == playerMoving) {
counter += 1;
} else {
break;
}
if (counter > 4) {
return true;
}
}
return false;
}
lastPlacedTileRow is the row of the last placed tile, col is the column chosen by the user, counter is a counter used to check if there are 4 tiles in a row, and playerMoving is the current players tile.
The current problem I have is that my for loops give errors. This is my first time using two variables in a single for loop so I am not sure how it is supose to be arranged.
Thanks for the help
Syntax
You have put a semicolon instead of a comma in the first for loop.
for (int i = lastPlacedTileRow-1; q = col-1; i >= 0, q >=0; i--,q--){
this should be
for (int i = lastPlacedTileRow-1, q = col-1; i >= 0, q >=0; i--,q--){
Logic
I think variable i should be counted down (or up) in both the loops because we have to check below the lastPlacedTileRow in both cases.

Why won't the loop stop iterating?

I am a beginner java student writing a gui tic-tac-toe program for my class. (No players, just computer generated).
Everything in my program works as expected, except for one thing; it seems that the placement of my method call for checkWinner is not place correctly, because the assignment for the X's and O's always finish. Why won't the loop end as soon as there is a winner?
It will return the correct winner based on the method call, but the for-loop will continue to iterate and fill in the rest (so sometimes it looks like both the x and o win or one wins twice). I've been going crazy, thinking it might be the placement of my checkWinner method call and if statement. When I set the winner = true; shouldn't that cancel the loop? I have tried putting it between, inside and outside each for-loop with no luck :(
I have marked the area I think is the problem //What is wrong here?// off to the right of that part the code. Thank you for any input!! :)
public void actionPerformed(ActionEvent e)
{
int total = 0, i = 0;
boolean winner = false;
//stop current game if a winner is found
do{
// Generate random # 0-1 for the labels and assign
// X for a 0 value and O for a 1 value
for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
//Generate random number
gameboard[row][col] = (int)(Math.random() * 2);
//Assign proper values
if(gameboard[row][col] == 0)
{
labels[i].setText("X");
gameboard[row][col] = 10; //this will help check for the winner
}
else if(gameboard[row][col] == 1)
{
labels[i].setText("O");
gameboard[row][col] = 100; //this will help check for winner
}
/**Send the array a the method to find a winner
The x's are counted as 10s
The 0s are counted as 100s
if any row, column or diag = 30, X wins
if any row, column or diag = 300, Y wins
else it will be a tie
*/
total = checkWinner(gameboard); **//Is this okay here??//**
if(total == 30 || total == 300) //
winner = true; //Shouldn't this cancel the do-while?
i++; //next label
}
}//end for
}while(!winner);//end while
//DISPLAY WINNER
if(total == 30)
JOptionPane.showMessageDialog(null, "X is the Winner!");
else if(total == 300)
JOptionPane.showMessageDialog(null, "0 is the Winner!");
else
JOptionPane.showMessageDialog(null, "It was a tie!");
}
The easiest way would be to break all loops at once. (Even if some people dont like this)
outerwhile: while(true){
// Generate random # 0-1 for the labels and assign
// X for a 0 value and O for a 1 value
for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
total = checkWinner(gameboard);
if(total == 30 || total == 300)
break outerwhile; //leave outer while, implicit canceling all inner fors.
i++; //next label
}
}//end for
}//end while
This However would not allow for the "tie" option, because the while will basically restart a game, if no winner has been found. To allow tie, you dont need the outer while at all, and can leave both fors at once, when a winner is found:
Boolean winner = false;
outerfor: for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
total = checkWinner(gameboard);
if(total == 30 || total == 300){
winner = true;
break outerfor; //leave outer for, implicit canceling inner for.
}
i++; //next label
}
}//end for
if (winner){
//winner
}else{
//tie.
}
First of all, your code iterates through a board and generates random marks of X and O. This leads to some very odd board states, being always filled row-by-row, and possibly with unbalanced number of X and O marks.
IMHO you should organize your code in opposite manner to fill a board similary to a true game. I mean a series of 9 marks 'XOXOXOXOX' spreaded over the board.
Let Labels labels be a nine-character array, initialized to 9 spaces.
public int doGame( Labels labels)
{
labels = " ";
int itisXmove = true; // player X or O turn
for( int movesLeft = 9; movesLeft > 0; movesLeft --)
{
int position = // 0 .. movesLeft-1
(int) Math.floor(Math.random() * movesLeft);
for( int pos = 0; pos < 9; pos ++) // find position
if( labels[ pos] == " ") // unused pos?
if( position-- == 0) // countdown
{
if( itisXmove) // use the pos
labels[ pos] = "X"; // for current player
else
labels[ pos] = "O";
break;
}
int result = checkWinner( labels); // who wins (non-zero)?
if( result != 0)
return result;
itisXmove = ! itisXmove; // next turn
}
return 0; // a tie
}
then
public void actionPerformed(ActionEvent e)
{
Labels labels;
int result = doGame( labels);
if( result == valueForX)
JOptionPane.showMessageDialog(null, "X is the Winner!");
else if( result == valueForO)
JOptionPane.showMessageDialog(null, "O is the Winner!");
else
JOptionPane.showMessageDialog(null, "It's a tie!");
for( int rowpos = 0; rowpos < 9; rowpos += 3)
{
for( int colpos = 0; colpos < 3; colpos ++)
/* output (char)label[ rowpos + colpos] */;
/* output (char)newline */;
}
}
I think you should change your loop condition and add one more bool.
You have a "tie" condition but currently you only check for winner. The only explanation without the checkWinner code is that you are encountering a tie every time.
So...
boolean tie;
boolean winner;
do {
//your stuff
}
while(!(tie || winner))
Edit: I didn't realize you put the while loop outside your for loop, you will need to break out of your for loops in order for the while condition to be checked.
//stop current game if a winner is found
do{
for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
if(winner || tie)
break;
}//end for
if(winner || tie)
break;
}//end for
}while(!(winner || tie));//end while
//the rest of your stuff here
You're not checking the value of winner until both for loops complete. Add a break right after you set winner = true, and add an
if (winner)
{
break;
}
to the beginning or end of your outer for loop.
Your issue is that your do/while statement is wrapped around the for statements. So the for statements end up running their entire cycle before it ever reaches the while statement. A solution to get around this is checking for a winner in the for statements and breaking:
//stop current game if a winner is found
do {
for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
// ... your other code ...
total = checkWinner(gameboard);
if(total == 30 || total == 300) {
winner = true;
break; // end current for-loop
}
i++; //next label
}
if (winner) break; // we have a winner so we want to kill the for-loop
} //end for
} while(!winner); //end while
So you should be able to just loop through the two for-statements and break upon a winner. Your code also does not seem to handle a tied case, but I am guessing you already know that.

Java: Programming a simple maze game

I'm coding a simple maze game in java. The program reads in a text "map" from an input file for the layout of the maze. The rules are simple: navigate the maze (represented by a 2D array) through user input and avoid the cave-ins (represented by Xs), and get to the 'P' (player) the the spot marked 'T'. Right now, I've got most of the code written, it's just a matter of getting it to work properly. I've set up most of the game to run with a while loop, with the boolean "got treasure" set to false. Once this rings true, it should end the game.
However, I haven't coded the circumstance in which the player actually gets the treasure though, so I'm wondering why my code simply spits out "Congratulations! You've found the treasure!" and nothing else. If anyone could shed some light on this, I'd be very grateful. My code is somewhat of a mess of loops, as our teacher has just gotten to methods, constructors, and creating our own classes. Here is the code I have so far:
import java.util.*;
import java.io.File;
public class MazeGame {
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(new File("maze.txt"));
Scanner user = new Scanner(System.in);
int rows = scan.nextInt();
int columns = scan.nextInt();
int px = 0;
int py = 0;
String [][] maze = new String[rows][columns];
String junk = scan.nextLine();
for (int i = 0; i < rows; i++){
String temp = scan.nextLine();
String[] arrayPasser = temp.split("");
for (int j = 0; j < columns; j++){
maze[i][j] = arrayPasser[i];
}
}
boolean gotTreasure = false;
while (gotTreasure = false){
for (int i = 0; i < rows; i++){
for (int j = 0; j < columns; j++){
System.out.print(maze[i][j]);
System.out.print(" ");
}
System.out.print("\n");
}
System.out.printf("\n");
System.out.println("You may:");
System.out.println("1) Move up");
System.out.println("2) Move down");
System.out.println("3) Move left");
System.out.println("4) Move right");
System.out.println("0) Quit");
int choice = user.nextInt();
int i = 0;
if (choice == 1 && i >= 0 && i < columns){
for (int k = 0; k < rows; k++){
for (int l = 0; l < columns; l++){
if (maze[k][l].equals(maze[px][py]) && maze[px][py-1].equals("X") == false){
maze[px][py] = ".";
maze[k][l-1] = "P";
maze[px][py] = maze[k][l-1];
}else if (maze[px][py-1] == "X"){
System.out.println("Cannot move into a cave-in! Try something else.");
}else {
continue;}
}
}
}
else if (choice == 2 && i >= 0 && i < columns){
for (int k = 0; k < rows; k++){
for (int l = 0; l < columns; l++){
if (maze[k][l].equals(maze[px][py]) && maze[px][py+1].equals("X") == false){
maze[px][py] = ".";
maze[k][l+1] = "P";
maze[px][py] = maze[k][l+1];
}else if (maze[px][py+1] == "X"){
System.out.println("Cannot move into a cave-in! Try something else.");
}else {
continue;}
}
}
}
else if (choice == 3 && i >= 0 && i < columns){
for (int k = 0; k < rows; k++){
for (int l = 0; l < columns; l++){
if (maze[k][l].equals(maze[px][py]) && maze[px-1][py].equals("X") == false){
maze[px][py] = ".";
maze[k-1][l] = "P";
maze[px][py] = maze[k-1][l];
}else if (maze[px-1][py] == "X"){
System.out.println("Cannot move into a cave-in! Try something else.");
}else {
continue;}
}
}
}
else if (choice == 4 && i >= 0 && i < columns){
for (int k = 0; k < rows; k++){
for (int l = 0; l < columns; l++){
if (maze[k][l].equals(maze[px][py]) && maze[px+1][py].equals("X") == false){
maze[px][py] = ".";
maze[k+1][l] = "P";
maze[px][py] = maze[k+1][l];
}else if (maze[px+1][py] == "X"){
System.out.println("Cannot move into a cave-in! Try something else.");
}else {
continue;}
}
}
}
else if (choice == 0){
System.exit(0);
}
}
System.out.println("Congratulations, you found the treasure!");
scan.close();
user.close();
}
}
And here is the sample input file:
5 5
P.XX.
.X...
...X.
XXT..
..X..
(sigh) one equals sign instead of two. You have "while (gotTreasure = false)", which assigns the value false to gotTreasure and does not enter the loop. Change it to "while (gotTreasure == false) and it enters the loop.
For future questions: please attempt to figure out on your own what is happening, and let others know what you have tried and what specific questions you have about it. It is arguable I should just have let this go, since it is essentially a request to debug your code for you. Learn to debug yourself. If trace statements aren't getting executed, it's most likely the code at that point isn't getting executed. If a loop isn't getting entered, it is almost certainly because the conditions for entering the loop don't exist.
Learn to use a debugger - eclipse (and, I am sure, lots of other development tools) has an excellent one. Find out what a breakpoint is, how to set it and examine variables when it is hit, and figure out from there what has gone wrong.
If this is a typo ignore this, if it isnt
while (gotTreasure = false) is wrong.
you are not checking if gotTreasure is false, you are assigning it false.
to check if gotTreasure is false use == operator
while(gotTreasure==false)
lemme know if this is a type, i ll delete the answer. :)
You have a simple mistake in your while loop condition,
Instead of,
while (gotTreasure = false)
You should use,
while (gotTreasure == false)
In the first case, you are assigning false to gotTreasure and in the second you are evaluating if gotTreasure is false.
I refeactored your code, because there are a lot of bad programming-styles. Now the game should run as intended.
I used a Construktor and a lot of methods, to divide your big method in small parts. -> easier to understand.
I declared attributes (known in the whole class), so that the different methods can use this variables.
You often checked for a condition like if(variable == false). Try to use if(!variable), the exclamation mark negates the value of the variable.
Your update-Methode had a lot of redundandancies.
By adding the following switch-case-Part, I could seperate the different directions:
General code for setting directions by a userinput:
switch (choice){
case 0: System.exit(0);
case 1: xdir = 0; ydir = -1; break;
case 2: xdir = 0; ydir =1; break;
case 3: xdir = -1; ydir = 0; break;
case 4: xdir = 1; ydir = 0; break;
}
Afterwards I could calculate the new position by adding xdir to x and ydir to y. This comes handy, if you try to check if the new position is in the bounds of the array.
//1. Check if the new position is in the array.
if (x+xdir >= 0 && x+xdir <columns && y+ydir >=0 && y+ydir < rows){
Here follows the whole class:
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class MazeGame2 {
Scanner scan;
Scanner user;
int rows;
int columns;
String [][] maze;
int x; //Player x-Position
int y; //Player y-Position
boolean gotTreasure;
/**
* Konstruktor for the class.
*/
public MazeGame2(){
init();
game();
scan.close();
user.close();
}
/**
* Initialisation of the maze and all attributes.
*/
public void init(){
user = new Scanner(System.in); //Scanner for Userinput
/********************************
* Scanning the maze from a file.
*/
//1. Open the file. Has to be in a try-catch-Bracket, because the file might not be there.
try{
scan = new Scanner(new File("maze.txt"));
}catch(FileNotFoundException e){
e.printStackTrace();
}
//2. Scan the dimensions of the maze.
rows = scan.nextInt();
columns = scan.nextInt();
scan.nextLine(); // So that the next Line can be scanned.
maze = new String[rows][columns];//Create the maze-Array with the right dimensions.
for (int i = 0; i < rows; i++){
String temp = scan.nextLine(); //Scan one line.
for (int j = 0; j < columns; j++){
maze[i][j] = temp.substring(j, j+1);//Put every character in the maze
if (maze[i][j].equals("P")){ //Look out for the Player-Position
x = j;
y = i;
}
}
}
gotTreasure = false;
}
/**
* Prints the Input of the maze-Array. But only if the spots are visible by the player.
*/
public void printMaze(){
for (int i = 0; i < rows; i++){
for (int j = 0; j < columns; j++){
System.out.print(maze[i][j]);
System.out.print(" ");
}
System.out.println();
}
}
/**
* Prints the possebilities to move by the player.
*/
public void printUserPossebilities(){
System.out.println();
System.out.println("You may:");
System.out.println("1) Move up");
System.out.println("2) Move down");
System.out.println("3) Move left");
System.out.println("4) Move right");
System.out.println("0) Quit");
}
/**
*
*/
public void update(int choice){
int xdir=0;
int ydir=0;
// Update the direction based on the userChoice
switch (choice){
case 0: System.exit(0);
case 1: xdir = 0; ydir = -1; break;
case 2: xdir = 0; ydir =1; break;
case 3: xdir = -1; ydir = 0; break;
case 4: xdir = 1; ydir = 0; break;
}
/**
* Update the situation based on the current direction and step.
*/
//1. Check if the new position is in the array.
if (x+xdir >= 0 && x+xdir <columns && y+ydir >=0 && y+ydir < rows){
//2. Check if a step is possible
if (maze[y+ydir][x+xdir].equals("X")){
System.out.println("Cannot move into a cave-in! Try something else.");
}else{
//3. clear the P from the old Position
maze[y][x] =".";
//4. Check if the Player is over the treasure
if (maze[y+ydir][x+xdir].equals("T")){
gotTreasure = true;
}
x = x+xdir;
y = y + ydir;
maze[y][x] = "P"; //Show the new position of the player.
}
}else{
System.out.println("That's not a possible Move.");
}
}
/**
* The game-Methode that includes the game-loop and
*/
public void game(){
while (!gotTreasure){
//System.out.print('\u000C');
printMaze();
printUserPossebilities();
int userInput = user.nextInt(); //Wait for userinput
update(userInput);
}
//System.out.print('\u000C');
printMaze();
System.out.println("Congratulations, you found the treasure!");
}
public static void main(String[] args){
MazeGame2 m = new MazeGame2();
}
}

Messed up recursion code for a board game

What I have to do here is to count the number of adjacent white blocks (in 2's) on a square board which is made up of random black(0's) and white(1's) blocks. The white blocks have to be at i+1,j || i-1,j || i,j+1 || i,j-1. Technically diagonals are not counted. I have provided an example below:
[1 0 1]
[1 1 0]
[0 1 0]
Here count == 3 (0,0)(1,0) and (1,0)(1,1) and (1,1)(2,1)
Here is my code:
public int count = 0;
boolean count(int x, int y, int[][] mat)
{
if(x<0 || y<0)
return false;
if(mat[x][y] == 0)
return false;
for(int i = x; i<mat.length; i++)
{
for(int j = y; j<mat[0].length; j++)
{
if(mat[i][j] == 1)
{
mat[i][j] = 0;
if(count(i-1,j,mat))
count++;
if(count(i,j-1,mat))
count++;
if(count(i+1,j,mat))
count++;
if(count(i,j+1,mat))
count++;
}
}
}
return true;
}
Short explanation of what I am trying to do here: I am going about finding 1's on the board and when I find one I change it to a 0 and check its up,down,left,right for a 1. This goes on till I find no adjacent 1's. What is the thing I am missing here? I kind of have a feeling I am looping unnecessarily.
here's a solution without recursion
for(int i = 0; i < mat.length; i++) {
for(int j = 0; j < mat[i].length; j++) {
if(mat[i][j] == 1) {
if(i < mat.length - 1 && mat[i+1][j] == 1) {
count++;
}
if(j < mat[i].length - 1 && mat[i][j+1] == 1) {
count++;
}
}
}
I don't think recursion is the right answer as you should only being going one step deep (to find the adjacent value). Instead just loop through the elements looking to the right and down. Don't look up or left as twain mentioned so that you don't double count matches. Then is it simply:
for (i=0; i<max; i++)
for (j=0; j<max; j++)
if (array[i][j] == 1){
if (i<max-1 && array[i+1][j] == 1) count++;
if (j<max-1 && array[i][j+1] == 1) count++;
}

Categories