Using enum with a switch case String for my assignment - java

I've made changes to the code and was able to successfully I hope use the switch case with a String. Now I just need help declaring two variables for the string getDirection. I need it to be declared as "Right" and "Left"
String quit= "exit";
String choice;
String getDirection= "Right";//I need it to be declared as both left and right
quit.equalsIgnoreCase("exit");
do
{
System.out.println("would you like the bug to move or turn around?");
System.out.println();
System.out.println("Or enter 'exit' to quit");
choice= scan.nextLine();
option options=option.MOVE;
switch(options)
{
case MOVE:
b.move();
if (getDirection.equals("Right"))
System.out.println("The bug moved 1 unit towards " + b.getDirection("Right ") + " and is now at position " + b.getPosition());
else if (getDirection.equals("Left"))
System.out.println("The bug moved 1 unit towards " + b.getDirection("Left ") + " and is now at position " + b.getPosition());

if (b.getDirection.equals("Right"))//this getDirection is showing up as an error
That's because there's no member variable called getDirection in class Bug.
You have defined a local variable called getDirection, which is unrelated to class Bug.
Probably you intended a method call, b.getDirection(), by analogy with your similar calls in the same section of code.
Incidentally, IMO variables should have noun phrases for names, not verb phrases. So, method getDirection() is well-named, variable getDirection is not.

Related

Need Help Fixing An Exception Error in my Code

I am working on a Lab on the site Zybooks and I have completed the following code below:
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String firstName;
String middleName;
String lastName;
firstName = scnr.next();
middleName = scnr.next();
lastName = scnr.nextLine();
if (lastName.contains("")){
System.out.println(middleName + ", " + firstName.charAt(0) + ".");
}
else {
lastName = lastName.substring(1);
System.out.println(lastName + ", " + firstName.charAt(0) + "." + middleName.charAt(0) + ".");
}
}
}
The Exception Error that I receive is this:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at LabProgram.main(LabProgram.java:13)
When I run the following code in an IDE everything works just fine. However when I try running it in Zybooks I get an exception error. I've come to learn that this is because when I don't add a space after I enter two names that Zybooks gives an exception error. However when I add a space after the last name the code compiles as intended. For grading purposes I need the code to compile without a space from the keyboard, thus I am asking how I can get this code to compile. I've tried manually adding whitespace but nothing has worked.
Any help would be very much appreciated
Looking at the code it's obvious that you have three (3) specific User entry prompts to deal with. The User must supply a First Name, then the User needs to supply a Middle Name, and then finally the User needs to supply a Last Name. As with any input each of these names needs to be validated for proper context. This would include the rules for names, for example everyone has a First Name and Last Name but not everyone has a Middle Name also first and last names can contain two name words (ex: De Vanderholt).
When you have three specific prompts for the User to fill in then let them know exactly where they are at. Display on Screen what the User is expected to enter. It's always a good idea to place each prompt into a loop so that the input can be validated and if there is a problem the User is given the opportunity to provide actual valid data (in this case a valid name).
In your code you use the Scanner#next() method to retrieve the input for both First Name and Middle Name(s) however this method will not play well with multi word names since the next() method is token based. This means that if a two word name is supplied to the First Name prompt then only the first word is retrieved and the second word is automatically applied to the Middle Name prompt. You don't even get a chance to enter the middle name. This is no good unless special code is put in place to take car of this situation. It's just better not to use the next() method in this case and simply use the Scanner#nextLine() method for all your prompts. Keep in mind however that the Scanner#next() method will work just fine if you know that only a single name word will be provided by the User but this method is better used in conjunction with the Scanner#hasNext() method.
Look at your code. As said earlier, everyone has a Last Name but not everyone has a Middle Name so why have this line of code (unless your rules include the fact that last names can be nothing):
if (lastName.contains("")){
It should actually never be allowed to come to this scenario where the last name contains nothing, don't even accept the fact unless it's a middle name. If the supplied Last Name was validated then you would never need to worry about this situation unless of course your rules allow it. The example code below does not allow it.
Because there are three prompt which basically do the same thing and require the same basic validation a helper method (getName()) is used so as to eliminate the need for duplicate code:
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
// First Name:
String firstName = getName(scnr, "First");
// Middle Name:
String middleName = getName(scnr, "Middle");
// Last Name:
String lastName = getName(scnr, "Last");
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName.charAt(0))
.append(". ")
.append(middleName.isEmpty() ? "" : middleName.charAt(0))
.append(middleName.isEmpty() ? "" : ".").toString());
// O R
/*
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName)
.append(" ")
.append(middleName)
.toString());
*/
// O R
/*
System.out.println(new StringBuilder("")
.append(firstName)
.append(" ")
.append(middleName)
.append(middleName.isEmpty() ? "" : " ")
.append(lastName)
.toString());
*/
}
The Helper Method (getName()):
private static String getName(final Scanner scnr, final String nameTitle) {
String name = "";
while (name.isEmpty()) {
System.out.print("Enter your " + nameTitle + " Name: --> ");
// Get input and trim off leading/trailing whitespaces, etc
name = scnr.nextLine().trim();
// Is this for a Middle Name?
if (nameTitle.equalsIgnoreCase("middle")) {
// If nothing was supplied then there is no
// middle name so break out of prompt loop.
if (name.isEmpty()) {
break;
}
}
// Validate name...
/* Does the supplied name only contain A to Z characters
in any letter case. Add characters to the regular
expression as you see fit. (?i) means any letter case. */
if (name.matches("(?i)[A-Z. ]+")) {
// Yes, it does...
/* Ensure 'first' character of each name word (if more than one)
is upper letter case. */
String[] tmp = name.split("\\s+");
StringBuilder nme = new StringBuilder("");
for (String str : tmp) {
if (!Character.isUpperCase(str.charAt(0))) {
str = str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
if (!nme.toString().isEmpty()) {
nme.append(" ");
}
nme.append(str);
}
name = nme.toString();
}
// No it doesn't so inform User of the mistake and to try again.
else {
System.err.println("Invalid " + nameTitle + " Name Supplied! (" + name + ") Try Again...");
name = ""; // Set to null string so as to re-prompt.
}
}
return name;
}

Transfering a non-static variable to static in JAVA?

Only my third week of class (new to programming).
I'm making a text-based story in Java, but I've come to a stump in the process. I have a static variable called "static String dogName;" that I'm trying to change the value of (only once). In the beginning of the game, the user has the option to name their dog. When I try to name the dog, the code skips the naming prompt because of the static String dogName.
I want to give the user the option to name their dog.
If there's a better way to do things in my code, please let me know.
Part of the code may not be complete like the decisions...
public static Scanner keyboard = new Scanner(System.in);
public static int choice;
// dogName is Dogs name forever a hundred times rick & morty
static String dogName;
public static void main(String[] args) {
int karma = 0;
// Dog stuff...
Dog Dandy;
Dandy = new Dog();
// Prologue
System.out.println("You're walking through an alley late at night "
+ ", you see a stray dog. What do you do? ");
System.out.println("[1] Approach");
System.out.println("[2] Attempt to touch");
System.out.println("[3] Give treat");
boolean running = true;
GAME:
while (running) {
choice = keyboard.nextInt();
switch (choice) {
case 1:
System.out.println("The dog became alarmed!");
Dandy.bark();
break;
case 2:
System.out.println("The dog becomes aggressive!");
Dandy.bite();
break;
case 3:
System.out.println("The dog comes in peace");
Dandy.sit();
break;
}
if (choice == 1) {
System.out.println("You stand back in caution. You cannot risk being bitten.");
}
if (choice == 2) {
System.out.print("");
karma--;
}
if (choice == 3) {
System.out.println("You give the dog a treat. It wags its tail in excitement");
karma++;
}
// Chapter 1.1 - Man's best friend
System.out.println("\nThe dog will live a harsh life in the outside world. What would you like to do? "
+ "\n[1] Adopt dog\n[2] Leave dog\n[3] Quit game! You're bored...");
choice = keyboard.nextInt();
switch (choice) {
case 1:
System.out.println("\nYou welcome your new companion");
System.out.println("\nWould you like to give him a name?\n[1] No\n[2] Yes");
choice = keyboard.nextInt();
switch (choice){
case 1:
System.out.println("You see a shiny object beneath his foot, it's a dog collar."
+ "\nYou pick up the dog collar and see the name Todd on it."
+ "\nYes, because you did not choose a name for your dog, we gave him the most basic name ever. "
+ "You're welcome.");
dogName = "Todd"; //RIP doge
karma--;
break;
case 2:
dogName = keyboard.nextLine();
karma++;
}
}
// Good guy player gives his dog a name
// Chapter 1.2 - Home sweet home
System.out.println("\n" + dogName + " crawls up to your leg and lets out a whimper.\n"
+ "Is " + dogName + " just afraid of the dark, or is he hungry?"
+ "\nYou don't know the last time he ate. What will you do?");
System.out.println("\n[1] Go home\n[2] Find a store\n[3] Search the area");
choice = keyboard.nextInt();
if (choice == 1){
System.out.println("\nYou head home with " + dogName + " as fast as you can.\n"
+"On the way back, " + dogName + " seems extremely happy to be with"
+ " his new owner.\nGoing out you had no idea you'd bring home a new friend.");
karma++;
}
if (choice == 2){
System.out.println("");
System.out.println("");
}
if (choice == 3){
}
}
// GAME ENDING
if (karma > 0) {
System.out.println("\nYou ended with " + karma + " karma. Good job!");
}
else if (karma == 0){
System.out.println("\nYou ended with " + karma + " karma. Neither good nor bad, a neutral state.");
}else{
System.out.println("\nYou ended with " + karma + " karma. Bad job!");
}
// CREDITS
System.out.println("\n\t# THANK YOU FOR PLAYING #");
System.out.println("\t# Game created by aliens from outer space #");
}
}
When I try to name the dog, the code skips the naming prompt because of the static String dogName.
No, the problem is unrelated to dogName being static. Instead, the problem is with the way you use the Scanner. When you do keyboard.nextInt() it reads just enough data to be able to return an int. So, if the user types 2 and Enter, the Scanner will read the 2 and return it as an int, leaving the newline character in the input buffer.
Then, when you go to read the dog's name with dogName = keyboard.nextLine(); the newline character that's already present causes it to return an empty string for the dog's name immediately, rather than wait for any user input.
You can fix this by doing another keyboard.nextLine() just before you ask for the dog's name:
case 2:
keyboard.nextLine();
dogName = keyboard.nextLine();
karma++;
The first nextLine() eats up the newline from the previous number that was typed, and the second nextLine() returns a line of text (sans newline) that can be assigned to dogName.
However, there are other problems you will run into with Scanner. If the player types anything other than a number, nextInt() will throw an InputMismatchException. It's possible to work around these problems, but they can end up giving you a headache.
You might be better off using keyboard.nextLine() every time to get a line from the player, and then checking to see if it contains a number and parsing that number.
Also, the convention in Java is to use lower case letters to begin variable names, so your variable Dandy should be named dandy. Others have given some sensible suggestions about splitting your program up into pieces rather than having one monolithic main method.
couple of things.
Separate your logic from your Main method class.
Create a POJO for Dog (I think you already have one) class that takes name in the constructor argument.
public class Dog {
private String dogName;
public Dog(String dogName)
this.dogName = dogName;
}
//getters setters..
}
Instead of putting everything in your main, you'll have to remove the static keyword, and make a new instance of the program, something like this:
public static void main(String[] args) {
Game game = new Game();
game.start();
}
Then the choice and dogName variable doesn't have to be static anymore.
For general remarks: start by splitting up your code into multiple methods, each grouped by functionality, for example, one method for handling the user input, one for printing the options, etc. That way your code will become less of a mess, and allows you to refactor later into different classes more easily.
#DavidConrad's answer covers your actual error, but I thought I'd add more on "what you could do better"
public static Scanner keyboard = new Scanner(System.in);
public static int choice;
// dogName is Dogs name forever a hundred times rick & morty
static String dogName;
Note how all these fields are static? This is only required because you are trying to use them from a static method (that method being main). With only the code you have posted, it would seem you could move those fields into the main method like where you create the Dog.
Also, a tiny pet-peeve of mine, but it's not actually a rule or anything, is "excessive" spacing - (like inbetween choice and dogName). One space is fine. Two is "too" many for my liking. ;)
public static void main(String[] args) {
int karma = 0;
// Dog stuff...
Dog Dandy;
Dandy = new Dog();
Grr, more spaces! But, more importantly is the line about Dog Dandy. Your variable name is capitalized, and it is best practice to name variables in lower-case (such as you did correctly for karma). You should also declare and initialize your Dog in the same line, like so: Dog dandy = new Dog();
With the prologue and chapters, you may consider separating these into a separate class. You may notice a pattern in each chapter.
some text is given
options are given
result of option is displayed
You could greatly improve the overall readability of your code by creating a class which could taken some introText, options, and then show an option depending on the choice made. If that seems over your head, then I wouldn't worry about it though - it's only your third week so I wouldn't expect you to have the differences between classes, methods, and fields down pat quite yet. If this is something you are seriously interested in, you could find all kind of tutorials covering those, it will be greatly beneficial when you truly understand what they can do and how they interact.

Getting Material Type & Changing to New Material

final Material b = event.getClickedBlock().getType();
p.sendMessage(ChatColor.GRAY + "This rock contains " + b.toString().toLowerCase().replaceAll("_", " ") + ".");
Alright, so lets say b is equal to CLAY and I want to print out "clay" in the message. What I've done here works. But lets say b is equal to LAPIS_ORE and I want to print out "copper" in the message. In this case it won't work because it would print out "lapis ore" instead of "copper". In the API that I am using, copper is not a Material type, so therefore I cannot declare a variable Material LAPIS_ORE = COPPER;. How else would I be able to print out "copper" from Material type LAPIS_ORE?
I tried:
String LAPIS_ORE = "copper";
p.sendMessage("This rock contains " + b.toString() + ".");
But that still didn't work out, probably because LAPIS_ORE is not a string, so how else would I do it? If needed, how could I declare a new Material type and set it equal to LAPIS_ORE?
Edit: I can do this with a switch statement but that is very inefficient.
Edit: Fixed it! Was simpler than I thought and kind of embarassing.
b.toString().toLowerCase().replaceAll("_", " ").replaceAll("GLOWING_REDSTONE_ORE", "copper ore").replaceAll("REDSTONE_ORE", "copper ore")
Not that way i am sure :) you can easy get it work ... :) see example one way to do it:
http://forums.bukkit.org/threads/solved-checking-sign-text.57905/
Enjoy it...

