This program doesn't work, but meanwhile it has no error notice...Every time I entered a starting point, the starting point will show up, but no path to the Ending point nor the path it through. the program has a 7*11 Maze, "B" presents obstacle and a fixed ending point which presents as "X" and what the program would do is, you can enter a coordinate into it to make it as your starting point. Then the program would find a way from your starting point to the end (also the path will be shown in "O"). I tried to use recursion during this process, however it wouldn't work, and I don't know why. Please help me out guys.
import java.io.*;
public class Maze {
private static final Maze[][] String = null;
String[][] Maze=new String[7][11];
int x,y;
public static void main(String[] args) throws IOException{
String name;
int k=0,x1,y1;
Maze M=new Maze();
System.out.println("Hello there, would you like to provide your name, please?");
name=M.Name();
M.Maze=M.Set(M.Maze);
M.Print(M.Maze);
while (k==0){
System.out.println(name+", now please enter coordinate of the starting point");
System.out.println("The left top point would be (0,0)");
System.out.println("Now, please enter the x value:");
M.x=M.Input();
System.out.println("And then, please enter the y value");
M.y=M.Input();
if (M.Maze[M.y][M.x]==" "){
M.Maze[M.y][M.x]="$";
k=1;
}
else
System.out.println("Sorry, you cannot put your starting point there, please try again");
}
M.Process(M.x,M.y);
M.Print(M.Maze);
System.out.println("$ is the Starting Point");
System.out.println("X is the Ending Point");
System.out.println("O is the Path");
}
public static String Name() throws IOException{
String name;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
name=br.readLine();
return name;
}
public static int Input()throws IOException{
int i;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
i=Integer.parseInt(br.readLine());
return i;
}
public static String[][] Set(String Maze[][]){
for(int i=0;i<7;i++){
for(int j=0;j<11;j++){
Maze[i][j]=("B");
}
}
Maze[1][1]=Maze[2][1]=Maze[3][1]=Maze[4][1]=Maze[5][1]=Maze[1][2]=Maze[1][3]=Maze[2][3]=Maze[3][3]=Maze[5][3]=Maze[3][4]=Maze[5][4]=Maze[1][5]=Maze[2][5]=Maze[3][5]=Maze[5][5]=Maze[3][6]=Maze[4][6]=Maze[5][6]=Maze[1][7]=Maze[2][7]=Maze[2][7]=Maze[3][7]=Maze[5][7]=" ";
Maze[6][7]="X";
Maze[1][8]=Maze[3][8]=Maze[1][9]=Maze[3][9]=Maze[4][9]=Maze[5][9]=" ";
return Maze;
}
public static boolean Process(int x1, int y1){
Maze M=new Maze();
if (Move(M.Maze,x1,y1)){
if (End(x1,y1))
return true;
}
else{
M.Maze[y1][x1]="1";
if (Process(x1-1,y1)){
M.Maze[y1][x1]="O";
return true;
}
else if(Process(x1+1,y1)){
M.Maze[y1][x1]="O";
return true;
}
else if (Process(x1,y1-1)){
M.Maze[y1][x1]="O";
return true;
}
else if (Process(x1,y1+1)){
M.Maze[y1][x1]="O";
return true;
}
}
return false;
}
public static boolean Move(String Maze[][],int x1, int y1){
if (x1<0||y1<0||x1>6||y1>10)
return false;
if ((Maze[y1][x1]=="B")||Maze[y1][x1]=="1")
return false;
return true;
}
public static boolean End(int x1, int y1){
if ((y1==7)&&(x1==5))
return true;
return false;
}
public static void Print(String Maze[][]){
for(int i=0;i<7;i++){
for(int j=0;j<11;j++){
System.out.print(Maze[i][j]);
System.out.print(" ");
}
System.out.println(" ");
}
}
}
I'm not sure, what you want to do with this line, since it is used nowhere:
private static final Maze[][] String = null;
I found several issues in your code:
Every time your code enters the Process-method, a new instance of Maze is created with Maze M=new Maze();. The new instances don't know the extra markings which you made in the steps before (like the 1s), so it will switch back and forth between two neighbouring fields until you get an StackOverflowError.
Also the new Maze instances are not initialized with the labytinth, because you didn't call Set on it. You should place the code of the Set-method in the constructor of Maze, so that this kind of error can't occur.
BUT your program dosen't even come this far. If you feed the Process-method the cooridinates of your start field, it will wonder: "Can I move to the specified field and if so, is it the end?". The answer to "can I move there?" is obviously yes, since you made sure that the start field is clear. The answer to "is this the end?" is no. Process returns true and stops.
--> What you should do about it: place the recursive calls of Process into the if, not the else. You don't need the else.
To prevent the StackOverflowError from item 1 to occur (it does by now) pass an instance of Maze to the Process-method. Remember to do this everytime you call Process and be careful that it always is the same instance. Delete the lines that produce a new Maze instance in Process.
For now you are error free, but it still doesn't work. This is because you mixed up the x and y maximum indices in the Move-method. You declared the array like this: String[][] Maze=new String[7][11];. This means that the maximum x-index is 10 and the maximum y-index is 6. In Move you check the bounds like this: if (x1<0||y1<0||x1>6||y1>10)
Similar is true for the End-method. If you count of the 'X' in your labyrinth, it is the 8-th to the left and 6-the from the top. This corresponds with a y-index of 6 and a x-index of 7. You did (y1==7)&&(x1==5)
Now it works. The 1s are the paths the program tried.
I think you have noticed that you cannot call non-static methods from a static-mehtod like the main-mehtod. If you have an instance of an object, like the M in your code, you can call non-static methods on it with M.<methodName>().
I would strongly advice you to study the object orientated design more closely as it seems you did not understand it.
Also it would be nice if you would adhere to the java naming conventions - only classes and such start with an uppercase letter, everything else starts with a lowercase letter (variables, methods, etc.). It makes things easier to read for those who are used to it, which would almost be everyone, who was taught in a class or with a book.
Related
so this is the main code for my text-based game.
import java.util.Scanner;
public class D_M_RPG {
public static void main(String[] args) {
//Creating the class to call on my toolbox
D_M_RPGtoolbox toolbox = new D_M_RPGtoolbox();
//Creating the scanner class for user input
Scanner input = new Scanner(System.in);
//Initiating variables and final variables aswell as arrays
//token variable to validate open spots in an array
int slotCounter = 0;
int inventoryExpander = 11;
//First initiated will be the character creation variables
String hairColor = "";
String eyeColor = "";
String skinColor = "";
String gender = "";
//Initiating the arrays for character inventory slots
String[] weaponSlots = new String[10];
//initiating the arrays for the character creation
String[] hairColorARR = {"black","Green","Yellow","Brown","Blue","Blonde","Grey","White"};
String[] eyeColorARR = {"Green","Brown","Blue","Grey",};
String[] skinColorARR = {"White","brown","Black",};
String[] genderARR = {"Male","Female"};
//Creating the introduction title and introduction
System.out.println("Welcome to, COLD OMEN.");
System.out.println("\nNOVEMBER 12th, 2150: ONTARIO, CANADA");
System.out.println("\nYou hear loud shouts and gun fire all around you but can't pinpoint the location of anything, you feel a bit dazed until someone grabs you and you open your eyes and snap out of it.");
System.out.println("\nUnknown: 'Get up, its time to move out. Take this.'");
System.out.println("\nUnknown hands you a 'M4-A4 RIFLE'");
System.out.println("\nyou manage to catch a small glimpse of him before you get up.");
//Character creation screen
System.out.println();
//ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "M4-A4 RIFLE");
System.out.println("\n" + weaponSlots[0]);
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "ak47");
System.out.println(weaponSlots[0]);
}
}
so I have this method I made to basically add an "item" to the weaponSlots array (the inventory) but whenever I run it it will add to the first element in the array [0] but it wont incremement the slotcounter which should go up by one every time the method is used so that I dont replace any items in the array It should just add items until its full which is checked using the inventoryExpander variable. at the moment I have it printing the element at 0 and 0 for the array but i have checked 1 aswell and 1 is just null no item added it only just replaces the element at 0. heres the code for the method to increment etc:
public class D_M_RPGtoolbox {
//method for random number generating to be used for crit hits, turns, loot generation etc
public int randomGen(){
int x = (int) (Math.random()*((20-0)+1)+0);
return x;
}
//method for inserting into an array ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER FIX
public void insert(String[] a, int b, int d , String c) {
if(b < d) {
a[b] = c;
b++;
}//end of if statement
}//end of method
}
What you are actually performing the ++ operation on in b is a copy of the value in slotCounter.
The variable slotCounter is passed into insert "by-value".
This unlike what you probably imagine, that it is passed "by-reference".
One solution would be to do the slotCounter++ from the call row instead; and another would be to let the toolbox own the slotCounter variable completely.
This question uses the image of passing a copy of document content (by value) where changes to the document would not be seen by the sender; or as a link to a shared document (by reference), where changes could be made to the same page that the sender sees.
Its always going to be zero since you are passing zero and incrementing the local variable b.
Try calling the method as below with post increment ++ to slotCounter and see if it works for you,
toolbox.insert(weaponSlots, slotCounter++, inventoryExpander, "M4-A4 RIFLE");
I'm really scratching my heard on this one. I'm new at java, and I'm having the strangest thing happen.
It's homework and I'm taking it one step at a time. My issue is the loop just keeps going and stops asking for input, just keeps looping until it terminates. My comments are largely for myself. I tried to extract what was causing my problem and post it here.
Look at the "hatColor" switch, you'll notice the way I'm making sure the user enter only from the options I have allotted. Should I be using a exception handler or something?
Anyway, in short, the problem is that if I enter something with spaces, the loop skips asking for my next input. Like, if I entered "y y y y y " to the scanner when first prompted, the program will terminate and not give me the chance to enter something else.
Please, anyone that understands this, I would really appreciate your help.
import java.util.Scanner;
public class Testing
{
static String hatColor;
public static void main(String[] args) {
gameStart();
}
public static void gameStart()
{
Scanner userInput = new Scanner(System.in);
boolean keepLooping = true;
int loopCounter = 0;
System.out.println("The game begins. You must choose between 3 different colored hats."
+ " You can type white, black, or gray.");
while (keepLooping == true)
{
hatColor = userInput.next();
switch(hatColor)
{
case "white":
System.out.println("You have chosen the path of well intentioned decisions.");
walletDrop();
//the two items below are only there in case the wallet drop somehow completes without calling another method
keepLooping = false; // stops the while loop from looping again.
break; // breaks out of the switch
case "gray":
System.out.println("You have chosen the path of free will.");
walletDrop();
keepLooping = false;
break;
case "black" :
System.out.println("You have chosen the path of personal gain.");
walletDrop();
keepLooping = false;
break;
default : //we could just copy this default chunk for later switch statements
if (loopCounter >= 3)//end program on them
{
System.exit(0);
}
System.out.println("You didn't enter a usable answer. Try again");
loopCounter++;
if (loopCounter == 3)
{
System.out.println("This program will self destruct if you enter another invalid response.");
}
}//end of switch
}//end of while
}//end of game start method
public static void walletDrop()
{
System.out.println("wallet drop successful");
}
}
So I have actually solved this right after posting. In case someone else needs to look here for help:
The issue I was experiencing was due to using the scanner method
variableToAssign = scannerName.next();
instead of
variableToAssign = scannerName.nextLine();
I have a project for my computer science class and we're making battleship. Part of the program is that we have make sure that the piece the player puts down does not go off of the board.
I've made a method to check to see whether it goes off the board:
private static boolean test(String s, int row, int column,int spaces)
{
if(s.equals("right")&&column+5<=10)
{
return true;
}
if(s.equals("up")&&row-spaces>=0)
{
return true;
}
if(s.equals("left")&&column-spaces>=0)
{
return true;
}
if(s.equals("Down")&&row+spaces<=10)
{
return true;
}
return false;
}
But once I've gotten it to print out an error message, I'm not sure how to make it so that the program can re-recieve the new position for the piece, without putting an if statement in and if statement in an if statement (and on and on), because you need to check the new position to make sure it doesn't go off of the board.
Here is the part where I get the position of the playing piece (although I don't think you need it)
Scanner sonic= new Scanner(System.in);
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
int beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
int begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
String direction = sonic.next();
And here's one of the if statements that I use to check/place the pieces
if(direction.equals("left")&&test("left",beginrow,begincolumn,5))
{
for(int i = beginrow; i>beginrow-5; i--)
{
battleship[begincolumn-1][i-1] = ('a');
}
}
else if(!test("left",beginrow,begincolumn,5))
{
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
}
This may be a duplicate, but I didn't know how to reword my search to find what I wanted. (So if anyone could direct me to the right article, that'd be nice as well)
What you should do is split your code appropriately into methods and call that methods repeatedly until your program is satisfied with the outcome.
For example:
create a method startGame() which has the job call methods getting user input until satisfied
make a method to request the user to input all the different ships and other required data
That might look something like
public void startGame() {
// do some setup
while(!requestShipInput()) { // request ship data until the data is valid
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
}
// do some more ship setup
// get the actual playing started
}
public boolean requestShipInput() {
Scanner sonic= new Scanner(System.in);
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
int beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
int begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
String direction = sonic.next();
if(direction.equals("left")&&test("left",beginrow,begincolumn,5)) {
for(int i = beginrow; i>beginrow-5; i--) {
battleship[begincolumn-1][i-1] = ('a');
}
return true; // valid ship data
}
return false; // invalid ship data
}
As a first step, separate input validation from taking the action based on that input - you already have the validation logic in a separate function, so this is easy. Then figure out what needs to be done in case of invalid input - in your case, you need to ask for new input until you get a valid position:
do {
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
direction = sonic.next();
} while (!test(direction, beginrow, begincolumn, 5))
After that, you know you've got a valid position.
My next step would probably be to group the information required to describe a ship on the board (i.e. beginrow,begincolumn,direction, probably also size) in a separate Object - possibly named Ship.
I think you could pretty naturally use recursion here:
public void getInput() {
// scanner code to get input
if (!test("left",beginrow,begincolumn,5)) { // test failed
getInput()
return
}
// test succeeded, continue
}
You already have something to the limits of you board? If you execute the check first, you don't need to execute a cascade of if-else
if(!test(direction,beginrow,begincolumn,size))
{
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
} else {
// check for collision with already placed ships
}
Keep in mind that there is a chance to combine up/down and left/right. The calculation rules are nearly the same and you only have to decide if you have to look to the one or the other direction.
So I am a student. I am taking my first class in Java. I am sure my code is horrible, but please don't beat me up, I am really trying to learn. I have read quite a few method questions and adjusted my code according the the suggestions on this website. The closest post to my problem is Running Loop on Java Method. I adjusted my code according to the suggestions in this post, along with a few others. That said, it did not fix my problem. My methods are not pulling through properly.
Can anyone help? It will not pull any of the Boolean code into the main and I am not sure if the Boolean is pulling my methods correctly. Intro runs properly. Below is my code (edited down to include main and bool code only):
public static void main(String[] args)
{
intro(); // This works
while (repeat()) //This does not work
;
}//end Main
//None of this is being called
public static boolean repeat()
{
//Assign Variables
char calculate, calculateCS, repeat;
double inchCircle, inchSphere, radiusCS, volume, volumeSphere, area, areaCircle;
String shape;
//Initialze Variables
calculate = 1;
area = 1;
volume = 1;
inchCircle = 1;
inchSphere = 1;
shape = "";
//Ask if user wants to repeat
System.out.print("Do you want to calculate anouther round object (Y/N): ");
if (!takeInput().equalsIgnoreCase("y"))
{
System.out.println("Thank you for using the Round Object Calculator. Goodbye. ");
return false;
}
else
{
printCircleSphere(shape);
if (!printCircleSphere(shape).equalsIgnoreCase("c"))
{
printRadiusC(inchCircle);
printCircle(area);
}
else if (!printCircleSphere(shape).equalsIgnoreCase("s"))
printRadiusS(inchSphere);
printSphere(volume);
}
return true;
}//end repeat
In the land of Puzzlevania, Aaron, Bob, and Charlie had an argument over which
one of them was the greatest puzzler of all time.
To end the argument once and
for all, they agreed on a duel to the death.
Aaron was a poor shooter and only hit
his target with a probability of 1>3.
Bob was a bit better and hit his target with a
probability of 1>2.
Charlie was an expert marksman and never missed. A hit means
a kill and the person hit drops out of the duel.
To compensate for the inequities in their marksmanship skills, the three decided
that they would fire in turns, starting with Aaron, followed by Bob, and then by
Charlie. The cycle would repeat until there was one man standing, and that man
would be the Greatest Puzzler of All Time.
An obvious and reasonable strategy is for each man to shoot at the most accurate
shooter still alive, on the grounds that this shooter is the deadliest and has the best
chance of hitting back.Write a program to simulate the duel using this strategy.
Your program should use
random numbers and the probabilities given in the problem to determine whether
a shooter hits the target.
Create a class named Duelist that contains the dueler’s
name and shooting accuracy, a Boolean indicating whether the dueler is still alive,
and a method ShootAtTarget ( Duelist target ) that sets the target to dead if
the dueler hits his target (using a random number and the shooting accuracy) and
does nothing otherwise.
Once you can simulate a single duel, add a loop to your program that simulates
10,000 duels. Count the number of times that each contestant wins and print the
probability of winning for each contestant (e.g., for Aaron your program might
output “Aaron won 3,595>10,000 duels or 35.95%”).
An alternate strategy is for Aaron to intentionally miss on his first shot. Modify the
program to accommodate this new strategy and output the probability of winning
for each contestant.
Which strategy is better for Aaron: to intentionally miss on the
first shot or to try and hit the best shooter? Who has the best chance of winning,
the best shooter or the worst shooter?
Ok so that the problem. Here is my code so far:
public class Duelist {
private String name;
private double probabilityOfHitting;
private boolean alive = true;
//Only declared instance variables. Must created setters and getters
public void setName(String newName){
name = newName;
}
//name setter created
public void setProbabilityOfHitting( double newProbabilityOfHitting){
probabilityOfHitting = newProbabilityOfHitting;
}
//probability of hitting setter created
public void setAlive(boolean newAlive){
alive = newAlive;
}
//name setter created
//now must create getters
public String getName(){
return name;
}
//created the name getter
public double getProbabilityOfHitting(){
return probabilityOfHitting;
}
//created the probability of hitting getter
public boolean getAlive(){
return alive;
}
//created the alive getter
//no constructors created before
public Duelist(String tempName, double tempProbability){
name = tempName;
probabilityOfHitting = tempProbability;
}
//constructor is now created
//need to create a method for the duelists to shoot at each other
public void shootAtTarget(Duelist target){
double randomNum = Math.random();
if (this.probabilityOfHitting ==1){
target.setAlive(false);
target.getAlive();
}
else if (randomNum <= this.probabilityOfHitting){
target.setAlive(false);
target.getAlive();
}
else {
target.getAlive();
}
}
}
public class Tester {
public static void main(String[] args) {
int winsA = 0;
int winsB = 0;
int winsC = 0;
Duelist aaron = new Duelist("Aaron",(1/3));
Duelist bob = new Duelist("Bob", (1/2));
Duelist charlie = new Duelist("Charlie", 1);
if(aaron.getAlive() == true){
if(charlie.getAlive()== true){
aaron.shootAtTarget(charlie);
}
else if(bob.getAlive() == true){
aaron.shootAtTarget(bob);
}
else{
winsA++;
}
}
else if(bob.getAlive() == true){
if(charlie.getAlive() == true){
bob.shootAtTarget(charlie);
}
else if(aaron.getAlive() == true){
bob.shootAtTarget(aaron);
}
else{
winsB++;
}
}
else{
if (bob.getAlive() == true){
charlie.shootAtTarget(bob);
}
else if(aaron.getAlive() == true){
charlie.shootAtTarget(aaron);
}
else{
winsC++;
}
}
System.out.println(winsA);
System.out.println(winsB);
System.out.println(winsC);
}
}
I know I haven't gotten close to finishing the problem yet. What I did in my tester class was to try and simulate one duel and once when I simulated one duel, I would be able to loop it so I can simulate more. The problem I'm having is that the when I run the code, the wins for Aaron, Bob, and Charlie all come up to 0 and I don't know why.
As the last parameter in the constructor calls, you wrote
Duelist aaron = new Duelist("Aaron",(1/3));
There you are dividing an int by another int, and the result will be 0 in this case. This has to be changed to
Duelist aaron = new Duelist("Aaron",(1.0/3.0));
so that double values are used (and the result will be 0.3333, as desired).
Most of your Duelist class does not seem to be "wrong", but the shootAtTarget method could be improved.
A general hint: I'd recommend you to never use Math.random(). This will deliver unpredictable results. Instead, you should use an instance of java.util.Random. This can be initialized with a certain random seed, so that it always provides the same sequence of random numbers. This makes debugging much easier.
Additonally, some tests have been redundant. When the probabilityOfHitting is 1.0, then there is no special test required: The random number will always be less-than-or-equal to 1.0. You are also occasionally calling target.getAlive() for no apparent reason.
So in the end, the method could look like this:
private static Random random = new Random(0);
//need to create a method for the duelists to shoot at each other
public void shootAtTarget(Duelist target)
{
double randomNum = random.nextDouble();
if (randomNum <= this.probabilityOfHitting)
{
target.setAlive(false);
}
}
However, the main problem was in your Test class. I'm not sure about general recommendations here. One could go very far in terms of abstraction. (A Java Enterprise Architect would probably end up with writing a AbstractDuelistStrategyFactory somewhere...). But to put it simply: At the moment, you are doing at most one shot. After one shot, nobody can have won. And you don't know how many shots have to be taken before there is only one duelist remaining.
Much of this could be made more elegant and flexible if you placed the Duelists into a List<Duelist>. But without that, an approach that is "structurally close to what you started" could look like this:
int alive = 3;
while (alive > 1)
{
System.out.println("Status: A:"+aaron.getAlive()+" B:"+bob.getAlive()+" C:"+charlie.getAlive());
if (aaron.getAlive())
{
if(charlie.getAlive())
{
System.out.println("A shoots at C");
aaron.shootAtTarget(charlie);
if (!charlie.getAlive())
{
System.out.println("A killed C");
alive--;
}
}
else if(bob.getAlive())
{
System.out.println("A shoots at B");
aaron.shootAtTarget(bob);
if (!bob.getAlive())
{
System.out.println("A killed B");
alive--;
}
}
}
// Other cases ...
}
if (aaron.getAlive())
{
winsA++;
}
if (bob.getAlive())
{
winsB++;
}
if (charlie.getAlive())
{
winsC++;
}
(Note that there are still cases missing!)