Java maze won't print - java

I have to make a maze for a java assignment, and I was able to finish most of it. I was provided with an outline of the code that had all the methods. Can someone help me? My issue is that the maze wont print out, and I can't figure out why.
package maze;
public class Maze {
private char direction;
private int r; // x position of the mouse
private int c; //y position of the mouse
private boolean exitFound = false;
public Maze(int[][] arrMaze) {
this.r = arrMaze.length - 1;
this.c = 0;
}
//Prints out the maze without solution
public void displayMaze(int[][] arrMaze)
{
//display the maze putting blank spaces where there are 1's in the array and putting
//another symbol where there are 0's to show the maze without the solution
for(int i=0; i<arrMaze.length; i++){
System.out.println(" ");
for(int j=0; j<arrMaze[i].length; j++){
if(arrMaze[i][j] == 0){
System.out.print("#");
} if(arrMaze[i][j] == 1) {
System.out.print(" ");
} if(arrMaze[i][j] == 2){
System.out.print("#");
} if(arrMaze[i][j] == 3){
System.out.println("~");
}
}
}
}
//displays the Maze with the path taken
public void displayPath(int[][] arrMaze)
{
//show the user how far the mouse has gone since the start.
//The path the mouse has gone will be filled in but the path ahead will not.
for (int i = 0; i < arrMaze.length; i++) {
System.out.println(" ");
for (int j = 0; j < arrMaze[i].length; j++) {
if (arrMaze[i][j] == 3) {
System.out.print("#");
} else if (arrMaze[i][j] == 2) {
System.out.print("~");
} else if (arrMaze[i][j] == 0) {
System.out.print("#");
} else {
}
}
}
}
public boolean takeStep(int[][] newMaze) {
// moveNorth(newMaze)
for (int i = 0; i < newMaze.length; i++) {
System.out.println(" ");
for (int j = 0; j < newMaze[i].length; j++) {
if (newMaze[r][c] == 3) {
moveNorth(newMaze);
System.out.print("~");
} else if (newMaze[r][c] == 2) {
System.out.print("#");
} else {
}
}
}
return isAnExit(newMaze);
}
public void moveNorth(int[][] arrMaze) {
//complete the code here
/*method will check for a 0 or a 1 in the position above the current position
* and then if not a 0 will change the current position to the row above it, but in the same column.
*/
if (arrMaze[r][c - 1] != 0) {
arrMaze[r][c - 1] = 3;
arrMaze[r][c + 1] = 2;
} else {
moveSouth(arrMaze);
}
displayPath(arrMaze);
}
public void moveSouth(int[][] arrMaze)
{
//method will check for a 0 or a 1 in the position below the current position and then if not a 0
//it will change the current position to the row below it, but in the same column.
if (arrMaze[r][c + 1] != 0) {
arrMaze[r][c + 1] = 3;
arrMaze[r][c + 1] = 2;
} else {
moveNorth(arrMaze);
}
displayPath(arrMaze);
}
public void moveEast(int[][] arrMaze) {
//method will check for a 0 or a 1 in the position to the right of  the current position and then if
//not a 0 will change the current position to the column to the right but the same row.
if (arrMaze[r + 1][c] != 0) {
arrMaze[r + 1][c] = 3;
arrMaze[r - 1][c] = 2;
} else {
moveWest(arrMaze);
}
displayPath(arrMaze);
}
public void moveWest(int[][] arrMaze) {
//method will check for a 0 or a 1 in the position to the left of  the current position and then if
//not a 0 will change the current position to the column to the left but the same row.
if (arrMaze[r - 1][c] != 0) {
arrMaze[r - 1][c] = 3;
arrMaze[r + 1][c] = 2;
} else {
}
displayPath(arrMaze);
}
private boolean isAnExit(int[][] arrMaze) {
//method will return true if the user arrives into the last column of the array because there is only one
//location in the last column that is a 1, so if the user reaches the array[i].length then that means that it found an exit.
if (arrMaze[r][c] > arrMaze.length) {
exitFound = true;
} else {
exitFound = false;
}
return exitFound;
}
//finds the path without stopping at every step
//method will show the complete path from start to finish of the maze and the suggested route to the end.
public void findExit(int[][] arrMaze) {
if (arrMaze[r][c] > arrMaze.length) {
for (int i = 0; i < arrMaze.length; i++) {
takeStep(arrMaze);
}
}
}
}
This is the test code. I was provided the test code, and I haven't changed it.
package maze;
import java.util.Scanner;
public class TestMaze
{
public static void main(String[] args)
{
int[][] mazeArray = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
{0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1},
{0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
Maze myMaze = new Maze(mazeArray);
boolean keepAsking = true;
Scanner scan = new Scanner(System.in);
String input = "";
myMaze.displayPath(mazeArray);
System.out.println("Maze");
do {
System.out.println("T = Take a step | S = Show path | Q = Quit");
System.out.print("Enter command: ");
input = scan.nextLine();
input.trim();
input.toLowerCase();
if(input.equals("t")) {
keepAsking = !myMaze.takeStep(mazeArray);
System.out.println("Which direction would you like to go? N, S, E, W?");
String direction = scan.nextLine();
if(direction.equalsIgnoreCase("n"))
myMaze.moveNorth(mazeArray);
if(direction.equalsIgnoreCase("s"))
myMaze.moveSouth(mazeArray);
if(direction.equalsIgnoreCase("e"))
myMaze.moveEast(mazeArray);
if(direction.equalsIgnoreCase("w"))
myMaze.moveWest(mazeArray);
}
else if(input.equals("s")) {
myMaze.findExit(mazeArray);
keepAsking = false;
}
else if(input.equals("q")) {
keepAsking = false;
}
else {
System.out.println("ERR: Invalid input");
}
} while(keepAsking);
System.out.println("Quitting program...");
scan.close();
}
}

You need to call displayMaze() (in displayPath()) to print it.
Currently, you're not calling the method, meaning that your code will never print the maze as it's no being instructed to.
Also, where are you assigning values to r and c? I think you meant to use i and j in your displayPath() method ([i][j] instead of [r][c]).

I imagine you're throwing an error somewhere because your r and c values are undefined everywhere they are used. Try adding code to initialize and update these values, then you should see your maze print.

Related

How can I move this into a other class

I am working on a Four in a row game.
But I have run into a problem with it. I have been able to make the game work. But I would like to know if I can move my public void fillBoard() and public void presentBoard() into another class. This is because I would like to make the code more organised.
package com.company;
public class Main {
public static void main(String[] args)
{
GameMechanics game = new GameMechanics();
game.play();
}
}
package com.company;
import java.util.Scanner;
public class GameMechanics
{
/*
This is my local variables
*/
public Scanner scanner = new Scanner(System.in);
public char token;
public int column;
public int player = 2;
public int turn = 2;
public int count = 0;
public boolean gameRunning = true;
public void play()
{
this.createBoard();
//While gameRunning is true, the methods inside the { } will run, and that's the 4InARow game
while (gameRunning)
{
this.presentBoard();
this.changeTurn();
this.dropToken();
this.gameWon();
}
presentBoard();
}
public void gameWon()
{
this.winConHorizontal();
this.winConVertical();
}
private char[][] board = new char[6][7];
//Creating my board and assign "space" to all the fields in the array.
public void createBoard() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
//Presents the board, it prints the board with |"space"| so it looks more like a gameboard.
public void presentBoard() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (j == 0) {
System.out.print("|");
}
System.out.print(board[i][j] + "|");
}
System.out.println();
}
}
public void changeTurn() {
if (this.turn == this.player) {
this.turn = 1;
this.token = 'X';
} else {
this.turn++;
this.token = 'O';
}
}
public void dropToken() {
System.out.println("player " + turn + ": press 1-7 to drop the token");
column = scanner.nextInt() - 1;
//If pressed any intValue outside the board, it will tell you to try again.
if (column >= 7 || column <= -1)
{
System.out.println("place the token inside the bord");
changeTurn();
} else {
//Drops the token and replace it with playerChar.
for (int i = 5; i > -1; i--) {
if (board[i][column] == ' ')
{
board[i][column] = token;
break;
}
}
}
}
public boolean winConHorizontal() {
while (gameRunning) {
for (int i = 0; 6 > i; i ++) {
for (int j = 0; 7 > j; j ++) {
if (board[i][j] == this.token) {
count ++;
} else {
count = 0;
}
if (count >= 4) {
System.out.println("player " + (turn) + " Wins!!!!");
gameRunning = false;
}
}
}
break;
}
return gameRunning;
}
public boolean winConVertical() {
while (gameRunning) {
for (int i = 0; 7 > i; i ++) {
for (int j = 0; 6 > j; j ++) {
if (board[j][i] == this.token) {
count ++;
} else {
count = 0;
}
if (count >= 4) {
System.out.println("player " + (turn) + " Wins!!!!");
gameRunning = false;
}
}
}
break;
}
return gameRunning;
}
}
An easy way to do this is as follows:
extract your char[][] board into its own class, e.g. Board
Said class could expose the function char getField(int index)
Extract the ,,presenting" part of your code into another class, e.g. BoardPresenter. Said class should have a function presentBoard(Board board) which internally uses getField(int index) of the Board class.
By doing this you abstract away your internal board storage mechanism while also reducing the number of responsibilities the GameMechanics class has (See https://en.wikipedia.org/wiki/Single_responsibility_principle)
yes, you can make another class and extend it with the current class GameMechanics and inside another class you can define the functions.
Note : This is a very simple approachable way.
Otherwise better if you manage your classes and interfaces similar to mvc model, for which you can search youtube for mvc structure java.

To test, using a backtracking algorithm, if a mouse can escape from a rectangular maze

This program has is meant to create and solve a mouse escape route from a maze, by reading from a text file.There is a Maze class which is basically a 2D array of MazeElements, the MazeElements contains a char variable and a position object; the Position holds the co-ordinates of each element on the 2D-array.
So far, the program effectively reads in and creates the 2D array. The problem lies in the backTracking algorithm. I am using a stack to implement the back track but the backtrack seems to only loop once from the output. I don't know if you can notice something from the code below:
import java.io.;
import java.util.;
public class MazeSolver
{
public static void main (String [] parms)
{
Maze maze = new Maze();
maze.displayMaze();
maze.backTracking();
maze.displayMaze();
}
}
//**********************************
//*******Position class*************
//**********************************
class Position
{
private int row;
private int col;
public Position()
{
row =0;
col =0;
}
public Position (int x, int y)
{
row = x;
col = y;
}
public void setRow(int x)
{
row = x;
}
public void setCol(int y)
{
col = y;
}
public int getRow()
{
return row;
}
public int getCol()
{
return col;
}
//NOTE: wrote for testing purposes, to see the mouse and exit positions
public String getPosition()
{
return row + ", " + col;
}
}//end Position
//**********************************
//*******Maze element class*********
//**********************************
class MazeElement
{
private char letter;
private Position prevPosition;
public MazeElement(char c, Position p)
{
this.letter = c;
this.prevPosition = p;
}
public char getLetter()
{
return letter;
}
public Position getPosition()
{
return prevPosition;
}
public void setPosition(Position p)
{
this.prevPosition = p;
}
public void setLetter(char c)
{
this.letter = c;
}
public void printElement()
{
System.out.print(letter + " ");
}
}//end MazeElement
//**********************************
//*******Maze class*****************
//**********************************
class Maze
{
private MazeElement [][] maze;
private int numRows;
private int numCols;
private Position start;
private Position exit;
BufferedReader inFile;
Scanner kbd = new Scanner(System.in);
String inLine;
String fileName;
String [] tokens;
public Maze()
{
try
{
System.out.println("Input file name");
fileName = kbd.next();
inFile = new BufferedReader(new FileReader(fileName));
inLine = inFile.readLine();
tokens = inLine.trim().split("\\s+");
numRows = Integer.parseInt(tokens[0]);
numCols = Integer.parseInt(tokens[1]);
maze = new MazeElement[numRows][numCols];
for(int row = 0; inLine != null && row < numRows; row++)
{
inLine = inFile.readLine();
tokens = inLine.trim().split("\\s+");
for(int col = 0; col < numCols; col++)
{
maze[row][col] = new MazeElement(tokens[col].charAt(0),null);
}
}
inFile.close();
//finding m and e from the maze
for (int i = 0; i < maze.length; i++)
{
for (int j = 0; j < maze[i].length; j++)
{
char letter = maze[i][j].getLetter();
if(letter == 'm')
{
start = new Position(i,j);
}
if(letter == 'e')
{
exit = new Position(i,j);
}
}
}
}//end try block
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
}
}//end public Maze()
public void backTracking()
{
Stack<Position> theStack = new Stack<Position>();//initialise stack
Position goal = exit;
Position curr;
MazeElement north, south, east, west;
int currRow, currCol;
curr = null;
boolean foundGoal = false;
theStack.push(start);
while((!foundGoal) && (!theStack.isEmpty()))
{
curr = theStack.pop();
currRow = curr.getRow();
currCol = curr.getCol();
//check neighbouring positions
east = maze[currRow][currCol+1];
south = maze[currRow+1][currCol];
west = maze[currRow][currCol-1];
north = maze[currRow-1][currCol];
//searching clockwise
//setting visited positions to '.', open = '0', wall = '1', exit==goal = 'e'
if(isValidPosition(east))
{
if(east.getLetter() == 'e')
{
east.setPosition(curr);
theStack.push(east.getPosition());
foundGoal = true;
}
else if((!foundGoal)&&(east.getLetter() == '0')&& (east.getLetter() != '.'))
{
east.setLetter('.');
east.setPosition(curr);
theStack.push(east.getPosition());
}
}
else if(isValidPosition(south))
{
if(south.getLetter() == 'e')
{
south.setPosition(curr);
theStack.push(south.getPosition());
foundGoal = true;
}
else if((!foundGoal)&&(south.getLetter() == '0')&& (south.getLetter() != '.'))
{
south.setLetter('.');
south.setPosition(curr);
theStack.push(south.getPosition());
}
}
else if(isValidPosition(west))
{
if(west.getLetter() == 'e')
{
west.setPosition(curr);
theStack.push(west.getPosition());
foundGoal = true;
}
else if((!foundGoal)&&(west.getLetter() == '0')&& (west.getLetter() != '.'))
{
west.setLetter('.');
west.setPosition(curr);
theStack.push(west.getPosition());
}
}
else if(isValidPosition(north))
{
if(north.getLetter() == 'e')
{
north.setPosition(curr);
theStack.push(north.getPosition());
foundGoal = true;
}
else if((!foundGoal)&&(north.getLetter() == '0')&& (north.getLetter() != '.'))
{
north.setLetter('.');
north.setPosition(curr);
theStack.push(north.getPosition());
}
}
}//end while
}
public void displayMaze()
{
for (int i = 0; i < maze.length; i++)
{
for (int j = 0; j < maze[i].length; j++)
{
maze[i][j].printElement();
}
System.out.println();
}
System.out.println("start is at " + start.getPosition());
System.out.println("exit is at " + exit.getPosition());
}//displayMaze()
public boolean isValidPosition(MazeElement element)
{
char wall = '1';
return (element.getLetter() != wall);
}
}
//**********************************
//*******Stack<E> class*************
//**********************************
class Stack<E>
{
protected Node<E> head;
public Stack()
{
head = null;
}
public boolean isEmpty()
{
return (head == null);
}
public void push(E item)
{
head = new Node<E>(item, head);
}
public E top()
{
E topItem = null;
if (head != null) topItem = head.getData();
return topItem;
}
public E pop()
{
E topItem = top();
if (head != null) head = head.getNext();
return topItem;
}
}
//**********************************
//*******Node class*****************
//**********************************
class Node <E>
{
private E data;
private Node<E> next;
public Node ()
{
//initializing everything to null at first
next = null;
data = null;
}
public Node(E data, Node <E> n)
{
this.data = data;
this.next = n;
}
public E getData()
{
return data;
}
public Node <E> getNext()
{
return next;
}
public void setNext(Node <E> next)
{
this.next = next;
}
}
My input file is the following:
6 5
1 1 1 1 1
1 0 0 e 1
1 1 1 0 1
1 m 1 0 1
1 0 0 0 1
1 1 1 1 1
When I print the maze after I call the backTrack() method, my Maze(with m and e positions) becomes:
1 1 1 1 1
1 0 0 e 1
1 1 1 0 1
1 m 1 0 1
1 . 0 0 1
1 1 1 1 1
start is at 3, 1
exit is at 1, 3
The issue is that I do not understand why my curr doesn't move beyond the point '.' in the output. Please help?
Here:
if(isValidPosition(east))
{
if(east.getLetter() == 'e')
{
east.setPosition(curr);
theStack.push(east.getPosition());
foundGoal = true;
}
else if((!foundGoal)&&(east.getLetter() == '0')&& (east.getLetter() != '.'))
{
east.setLetter('.');
theStack.push(east.getPosition());
}
}
Original :
From what I can tell, the only thing that has been pushed into theStack is start. So, curr == start. Then, in your conditions, if it meets the directions you do:
east.setPosition(curr);
theStack.push(east.getPosition());
(Or whichever direction it tests on, in this case it's actually south).
Remember, the first time curr == start, so you're setting east.setPosition == curr == start, which means you push back to the stack start.
Now, the code runs again with only 1 thing in the theStack and it's the same as it was before, EXCEPT, the character below start is now a '.', so there are no valid directions and your while loop breaks.
To fix the code, you'll have to push to theStack a Position whose values are the direction's and not update the direction position.
I made a few changes to your code, first to the map loading function, so that every element had a position. You can get rid of this and use rheStack.push(new Position(row,col)); but i was too lazy.
for(int row = 0; inLine != null && row < numRows; row++)
{
inLine = inFile.readLine();
tokens = inLine.trim().split("\\s+");
for(int col = 0; col < numCols; col++)
{
maze[row][col] = new MazeElement(tokens[col].charAt(0),new Position(row,col));
}
}
The next change is to the backtracking code. Now in essence you can backtrack using only a stack, however it is not enough to just store the places you have been. For example, after if you first went east and then west, then you need to store that on the stack as well. This makes backtracking more complicated, however programming languages gives us a much easier way of dealing with stacks - recursion.
All the parameters passed to a function, and all the temporaries it creates, are stored on a special stack - the program stack. This is the same stack referenced in StackOverflow. Therefore recursive functions have all the same strucutre as a backtracking alogorithm.
So I broke you backtracking algorithm to make it recursive
public void backTracking()
{
Stack<Position> theStack = new Stack<Position>();//initialise stack
theStack.push(start);
//pass it the stack and the goal
backTrackingRecursive(theStack, exit);
}
public boolean backTrackingRecursive(Stack<Position> theStack, Position goal)
{
//displayMaze();
Position curr = theStack.top();
int currRow = curr.getRow();
int currCol = curr.getCol();
//setting visited positions to '.', open = '0', wall = '1', exit==goal = 'e'
for(int i = 0; i != 4; i++)
{
//forget this code, it is only to avoid writing out north, south, etc
int col = currCol;
int row = currRow;
if(i%2 == 1)
col += ((i==1)?1:-1);
else
row += ((i==2)?1:-1);
//check it is a valid position, if not continue
if(row < 0 || row >= numRows || col < 0 || col >= numCols) continue;
MazeElement next = maze[row][col];
if(next.getLetter() == 'e')
{
theStack.push(next.getPosition());
return true;
}
else if(next.getLetter() == '0')
{
theStack.push(next.getPosition());
next.setLetter('.');
if(backTrackingRecursive(theStack,goal))
{
//success!
return true;
} else {
//try a different path
next.setLetter('0');
theStack.pop();
}
}
}
return false;
}
The backTrackingRecursive function does all the work, and we simply push the next position on to the stack before continuing. We don't even need to have the stack at all but I kept it for simplicity.
Output:
1 1 1 1 1
1 0 0 e 1
1 1 1 0 1
1 m 1 0 1
1 0 0 0 1
1 1 1 1 1
start is at 3, 1
exit is at 1, 3
1 1 1 1 1
1 0 0 e 1
1 1 1 . 1
1 m 1 . 1
1 . . . 1
1 1 1 1 1
start is at 3, 1
exit is at 1, 3
this works perfectly!!!! i followed the comments from the first answer and found this solution! thank you #CreationEdge
if(isValidPosition(east))
{
if(east.getLetter() == 'e')
{
foundGoal = true;
}
if((!foundGoal)&&(east.getLetter() == '0')&& (east.getLetter() != '.'))
{
east.setLetter('.');
east.setPosition(curr);
theStack.push(new Position(curr.getRow(), curr.getCol()+1));
}
}
if(isValidPosition(south))
{
if(south.getLetter() == 'e')
{
System.out.println(south.getLetter());
foundGoal = true;
}
if((!foundGoal)&&(south.getLetter() == '0')&& (south.getLetter() != '.'))
{
south.setLetter('.');
south.setPosition(curr);
theStack.push(new Position(curr.getRow() + 1, curr.getCol()));
}
}
if(isValidPosition(west))
{
if(west.getLetter() == 'e')
{
foundGoal = true;
}
if((!foundGoal)&&(west.getLetter() == '0')&& (west.getLetter() != '.'))
{
west.setLetter('.');
west.setPosition(curr);
theStack.push(new Position(curr.getRow(), curr.getCol()-1));
}
}
if(isValidPosition(north))
{
if(north.getLetter() == 'e')
{
foundGoal = true;
}
if((!foundGoal)&&(north.getLetter() == '0')&& (north.getLetter() != '.'))
{
north.setLetter('.');
north.setPosition(curr);
theStack.push(new Position(curr.getRow() - 1, curr.getCol()));
}
}

Adding an array into another array (for a Java Battleship program)

I've been at this Battleship code for weeks on and off and I really have trouble putting multi-cell ships in it. The program works fine as is, but I want to add ships that contain 2-4 cells. I've tried all that I could to no avail, if anybody can give me help that would be really great.
Here's my code, it might be a bit confusing:
import java.util.Random;
import java.util.Scanner;
public class Battleship
{
private static int counter = 0;
private static boolean flag = true;
public static void main(String[] args)
{
int[][] boardP1 = new int[10][10];
int[][] boardP2 = new int[10][10];
int[][] shipsP1 = new int[10][2];
int[][] shipsP2 = new int[10][2];
int[] shootP1 = new int[2];
int[] shootP2 = new int[2];
int shotHitP1 = 0, shotHitP2 = 0;
Scanner userInput = new Scanner(System.in);
String p1name = null, p2name = null;
// Welcome message
System.out.println("\033[2J\033[10;28f WELCOME TO BATTLESHIPS!");
System.out.print("\033[13;31f Player 1: ");
p1name = userInput.nextLine();
System.out.print("\033[15;31f Player 2: ");
p2name = userInput.nextLine();
// Clear screen
System.out.println("\033[2J");
// Initialize boards (random)
initBoardsP1(boardP1);
initBoardsP2(boardP2);
// Initialize ships (random)
initShips(shipsP1);
initShips(shipsP2);
do
{ // Display boards
showBoardP1(boardP1);
showBoardP2(boardP2);
// P1 ask for shot
shootP1(shootP1);
counter++;
if (hit(shootP2,shipsP2))
{
shotHitP1++;
if (shotHitP1 == 5)
{ System.out.println("\n\n\n" +p1name+ " has won the game!");
System.out.println(); }
}
else
{ System.out.println("\033[48;36f Miss!"); }
changeboardP2(shootP1, shipsP1, boardP1);
System.out.print("\033[2J");
// P2 Ask for shot
showBoardP1(boardP1);
showBoardP2(boardP2);
shootP2(shootP2);
counter++;
if (hit(shootP1,shipsP1))
{
shotHitP2++;
if (shotHitP2 == 5)
{ System.out.println("\n\n\n" +p2name+ " has won the game!");
System.out.println(); }
}
else
{ System.out.println();
System.out.println("You missed!");
System.out.println(); }
changeboardP1(shootP2, shipsP2, boardP2);
System.out.print("\033[2J");
} while (shotHitP1 != 5 || shotHitP2 != 5);
}
public static void initShips(int[][] ships)
{
Random random = new Random();
for (int ship = 0; ship < 10; ship++)
{
ships[ship][0] = random.nextInt(10); // Draws row coordinate
ships[ship][1] = random.nextInt(10); // Draws column coordinate
// Check to see if already used combo
for (int last = 0; last < ship; last++)
{
if ((ships[ship][0] == ships[last][0]) && (ships[ship][1] == ships[last][1]))
do
{ ships[ship][0] = random.nextInt(10);
ships[ship][1] = random.nextInt(10); }
while((ships[ship][0] == ships[last][0])&&(ships[ship][1] == ships[last][1]));
}
}
}
public static void initBoardsP1(int[][] boardP1)
{ for (int row = 0; row < 10; row++)
for (int column = 0; column < 10; column++)
boardP1[row][column] = -1; }
public static void initBoardsP2(int[][] boardP2)
{ for (int row = 0; row < 10; row++)
for (int column = 0; column < 10; column++)
boardP2[row][column] = -1; }
public static void showBoardP1(int[][] boardP1)
{
if (flag = true)
{ System.out.println("\033[9;15f PLAYER 2");
System.out.println("\033[12;5f 1 2 3 4 5 6 7 8 9 10");
System.out.println("\033[13;4f +-++-++-++-++-++-++-++-++-++-+"); }
else
{ System.out.println("\033[9;54f PLAYER 1");
System.out.println("\033[12;45f 1 2 3 4 5 6 7 8 9 10");
System.out.println("\033[13;44f +-++-++-++-++-++-++-++-++-++-+"); }
for (int row = 0; row < 10; row++)
{
if (flag = true)
{ System.out.print("\033[1C"); }
else
{ System.out.print("\033[40C"); }
if (row <= 8)
{ System.out.print(" " +(row+1)+ " "); }
else
{ System.out.print(" 10 "); }
for (int column = 0; column < 10; column++)
{
System.out.print("|");
if (boardP1[row][column] == -1)
{ System.out.print(" "); }
else if (boardP1[row][column] == 0)
{ System.out.print("0"); }
else if (boardP1[row][column] == 1)
{ System.out.print("\033[1;31mX\033[0m"); }
System.out.print("|");
}
if (flag = true)
{ System.out.println();
System.out.println(" +-++-++-++-++-++-++-++-++-++-+"); }
else
{ System.out.println();
System.out.println("\033[40C +-++-++-++-++-++-++-++-++-++-+"); }
if ((counter % 100) == 0)
{ flag = true; }
else
{ flag = false; }
}
}
public static void showBoardP2(int[][] boardP2)
{
if (flag = true)
{ System.out.println("\033[9;54f PLAYER 1");
System.out.println("\033[12;45f 1 2 3 4 5 6 7 8 9 10");
System.out.println("\033[13;44f +-++-++-++-++-++-++-++-++-++-+"); }
else
{ System.out.println("\033[9;15f PLAYER 2");
System.out.println("\033[12;5f 1 2 3 4 5 6 7 8 9 10");
System.out.println("\033[13;4f +-++-++-++-++-++-++-++-++-++-+"); }
for (int row = 0; row < 10; row++)
{
if (flag = true)
{ System.out.print("\033[40C"); }
else
{ System.out.print("\033[1C"); }
if (row <= 8)
{ System.out.print(" " +(row+1)+ " "); }
else
{ System.out.print(" 10 "); }
for (int column = 0; column < 10; column++)
{
System.out.print("|");
if (boardP2[row][column] == -1)
{ System.out.print(" "); }
else if (boardP2[row][column] == 0)
{ System.out.print("0"); }
else if (boardP2[row][column] == 1)
{ System.out.print("\033[1;31mX\033[0m"); }
System.out.print("|");
}
if (flag = true)
{ System.out.println();
System.out.println("\033[40C +-++-++-++-++-++-++-++-++-++-+"); }
else
{ System.out.println();
System.out.println(" +-++-++-++-++-++-++-++-++-++-+"); }
if ((counter % 100) == 0)
{ flag = true; }
else
{ flag = false; }
}
}
public static void shootP1(int[] shootP1)
{
Scanner userInput = new Scanner(System.in);
System.out.println("\033[38;26f ----- PLAYER ONE'S SHOT -----");
System.out.println("\033[40;27f (Legend: 0 - Miss, \033[1;31mX\033[0m - Hit)");
System.out.println("\033[55;21f Press any non-integer character to quit.");
System.out.print("\033[44;35f Row: ");
shootP1[0] = userInput.nextInt();
shootP1[0]--;
System.out.print("\033[45;32f Column: ");
shootP1[1] = userInput.nextInt();
shootP1[1]--;
}
public static void shootP2(int[] shootP2)
{
Scanner input = new Scanner(System.in);
System.out.println("\033[38;26f ----- PLAYER TWO'S SHOT -----");
System.out.println("\033[40;27f (Legend: 0 - Miss, \033[1;31mX\033[0m - Hit)");
System.out.println("\033[55;21f Press any non-integer character to quit.");
System.out.print("\033[44;35f Row: ");
shootP2[0] = input.nextInt();
shootP2[0]--;
System.out.print("\033[45;32f Column: ");
shootP2[1] = input.nextInt();
shootP2[1]--;
}
public static boolean hit(int[] shoot, int[][] ships)
{
for (int ship = 0; ship < ships.length; ship++)
{
if (shoot[0] == ships[ship][0] && shoot[1] == ships[ship][1])
{
System.out.println("\033[48;34f KABOOM!!");
System.out.printf("\033[50;23f You hit a ship located in (%d,%d)!\n\n", shoot[0]+1, shoot[1]+1);
return true;
}
}
return false;
}
public static void changeboardP1(int[] shoot, int[][] ships, int[][] boardP1)
{
if (hit(shoot,ships))
{ boardP1[shoot[0]][shoot[1]] = 1; }
else
{ boardP1[shoot[0]][shoot[1]] = 0; }
}
public static void changeboardP2(int[] shoot, int[][] ships, int[][] boardP2)
{
if (hit(shoot,ships))
{ boardP2[shoot[0]][shoot[1]] = 1; }
else
{ boardP2[shoot[0]][shoot[1]] = 0; }
}
}
I don't understand the board/ship arrays in your code.
What are the extra arrays for ship for?
I suggest you make 1 array for each player's board filled with 0's at creation by default, and then add the boats by filling in 1's in the boats locations? and possibly later on in the game 2's for missed points and 3 for hits.
The only extra array you will need will be a 2D array containing 5 rows for the 5 ships and 2 columns specifying initial and ending coordinate of the ship that may later on be used to check if the entire ship has been destroyed or not.

Java Binary Tree entered in a specific order

I am trying to complete an assignment where I need to write a Java program to take a string from the command line, and implement it as a Binary Tree in a specific order, then get the depth of the binary tree.
For example: "((3(4))7((5)9))"
would be entered as a tree with 7 as the root, 3 and 9 as the children, and 4 as a right child of 3, and 5 as a left child of 9.
My code is below.. The problem I am having is that, because I am basing my checks off of finding a right bracket, I am unsure how to get the elements correctly when they are not directly preceding the brackets, such as the 3 in the above string. Any direction would be greatly appreciated..
class Node {
int value;
Node left, right;
}
class BST {
public Node root;
// Add Node to Tree
public void add(int n) {
if (root == null) {
root = new Node( );
root.value = n;
}
else {
Node marker = root;
while (true) {
if (n < marker.value) {
if (marker.left == null) {
marker.left = new Node( );
marker.left.value = n;
break;
} else {
marker = marker.left;
}
} else {
if (marker.right == null) {
marker.right = new Node( );
marker.right.value = n;
break;
} else {
marker = marker.right;
}
}
}
}
} // End ADD
//Find Height of Tree
public int height(Node t) {
if (t.left == null && t.right == null) return 0;
if (t.left == null) return 1 + height(t.right);
if (t.right == null) return 1 + height(t.left);
return 1 + Math.max(height(t.left), height(t.right));
} // End HEIGHT
// Check if string contains an integer
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
}
catch(NumberFormatException e) {
return false;
}
return true;
} // End ISINT
public int elementCount(String[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
if (isInt(a[i])) count++;
}
return count;
}
} // End BST Class
public class Depth {
public static void main(String[] args) {
String[] a = args[0].split(" ");
BST tree = new BST();
int[] bcount = new int[10];
int[] elements = new int[10];
int x = 0, bracketcount = 0;
// Display entered string
System.out.print("Entered Format: ");
for (int j=0; j < a.length; j++) {
System.out.print(a[j]);
}
for (int i=0; i < a.length; i++) {
char c = a[i].charAt(0);
switch (c)
{
case '(':
bracketcount++;
break;
case ')':
if (isInt(a[i-1])) {
bcount[x] = bracketcount--;
elements[x++] = Integer.parseInt(a[i-1]);
}
break;
case '1':
case '7':
default : // Illegal character
if ( (a[i-1].charAt(0) == ')') && (a[i+1].charAt(0) == '(') ) {
bcount[x] = bracketcount;
elements[x++] = Integer.parseInt(a[i]);
}
break;
}
}
System.out.println("\nTotal elements: " + tree.elementCount(a));
// Display BracketCounts
for (int w = 0; w < x; w++) {
System.out.print(bcount[w] + " ");
}
System.out.println(" ");
// Display Elements Array
for (int w = 0; w < x; w++) {
System.out.print(elements[w] + " ");
}
System.out.println("\nDepth: " + tree.height(tree.root));
// Build the tree
for (int y = 0; y < x-1; y++) {
for (int z = 1; z < tree.height(tree.root); z++) {
if (bcount[y] == z) {
tree.add(elements[y]);
}
}
}
} // End Main Function
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
} // End Depth Class
I would do a couple of statements to get access to a tree with that kind of shape:
For input string : input= "((3(4))7((5)9))"
You could do :
public class Trial {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String input = "((3(4))7((5)9))";
String easier = input.replaceAll("\\(\\(", "");
String evenEasier = easier.replaceAll("\\)\\)", "");
System.out.println(evenEasier);
int firstVal = Integer.parseInt(evenEasier.substring(0, 1));
int firstBracketVal = Integer.parseInt(evenEasier.substring(2, 3));
int middleVal = Integer.parseInt(evenEasier.substring(3, 4));
int secondBracketVal = Integer.parseInt(evenEasier.substring(4,5));
int lastVal = Integer.parseInt(evenEasier.substring(6));
System.out.println("First Val:"+firstVal);
System.out.println("First bracket Val:"+firstBracketVal);
System.out.println("Middle Val:"+middleVal);
System.out.println("Second Bracket Val:"+secondBracketVal);
System.out.println("Last Val:"+lastVal);
}
}
This however would only ever work for entries in that specific format, if that were to change, or the length of the input goes up - this would work a bit or break.....If you need to be able to handle more complicated trees as input in this format a bit more thought would be needed on how to best handle and convert into your internal format for processing.
pseudocode:
function getNode(Node)
get one char;
if (the char is "(")
getNode(Node.left);
get one char;
end if;
Node.value = Integer(the char);
get one char;
if (the char is "(")
getNode(Node.right);
get one char;
end if;
//Now the char is ")" and useless.
end function
Before calling this function, you should get a "(" first.
In this method, the framwork of a Node in string is "[leftchild or NULL] value [rightchild or NULL])".
"("is not belong to the Node, but ")" is.

