This question already has answers here:
Java exception handling
(8 answers)
Closed 7 years ago.
Well im really new to java and im really trying hard to understand what can be done in java and what can't. I'm making a console application based on the well known game Hangman. Basiclay what i'am trying to do is stop the user from typing 'e's more than twice, to do that i made 2 methods:
The first one adds 1 to the int variable mManyTimes whenever the user types e.
public boolean adder() {
boolean tooMuch = letter == 'e';
if(tooMuch) {
mManyTimes ++;
}
return tooMuch;
}
the second method is the one that sends an exception
to the user when the user types e more then twice.
public void cheatStopper() {
if(mManyTimes == 3) {
throw new IllegalArgumentException("You cant type more Es");
}
}
Basicly i created two files, one that holds the code of the game(Which those two methods are in) and other one.
the file that holds the logic of the game is Game.java and here is the code that is inside it:
public class Game {
private String mAnswer;
private String mHits;
private String mMisses;
private int mManyTimes;
public char letter;
public Game(String answer) {
mAnswer = answer;
mHits = "";
mMisses = "";
}
public boolean applyGuess(char letter) {
//checks for char letter inside the mAnswer variable.
//If it is there the indexOf() method should return the index of the letter.
//If it is not there it will return -1.
//We are basicly saing if indexOf() method returns 0 or more then that then the isHit
//if it is not then the isHit boolean will return false.
boolean isHit = mAnswer.indexOf(letter) >= 0;
if (isHit) {
mHits = mHits + letter;
} else {
mMisses = mMisses + letter;
}
adder();
return isHit;
}
public boolean adder() {
boolean tooMuch = letter == 'e';
if(tooMuch) {
mManyTimes ++;
}
return tooMuch;
}
public void cheatStopper() {
if(mManyTimes == 3) {
throw new IllegalArgumentException("You cant type more Es");
}
}
The other file that holds the main() method and prints the code to the console is Hangman.java:
public class Hangman {
public static void main(String[] args) {
// Enter amazing code here:
Game game = new Game("treehouse");
game.applyGuess('e');
game.applyGuess('e');
System.out.println(game.cheatStopper());
}
}
So here is the question that frustrated me and i never found and answer for:
How do i get my code to work and stop the user from typing more then two e.
Well well i know my code has many errors and bad structure but dont forget that im new to java, and thanks for advance :).
You need a catch block. Look up how to catch exceptions.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've been trying to get this code to work for the past week now, and every time I make one change I end up with more bugs. Can anyone help figure out where I've gone wrong?
The code is split up into two files: a runner class, and a class with all the methods.
import java.util.Scanner;
import static java.lang.System.*;
public class RPSRunner
{
public static void main(String args[])
{
Scanner keyboard = new Scanner(System.in);
String response = "";
String player = "";
RockPaperScissors game = new RockPaperScissors();
System.out.print("What is your name? : ");
player = keyboard.next();
out.print("type in your prompt [R,P,S] :: ");
response = keyboard.next();
game.setPlayers();
game.convertUserInput(response);
game.setPlayerChoice(response);
game.computerThink();
game.determineWinner();
}
}
The method class:
import java.util.Scanner;
import static java.lang.System.*;
import java.util.Random;
public class RockPaperScissors
{
private String playerName; //used to set player's name
private int playChoice; //player's choice as a number
private int compChoice; //computer's choice as a number
private int playerNumber;
Random rand = new Random(); //allows useage of random methods
public RockPaperScissors()
{
//sets everything to null, prepare for incoming calculations
playerName = "";
}
public RockPaperScissors(String player)
{
playerName = player;
}
public void setPlayers(String player)
{
//good ol mutator method
playerName = player;
}
public String convertUserInput(String response)
{
//Convert R, P, S to integer using switch case
//If invalid input, set to -1
switch(response) {
case "R": playChoice = 0;
break;
case "P": playChoice = 1;
break;
case "S": playChoice = 2;
break;
default: playChoice = -1;
}
}
public boolean setPlayerChoice(String response)
{
//TODO set playChoice to convertUserInput
//return (playChoice != -1)
playChoice = convertUserInput(response);
return(playChoice != -1);
}
public int computerThink()
{
//Use Math.random from 0-2 inclusive
//return it all in one statement so
//return Math.random(whatever);
return rand.nextint(2);
}
public String determineWinner()
{
String winner="";
compChoice = computerThink();
switch(compChoice) {
case 0:
if(playChoice == 1){
winner = playerName;
} else if(playChoice == 2) {
winner = "Computer";
} else if(playChoice == 0) {
winner = "Tie";
}
case 1:
if(playChoice == 1) {
winner = "Tie";
} else if(playChoice == 2) {
winner = playerName;
} else if(playChoice == 0) {
winner = "Computer";
}
case 2:
if(playChoice == 1) {
winner = "Computer";
} else if(playChoice == 2) {
winner = "Tie";
} else if(playChoice == 0){
winner = playerName;
}
} //closes the switch
return winner;
}
}
This is my first major program, so I apologize for any glaring errors or incorrectly-interpreted concepts. I think my major issue lies in the return types, but I'm not positive.
Looking through your code, it is a bit of a mess, so I'll go through step by step.
game.setPlayers();
game.convertUserInput(response);
game.setPlayerChoice(response);
game.computerThink();
game.determineWinner();
You call ALL of these, yet some have return types and are called in previous functions already. For example, convertUserInput.
Your convertUserInput function sets the playChoice variable, declares it returns a String but actually returns nothing. This is called with your clump of functions above, but is then also called by setPlayerChoice, which replaces the playChoice set in the call with, well, nothing. Because nothing is returned you get a compile error.
computerThink returns an int, but you call it above without setting the returned value to anything, then determineWinner is called, which WOULD work had it not been for the above problems.
There is quite a bit wrong with your code. A few obvious ones: you have parameterized your setPlayers method of the RockPaperScissors class to accept a string, but when you invoke it, you dont provide any value, thats a compile time issue. In the RockPaperScissors class you have a method convertUserInput whose method signature says it will return a string, but there are no code paths which return a value in that method. I would do a few more simple tutorials to try to wrap your head around basic OOP concepts then come back to this once you understand basic stuff like, What is an Object? What is a method signature? and most importantly, read and interpret the compile time errors.
It's a little strange that you know your problem lies with the return types but don't know how to fix it. Are you just reading the error message but don't know what its actually saying?
The return type is declared in the first line of a method, the method declaration. The method is expected to return the return type or you will receive a compile-time error.
Some Examples
//these are method declarations
// the return type is before the name of the method
public void setPlayers(String player) {} //return type "void" - this method should not return anything
public String convertUserInput(String response) { // return type "String" - this method NEEDS to return a String
return "A String";
}
Matching method calls
//You need to match the return type with how you call the method
String myPlayers = setPlayers("player"); //WON'T COMPILE - setPlayers returns void, not String
setPlayers("player"); // this is okay, nothing is returned, return type void
String convertedInput = convertUserInput("response"); // this is okay, return type String, which is what convertedInput will be.
convertUserInput("response"); // this is also okay, even though it returns a String we don't have to assign it to a variable. Though in this example calling the method like this is pretty much useless.
int convertedInput = convertUserInput("response"); //WON'T COMPILE - convertUserInput returns String, not an int.
Ok, so I am going to see if this makes sense. In the second method below (int numAdd) I want to be used for the private method (int searchingNum). I don't really understand how private methods work, but whatever number the user enters for the (int numAdd) I want to be duplicated for the parameters in the first method. How is this possible?
//See if user input returns -1 to test whether or not number exists in the array
private int indexOf(int searchingNum)
{
}
//Add number in the array
public boolean addNumber(int numAdd)
{
if (list.contains(numAdd))
{
return false;
}
else
{
list.add(numAdd);
count++;
return true;
}
}
that's it? indexOf(numAdd);
public boolean addNumber(int numAdd)
{
// somewhere, in the middle of nowhere
indexOf(numAdd);
// more of code
}
You can call method of same class directly. No need to do anything. Like this :
public boolean addNumber(int numAdd)
{
int abc = indexOf(numAdd);
//Whatever you want to do...
}
This question already has an answer here:
Missing return statement error in a method
(1 answer)
Closed 9 years ago.
trying to figure this out. I've created a method that checks if the user has entered an integer using a catch block.
The method obviously is asking for a return statement but no matter where I put it it does not work. Could anyone offer any advice?
public class Week5 {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
inputInt();
inputDouble();
}
public static int inputInt(){
Scanner myKeyboard = new Scanner(System.in);
System.out.println("Enter number:");
int num;
boolean carryOn = true;
while (carryOn == true) {
{
try {
num = myKeyboard.nextInt();
carryOn = false;
}
catch (Exception e) {System.out.println ("Integers only, try again" );
myKeyboard.next();
return num;
}
}
}
}
When carryOn == false then it will go to the bottom of your method and there's no return statement there. You need to have a return statement at the bottom.
Here's an explanation of the error: If a function says it returns something (an int in this case) that means that every path it can take must return an int. You're missing one of those paths which is a compile time error.
Sorry if this is answered somewhere due to me missing something obvious, but I've been googling this for days now and it just doesn't seem to make any sense. I've got 3 years of experience in Javascript and am getting into Java now, so I'm not behind on the basic concepts of anything and such.
I'm using IntelliJ for this, but it fails to point out the problem. The communication (access rights and instantiations) between my classes is fine, the code syntax and variable types are as well, etc, so I really can't tell what it is.
I have a Data class, which just holds "read-only" data for the other classes to use.
public class Data {
// snip
public static int[][] specs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
There's another class that has to read this data when it's initialized.
public class Soldier {
// snip
public int range;
public Soldier() {
int x = ...; // user input
range = Data.specs[x][1];
}
}
The specs array itself contains its data as defined (ie the array is not empty), x is valid as an index of the specs array (ie 0 <= x <= 3), its type is int and Test has read access to the specs array (all confirmed with debug output statements). And yet, when it tries to set the value of range (then and only then, at that exact point), I get the "Index out of bounds" error.
Can someone please tell me what's going wrong when trying to read the array? Or am I right in saying that this is really weird and I need to post the entire code?
Note: a small new test also shows that, if I change the code to first output a manually chosen value from the array and then set the value of range, the console prints the error statement (and exits the program) and follows it up by printing the manually picked value, but assigning the value and then asking to output range only throws the error... That makes absolutely no sense at all!
Edit: I've edited the code above. The class called Test is called Soldier in my code (I'm making a text-based game...). Below's the stack trace, if it's any good without the full code (which is way long). The basic structure of my program is this:
1) Boot contains the main method and instantiates a new Game
2) Game instantiates x Teams
3) each Team instantiates an Army
4) each Army instantiates x Soldiers
Each instance of the classes is set as an attribute of the instantiating class (public Army army; and an Army instantiation in the Team constructor, for example). It's essentially a cascade of constructors instantiating subsequent classes and assigning them as their attributes.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Army.<init>(Army.java:13)
at Team.<init>(Team.java:19)
at Game.<init>(Game.java:22)
at Boot.main(Boot.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)5
Edit edit: here's the semi-full code (I'm leaving out the stuff that has absolutely nothing to do with it, including the imports). It's in no particular order and the classes are in separate .java files within the IntelliJ project. The game continues up to the point where a new Soldier asks for its type to be designated (the function performing the user input is working fine and validating the input as proven by a technically identical other part of the game).
public class Boot {
public static void main(String[] args) {
Object[] games = new Object[] {};
if (Lib.userConfirmPrompt("Start the game?") == true) {
do {
games[games.length] = new Game();
}
while (Lib.userConfirmPrompt("Do you want to play again?") == true);
}
System.exit(0);
}
}
public class Game {
public Object[] teams = new Object[] {};
public Game() {
for (int i = 0;i < settings.xbots + 1;i++) {
teams[teams.length] = new Team(this);
}
}
}
public class Team {
public Game game;
public Army army;
public Team(Game p) {
game = p;
army = new Army(this);
}
}
public class Army {
public Team team;
public static Object[] soldiers = new Object[] {};
public Army(Team p) {
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers[soldiers.length] = new Soldier(this);
}
}
}
public class Soldier {
private Army army;
public int sight;
public int range;
public int distance;
public int damage;
public Soldier(Army p) {
army = p;
int type = Lib.userTxtIntOptionsPrompt(Data.isoldiertypes);
// HERE is where it crashes, type is assigned and valid but the array access fails
sight = Data.isoldierspecs[type][0];
range = Data.isoldierspecs[type][1];
distance = Data.isoldierspecs[type][2];
damage = Data.isoldierspecs[type][3];
}
}
public class Data {
public static List isoldiertypes = Arrays.asList("Scout","Private","Machinegunner","Grenadier");
public static int[][] isoldierspecs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
public class Lib {
private static Scanner input = new Scanner(System.in);
// output
// default: 1 query string to print
public static void outBase(String query) {
System.out.print(query);
}
public static void outStd(String query) {
outBase(query + "\n");
}
// end of output
// input
// default: 1 query string to print,
// query and input are in-line (exception: userConfirmPrompt prints query block-wise and default instruction in-line before input),
// keeps user hostage until valid input is given (exception: userPrompt returns blindly)
public static String userPrompt(String query) {
outBase(query);
return input.nextLine();
}
public static String userTxtPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userPrompt(query);
} while (menuinput.length() == 0);
return menuinput;
}
public static int userIntPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userTxtPrompt(query);
} while(menuinput.matches("^-?\\d+$") == false);
return new Integer(menuinput);
}
// end of input
// options input
// default: takes a List of options as argument,
// prints an enumerated list of these options string-wise,
// prompts for a numeral selection of the desired option and returns the number if valid
public static int userTxtIntOptionsPrompt(List options) {
int choice = 0;
Boolean chosen = false;
do {
if (chosen == true) {
userHostage();
} else {
chosen = true;
}
chosen = true;
for (int i = 0;i < options.size() - 2;i++) {
outStd((i + 1) + ") " + options.get(i) + ",");
}
outStd((options.size() - 1) + ") " + options.get(options.size() - 2) + "\nand " + options.size() + ") " + options.get(options.size() - 1) + ".");
choice = userIntPrompt("Enter the number of the option you'd like to select: ") - 1;
} while(choice < 0 || choice >= options.size());
return choice;
}
// end of options input
// miscellaneous
public static void userHostage() {
outStd("Invalid operation. Please try again.");
}
}
The problem is in your Army class:
public static Object[] soldiers = new Object[] {};
You initialize an empty (length == 0) array named soldiers, but later you access:
soldiers[soldiers.length] = new Soldier(this);
This causes the failure.
By definition, soldiers.length is out of the bound of the array (since the bound is from 0 to soldiers.length-1)
To overcome it - make sure you allocate enough space in the array soldiers or use a dynamic array (ArrayList) instead. You can append elements to an ArrayList using ArrayList.add(), and you don't need to know the expected size before filling it up.
The x should be greater than -1 and less than 4.
The stacktrace does not mention the Solder class, its in the conctructor of the Army class.
Any how, only knowing that the index should be within a range is not enough. As a programmer its your duty to validate the index before trying to access an element at that index.
if(index > 0 && index < array.length) {
//then only acess the element at index
Problem is the array soldiers is of size 0.
This line int x = ...; // user input implies that you are taking input in some fashion from the user and accessing the array with it. Are you checking this value to see that is in range (i.e., between 0 and 3)? If not, this may be why your testing works.
Edit: something like this might solve it for you:
public class Army {
public Team team;
public Vector<Soldier> soldiers;
public Army(Team p) {
soldiers = new Vector<Soldier>()
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers.add(new Soldier(this));
}
}
}
Judging by your other code, this sort of pattern will be useful in your Game object as well.
How do I go about writing a loop that's supposed to be boolean, yet the answer can be an integer using JOptionPane?
boolean promptMenu( int menu )
This will represent the core of your code.
Should be in the body of a loop inside main().
Returns true if it should continue running.
Returns false if it is time to quit.
Notice that promptMenu takes in an int parameter:
0 - Prints the Main Menu.
So far this is what I got:
import javax.swing.JOptionPane;
public class BankSystem {
//Fields
static boolean question = true;
static String q ;
static int qt;
//Methods
public static void main(String[]args)
{
while(question = true)
{
promptMenu (qt) ;
}
}
static int promptMenu( int qt )
{
q = JOptionPane.showInputDialog ("Gen's Bank" + "\n \n Print main menu? 0-> YES\n\n") ;
qt = Integer.parseInt(q);
if (qt != 0)
{
question = false;
}
return (qt);
}
}
If you press anything that isn't 0 it still loops. Any Suggestions would help.
Read the question carefully. The question asks you for a method:
boolean promptMenu( int menu )
What you have written is a different method:
int promptMenu( int menu )
You instructor wants you to write a method returning a boolean but you are writing a method that returns an int. You are not answering the question that was asked.
To return a boolean you need:
return true;
return false;
or something like:
boolean boolVar;
boolVar = // Your code here.
return boolVar;
What you got:
public static void main(String[]args)
{
while(question = true)
{
promptMenu (qt) ;
}
}
What you need:
public static void main(String[]args)
{
while(question == true)
{
promptMenu (qt) ;
}
}
If you want to check conditions you have to use one of the following parameters (<, <=, >, >=, !=, ==). One single = is used to assign values to a variable.