Displaying individual elements of an object in an Arraylist through a for loop?

I'm trying to Display individual elements of an Object I have created.
It is a simple Java program that allows users to add and keep track of Player Details.
I'm just stumped when it comes to displaying the details after they have been added already. here is what my code looks like
I can create the object and input it into the arraylist no problem using the case 2, but when I try to print it out I want to do something like
System.out.println("Player Name" + myPlayersArrayList.PlayerName + "Player Position" + myPlayerArrayList.PlayerPosition + "Player Age" + "Player Age");
I know that is not correct, but I dont really know what to do, if anyone can be of any help it would be greatly appreciated. Thanks
System.out.println("Welcome to the Football Player database");
System.out.print(System.getProperty("line.separator"));
UserInput myFirstUserInput = new UserInput();
int selection;
ArrayList<Player> myPlayersArrayList = new ArrayList<Player>();
while (true) {
System.out.println("1. View The Players");
System.out.println("2. Add A Player");
System.out.println("3. Edit A Player");
System.out.println("4. Delete A Player");
System.out.println("5. Exit ") ;
System.out.print(System.getProperty("line.separator"));
selection = myFirstUserInput.getInt("Please select an option");
System.out.print(System.getProperty("line.separator"));
switch(selection){
case 1:
if (myPlayersArrayList.isEmpty())
{
System.out.println("No Players Have Been Entered Yet");
System.out.print(System.getProperty("line.separator"));
break;}
else
{for(int i = 0; i < myPlayersArrayList.size(); i++){
System.out.println(myPlayersArrayList);
}
break;
case 2: {
String playerName,playerPos;
int playerAge;
playerName = (myFirstUserInput.getString("Enter Player name"));
playerPos = (myFirstUserInput.getString("Enter Player Position"));
playerAge = (myFirstUserInput.getInt("Enter Player Age"));
myPlayersArrayList.add(new Player(playerName, playerPos, playerAge)); ;
break;
}
You need to use index to access individual element: -
for(int i = 0; i < myPlayersArrayList.size(); i++){
System.out.println(myPlayersArrayList.get(i));
}
Then you can override toString() method in your Player class
public String toString() {
return playerName + " : " + playerAge + " : " + playerPosition;
}
I can create the object and input it into the arraylist no problem using the case 2, but when I try to print it out I want to do something like
System.out.println("Player Name" + myPlayersArrayList.PlayerName + "Player Position" + myPlayerArrayList.PlayerPosition + "Player Age" + "Player Age");
I know that is not correct, but I dont really know what to do, if anyone can be of any help it would be greatly appreciated. Thanks
Just override toString() method to get desired output
A List is a collection of elements. The List provides a number of useful methods which allows you to manage it, add, remove, set, indexOf, contains and most importantly, in this case, get.
In order to manipulate a element within the list, you first need to "get" or retrieve it from the list.
List are Iterable, this means you don't need to use an indexed for loop to gain access to the various members (unless the index is of importance).
So you can do...
for(int i = 0; i < myPlayersArrayList.size(); i++){
Player player = myPlayersArrayList.get(i);
// display results
}
or
for (Player player : myPlayersArrayList) {
// display results
}
To display the contents of the Player object you can do a number of different things...
You could simply display the various properties of the Player (I don't have access to your Player class, so I'm guessing at its properties)
System.out.println("Player Name: " + player.PlayerName + "; Player Position: " + player.PlayerPosition + "Player Age: " + player.PlayerAge);
Or you could write a "formatter" method. This could be static to the Player class or it could be part of utility class, depending on your needs
System.out.println(PlayerUtils.format(player)); // Format the player properties as you see fit
Or you can, as has already being suggest, override the toString method of the Player
System.out.println(player);
There are advantages and disadvantages to all these approaches.
I tend to like putting diagnostic information into my toString methods which isn't normally useful for displaying to the user. Formatters aren't always obvious to other developers (unless they are well documented ;)).
You will need to choose those which are most useful to you and your needs.
You can also use forEach in Java 8:
List<String> myPlayersArrayList = new ArrayList<>();
myPlayersArrayList.stream().forEach((player) -> {
System.out.println("Player: " + player); //Override toString() in Player class
});
You could also use 'for-each' loop. Here's the syntax:
for(Class object : collectionOfObjects){
//this will loop through the list for you and
//now you can access each object in the list
//using object.property or object.method()
}
//using your example
for(Player player: myPlayersArrayList){
System.out.println(player); //requires override of toString() method
//or you could use
System.out.println(player.getName());
}
If you just want to show the data right after it is added, you can declare a Player reference and make it point to the object you add to the list, like so:
Player p = new Player(playerName, playerPos, playerAge);
myPlayersArrayList.add(p);
System.out.println("Player Name" + p.PlayerName + "Player Position" + p.PlayerPosition + "Player Age" + p.playerAge);
Direct access to an object's attributes is, however, very frowned upon in an OOP environment, so you should retrieve them via get methods. For example, to get the players name, this would suffice:
public String getPlayerName(){
return playerName;
}
If you want to print the data later, maybe you should take a look at the iterator pattern.

java statements inside printf and loop conditions

System.out.printf("\n"
+ "\nEnter a question: " + question=stdin.nextLine()
+ "\nEnter a guess: " + Guess=stdin.nextLine());
Produces error "The left-hand side of an assignment must be a variable".
Also,
do
{
...
} while(System.out.printf("\nWould you? "), stdin.nextLine().equalsIgnoreCase("y"))
produces "Syntax error on token ",", . expected"
I want printf to ignore the stuff that doesn't print anything. How to do so?
System.out.printf() does not allow assigning variables. So your attempt on the following code is wrong.
System.out.printf("\n"
+ "\nEnter a question: " + question=stdin.nextLine()
+ "\nEnter a guess: " + Guess=stdin.nextLine());
Try to change the above to multiple lines of code, after declaring all properly.
question=stdin.nextLine();
Guess=stdin.nextLine();
System.out.printf("\n"
+ "\nEnter a question: " + question
+ "\nEnter a guess: " + Guess);
The following do .. while() statement also have the same problem.
do
{
...
} while(System.out.printf("\nWould you? "), stdin.nextLine().equalsIgnoreCase("y"))
try the following
String answer = "n";
do
{
...
System.out.printf("\nWould you? ");
answer = <-- Get the user input using System.in -->;
} while (!answer.equalsIgnoreCase("y"))
you look like having syntax problem and following C++ way. Try to get hands on some java basics books and you are all set to go ..
Happy coding
Either question or Guess is not variable. Perhaps Guess is a class, not a variable.
The assignment is not automatically what gets assigned:
question = stdin.nextLine ();
assigns the result of stdin.nextLine () to question, but the result of the assignment is void, not question.
So your only solution is to work in 2 steps: do the assignment, and then, since nextLine has side effects, print the assigned values with println.

Categories

Resources