Why does this message print extra times (more than I want it to print)?

import java.util.ArrayList;
import java.lang.Math;
public class War {
ArrayList deck = new ArrayList(0);
ArrayList player1 = new ArrayList(0);
ArrayList player2 = new ArrayList(0);
int sum1 = 0;
int sum2 = 0;
int count = 0;
private void setup ()
{
for (int x = 1; x <= 13; x++)
{
for (int y = 1; y <= 4; y++)
{
deck.add(x);
}
}
while (deck.size() > 26)
{
double x = Math.random() * deck.size();
int y = (int) x;
player1.add(deck.remove(y));
}
while (deck.size() > 0)
{
double x = Math.random() * deck.size();
int y = (int) x;
player2.add(deck.remove(y));
}
for (int x = 0; x < 26; x++)
{
sum1 += (int) player1.get(x);
sum2 += (int) player2.get(x);
}
System.out.println("Player 1's starting power is " + sum1 + ".");
System.out.println();
System.out.println("Player 2's starting power is " + sum2 + ".");
System.out.println();
if (sum1 == sum2)
{
System.out.println("The two player's starting powers are equal! This'll be a good one, folks!");
}
}
public void play ()
{
if (hasSomeoneWon() || count == 0)
{
setup();
}
while (!player1.isEmpty() && !player2.isEmpty())
{
int a = (int) player1.get(0);
int b = (int) player2.get(0);
if (a > b)
{
player1.add(player1.remove(0)); // The winner's card is re-added to his deck before
player1.add(player2.remove(0)); // the loser's is added to the winner's deck.
}
if (a < b)
{
player2.add(player2.remove(0));
player2.add(player1.remove(0));
}
if (a == b)
{
war();
}
}
victory();
}
private void war ()
{
ArrayList temp1 = new ArrayList(0);
ArrayList temp2 = new ArrayList(0);
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
int x = 0;
while (!(player1.isEmpty() || player2.isEmpty()) && x < 3)
{
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
x++;
}
int a = (int) temp1.get(temp1.size() - 1);
int b = (int) temp2.get(temp2.size() - 1);
if (a == b)
{
if (temp1.size() != temp2.size())
{
if (temp1.size() > temp2.size())
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
}
else
{
if (player1.isEmpty() || player2.isEmpty())
{
if (player1.isEmpty())
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
else
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
}
else
{
war();
}
}
}
else
{
if (a > b)
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
play();
}
}
private void victory ()
{
if (player1.isEmpty() && sum2 > sum1)
{
System.out.println("Player 2 has won!");
}
if (player1.isEmpty() && sum1 > sum2)
{
System.out.println("Upset! Player 2 has won!");
}
if (player2.isEmpty() && sum1 > sum2)
{
System.out.println("Player 1 has won!");
}
if (player2.isEmpty() && sum2 > sum1)
{
System.out.println("Upset! Player 1 has won!");
}
hasSomeoneWon();
}
private boolean hasSomeoneWon ()
{
if (player1.isEmpty() || player2.isEmpty())
{
count++;
return true;
}
return false;
}
}
Sorry for including all of my code, but I don't know which part is causing the extra printing.
This is the card game War. It's supposed to play out the game between two players on its own and then print the winner. Whenever I've played it, though, the victory message (whichever one gets printed) is printed a variable number of times. I'm guessing this has something to do with either where and how often I've included my calls to some of the methods OR the recursive call to war within the war() method.
My only experience with Java is an AP Computer Science class I took this school year, so I'm for sure a noob by the standards of everyone reading this.
In the war() method you are recursively calling war() and war() will eventually end by recalling play(). So there will be multiple instances executing play(). Eventually when the cards run out for one player all this instances will comeback as the stack is unwound and continue executing play(). And finally of course calling victory() and printing it multiple times (should be the amount of times war() was called).
So each war() may print out a player has won once it reached the bottom of the recursion. I don't think the call to play() in war() is necessary, it will go back to the play() method after it finishes the war() method anyway.

Categories

Resources