Strange behavior in while loop - java

I'm writing a function to take a turn in Blackjack. It looks like this:
public void takeTurn(Deck deck) {
Scanner reader = new Scanner(System.in);
String response = "y";
while (response.toLowerCase().equals("y")) {
System.out.print("Would you like another card? (Y or N) ");
response = reader.nextLine();
if (response.toLowerCase().equals("y")) {
hand.getCards().add(deck.getTopCard());
System.out.println("Current hand: " + hand);
if (hand.getValue() > 21) {
System.out.println("You busted with " + hand.getValue());
break;
}
}
}
}
The weird thing is that when I enter "n", it doesn't draw another card but it does re-prompt me. So then I threw in a printLine statement, as follows:
public void takeTurn(Deck deck) {
Scanner reader = new Scanner(System.in);
String response = "y";
while (response.toLowerCase().equals("y")) {
System.out.println("response is " + response);
System.out.print("Would you like another card? (Y or N) ");
response = reader.nextLine();
if (response.toLowerCase().equals("y")) {
hand.getCards().add(deck.getTopCard());
System.out.println("Current hand: " + hand);
if (hand.getValue() > 21) {
System.out.println("You busted with " + hand.getValue());
break;
}
}
}
}
And here's a sample interaction:
response is y
Would you like another card? (Y or N) n
response is y
Would you like another card? (Y or N)
The first "response is y" makes sense. The second I can't explain.
Any ideas?

public static void main(String[] args) {
takeTurn(new Scanner(System.in)); // just an example how you share a single Scanner as a parameter when calling takeTurn function
}
public static void takeTurn(Scanner sc/*, Deck deck*/) { // static may be removed if you do not use the function within static main void
if (isYResponse(sc, "Would you like another card? (Y or N) ")) {
System.out.println("response is y");
/*
hand.getCards().add(deck.getTopCard());
System.out.println("Current hand: " + hand);
if (hand.getValue() > 21) {
System.out.println("You busted with " + hand.getValue());
}
*/
} else {
System.out.println("response is n");
}
takeTurn(sc/*, deck.next()*/); // be careful with this loop: define when it stops actually... when isGameOver(), for example?
}
private static boolean isYResponse(Scanner sc, String message) { // static may be removed if you do not use the function within static main void
System.out.print(message);
String response;
if ((response = sc.nextLine()).isEmpty()) {
response = sc.nextLine();
}
return ("y".compareToIgnoreCase(response) == 0)
? true
: (("n".compareToIgnoreCase(response) == 0)
? false
: isYResponse(sc, message));
}
P.S. I'm sorry: I don't know the structure of other classes, like Deck, for example. I just hope my answer can help you find the final concrete solution you need if you think that way.

Related

how to run the same result of a if statement in a method in a new method

I am new to java and I'm working on a temp conversion tool
the whatToDo method takes a users input and runs it though if and else if statements and will convert one unit to another depending on what the user imputed
then the whatsNext method runs once the conversion method was executed it will ask the user if they want to convert something else convert the same thing or exit the program
I want it so when the whatsNext method is ran the and the user inputs "1" it will run the same conversion method that was just run from the whatToDo method
I have tried to take the WhatToConvert int from the whatToDo method to make a new if statement in the whatsNext method but I can not because its in a method and java cannot find it
Thank you in advanced if you do help :)
import java.util.Scanner;
public class App {
public static void conversions() {
System.out.println("What two temperatures would you like to convert?");
System.out.println("[1]:celsius to fahrenheit");
System.out.println("[2]:fahrenheit to celsius");
System.out.println("[3]:celsius to kelvin");
System.out.println("[4]:fahrenheit to kelvin");
System.out.println("[5]:kelvin to celsius");
System.out.println("[6]:kelvin to fahrenheit");
}
public static void options() {
System.out.println("what would you like to do now?");
System.out.println("[1]:convert the same thing");
System.out.println("[2]:convert something else");
System.out.println("[3]:exit");
}
public static void whatToDo() {
Scanner in = new Scanner(System.in);
conversions();
int whatToConvert = in.nextInt();
if (whatToConvert == 1) {
cF();
} else if (whatToConvert == 2) {
fC();
} else if (whatToConvert == 3) {
cK();
} else if (whatToConvert == 4) {
fK();
} else if (whatToConvert == 5) {
kC();
} else if (whatToConvert == 6) {
kF();
}
else {
System.out.flush();
System.out.println(whatToConvert + ": is a unknown command pls try again:");
whatToDo();
}
}
// runs once conversion method was run
public static void whatNext() {
var in = new Scanner(System.in);
options();
int choice = in.nextInt();
if (choice == 1) {
System.out.println("needs to be added");
cF();
} else if (choice == 2) {
whatToDo();
} else if (choice == 3) {
System.exit(1);
}
}
// conversion methods
public static void cF() {
Scanner in = new Scanner(System.in);
System.out.println("please enter the temperature in celsius:");
double cToF = in.nextDouble();
System.out.println(cToF + "°C is about " + (cToF * 1.8 + 32) + "°F");
}
public static void fC() {
Scanner in = new Scanner(System.in);
System.out.println("please enter the temperature in fahrenheit:");
double fToC = in.nextDouble();
System.out.println(fToC + "°F is about " + (fToC - 32) / 1.8 + "°C");
}
public static void cK() {
Scanner in = new Scanner(System.in);
System.out.println("enter the temperature in celsius:");
double cToK = in.nextDouble();
System.out.println(cToK + "°C is about " + (cToK + 273.15) + "°K");
}
public static void fK() {
Scanner in = new Scanner(System.in);
System.out.println("enter the temperature in fahrenheit:");
double fToK = in.nextDouble();
System.out.println(fToK + "°F is about " + ((fToK - 32)*5/9 + 273.15) + "°K");
}
public static void kC() {
Scanner in = new Scanner(System.in);
System.out.println("enter the temperature in kelvin:");
double kToC = in.nextDouble();
System.out.println(kToC + "°K is about " + (kToC - 273.15) + "°C");
}
public static void kF() {
Scanner in = new Scanner(System.in);
System.out.println("enter the temperature in kelvin:");
double kToF = in.nextDouble();
System.out.println(kToF + "°K is about " + ((kToF - 273.15)* 9/5 + 32) + "°C");
}
public static void main(String[] args) throws Exception {
while (true) {
whatToDo();
whatNext();
}
}
}
I could think of two easy ways you can achieve this:
The variable whatToConvert is declared inside a variable. Hence its scope (or simply say its access) is only inside that method - unless you specifically pass it as argument to some other method.You can also have variables with global scope - meaning variables declared at class level and not inside a method. Such variables are accessible to all the methods of that class.You can read more on "scope of variables in java".
What you can do here is - declare whatToConvert variable as static at class level instead of inside whatToDo() method.
public class App {
static int whatToConvert = 0;
//all other code
}
Method whatNext() can then have access to this variable.
You know that whatNext() always runs after whatToDo(). In such case, you can return the value of 'whatToConvert' from whatToDo() and pass
that value as method argument to whatNext()
In either case you should extract the if-else code to a new method to add re-usability for method whatNext()
New method can have method signature something like:
public static void decideOperation(int choice) {
//If-else blocks or switch case
}
When you declare a variable in a method, it will be local, so it will be instantiated and in the method and removed once the method is finished. In order for a variable to be read by all methods you should declare it as a global variable, in this way:
public class App {
private static int whatToConvert;
...
public static void whatToDo() {
Scanner in = new Scanner(System.in);
conversions();
whatToConvert = in.nextInt();
...
}
Now you can use whatToConvert in other methods

Formatting java text with void method

I have looked and cant find the information I am looking for. My code is functioning as I expect it to but I have one bit of code that I would like to improve.
The problem is that I can not call a void method within a print statement like this:
System.out.print("Water is a " + printTemp(temperature) + " at" + temperature + " degrees.";
printTemp(temperature is a void method so this won't work, as a result I found a work-around but it is not ideal:
System.out.print("\nWater is a ");
printTemp(temperature);
System.out.print(" at");
System.out.printf(" %.0f", temperature);
System.out.print(" degrees.\n");
here is the full code:
import java.util.Scanner;
public class printTemp {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter the temperature: ");
Double temperature = input.nextDouble();
// takes the state of the water from the printTemp method and
// the temperature to return a formatted output to the user
System.out.print("\nWater is a ");
printTemp(temperature);
System.out.print(" at");
System.out.printf(" %.0f", temperature);
System.out.print(" degrees.\n");
}
public static void printTemp(double temperature) {
String returnMessage = "null" ;
if (temperature < 32 )
returnMessage = "solid";
else if (temperature > 212)
returnMessage = "gas";
else
returnMessage = "liquid";
System.out.printf(returnMessage);
}
}
This is for school thus there are conditions that must remain, printTemp MUST be a void method and the variable temp must remain a DOUBLE.
What about to put the following code snippet
...
System.out.print("Water is a " + returnMessage + " at" + temperature + " degrees.");
to the printTemp method as the last line? Then in the main outputs nothing and you just write:
...
printTemp(input.nextDouble());
Use a class variable to hold the Temperature String word and use the void method to set it.
public class PrintTemp {
private static String TempStr = "";
public static void main(String[]args) {
[...]
printTemp(temperature);
System.out.print("Water is a " + TempStr + " at" + temperature + " degrees.");
}
public static void printTemp(double temperature) {
if (temperature < 32 )
TempStr = "solid";
else if (temperature > 212)
TempStr = "gas";
else
TempStr = "liquid";
}
}
Sorry for the delay guys!
Here is the solution.
import java.util.Scanner;
public class printTemp {
public static void main(String[]args) {
//Read in the temperature from the user
Scanner input = new Scanner(System.in);
System.out.print("\nPlease enter the temperature: ");
//Call and insert the input into the printTemp method.
printTemp(input.nextDouble());
}
public static void printTemp(double temperature) {
//Decide whether the water is in a soild, liquid or gaseous sate.
String returnMessage = "null";
if (temperature < 32 )
returnMessage = "solid";
else if (temperature > 212)
returnMessage = "gas";
else
returnMessage = "liquid";
//Print to the user.
System.out.print("\nWater is a " + returnMessage);
System.out.printf(" at %.0f degrees.%n\n", temperature);
}
}
UPDATE
public class PrintTemp {
public static void main(String[] args) {
double temperature = 35;
StringBuilder returnMessage = new StringBuilder();
printTemp(temperature, returnMessage);
System.out.print("Water is a " + returnMessage + " at " + temperature + " degrees.");
}
public static void printTemp(double temperature, StringBuilder returnMessage) {
if (temperature < 32)
returnMessage.append("solid");
else if (temperature > 212)
returnMessage.append("gas");
else
returnMessage.append("liquid");
}
}
This is the easiest way to have printTemp modify the message without actually returning it and without using additional classes / beans.
But this does work only for objects (not primitive type) and amongst objects it does not work for Strings because in Java they are treated as a special case. (That is why I had to use a StringBuilder, StringBuffer would work too)

having a variable in recursive method not redefine itself after each call

I am going to post my code below because this is kind of hard to describe. The code below works, but it is using Math.pow in the main method rather than in the helper, so if someone could show me a way to move the power to the helper method without messing up the program that would be much appreciated.
Main method:
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter an integer: ");
double input = keyboard.nextInt();
double x = Math.pow(2.0, input);
int n = (int)x;
System.out.println(starStr(n));
Helper method:
public static String starStr(int n)
{
if (n >= 1) {
return ("*" + starStr(n-1));
}
else {
return "";
}
}
EDIT:
if(n == 0) {
return "*";
}
else {
return starStr(n - 1) + "**";
}
Something like this would work. You don't really need to use a power function at all. Just start with 1 star and double the number of stars in every step of the recursion.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter an integer for the number of stars: ");
int input = keyboard.nextInt();
System.out.println(doStars(input));
}
public static String doStars(int n)
{
//If n == 0 the recursion is done
//Otherwise, reduce n by 1 and double the number of stars
if(n == 0)
return "*";
else
{
String output = doStars(n - 1);
return output + output;
}
}
I think this is what you are looking for. Not sure if you have learned the tree data-structure, but that's the purpose of my variable names.
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
// 1 + (2^n)-1 = 2^n
System.out.println("*" + doStars(i));
}
}
public static String doStars(int n)
{
if (n == 0) {
return "";
}
else {
String subTree = doStars(n - 1);
return subTree + "*" + subTree; // length = (2^n)-1
}
}
}
Output
*
**
****
********
****************
Visualization - read clockwise in triangles from little to big
"*"
+
doStars(2)
"*"
doStars(1) + doStars(1)
"*" "*"
doStars(0) + doStars(0) doStars(0) + doStars(0)
"" "" "" ""

Set and get with arguments in Java

I new to java, still trying to get down arguments and passing info. I am writing a blood pressure program for school and have some issue passing info from one class to another.
I have a fully functioning system to take in the user info in one class and have to set up another to check if the average is above or below range. Now, the range is easy, but the passing of info is another thing.
Here is part of my program (in the class PressureInput) and where my issues start:
public void setSystolic(int sys)
{
sys = sysAvrg;
}
So, assuming the avrgSys has a number (it does), I then want to pass the info to the other class (BPChecker).
I don't feel like I'm doing this right, or at least, not in such a way as to facilitate passing the 'int' of sysAvrg from the class its in into another class (BPChecker).
I'm not sure whether to use a getSystolic since I'm not sure what the return would be.
I can't just initialize sys in the other class (BPChecker) without giving sys a value (which defeats the purpose), but it keeps telling me to.
In the end, I need to move the number of avrgSys into BPChecker without rewriting the whole program. So far, I keep getting a lot of 0s or errors...
Any help is appreciated, though my newness may have more complicated explanations go over my head (sorry to say).
So, here's the code i wrote. the ONLY thing I'm worried about is the very last part, the 'getSystolic' and its return. I need to send the info to another part of the program not in main or in this PressueInput (its BPChecker btw) and just banging my head against the problem.
Thank you for the input:
` import java.util.Scanner;
public class PressureInput
{
private int sysInput;
private int diaInput;
private int sysAvrg;
private int diaAvrg;
public PressureInput()
{
sysInput = 0;
diaInput = 0;
sysAvrg = 0;
diaAvrg = 0;
}
public void setSysPressure()
{
sysInput = 0;
while(sysInput <= 0 || sysInput >= 320)
{
Scanner cin = new Scanner(System.in);
System.out.println("Please enter a systolic reading> ");
sysInput= cin.nextInt();
System.out.println("You have entered " + sysInput + "\n");
if(sysInput <=0 || sysInput >= 320)
{
System.out.println("You're either dead or entered"
+ " an error. Try again." + "\n");
}
}
sysAvrg += sysInput;
}
public int getSysPressure()
{
return sysInput;
}
public void setDiaPressure()
{
diaInput = 0;
while(diaInput <= 0 || diaInput >= 320)
{
Scanner cin = new Scanner(System.in);
System.out.println("Please enter a systolic reading> ");
diaInput= cin.nextInt();
System.out.println("You have entered " + diaInput + "\n");
if(diaInput <=0 || diaInput >= 320)
{
System.out.println("You're either dead or entered"
+ " an error. Try again." + "\n");
}
}
diaAvrg += diaAvrg;
}
public int getDiaPressure()
{
return diaInput;
}
public void sysAvrgRead()
{
sysAvrg = sysAvrg / 3;
System.out.println("\n" + "The systolic averge is " + sysAvrg);
}
public void diaAvrgRead()
{
diaAvrg = diaAvrg / 3;
System.out.println("The diastolic averge is " + diaAvrg + "\n");
}
public void setSystolic(int sys)
{
sysAvrg = sys;
}
public int getSystolic()
{
return sys;
}
} `
In Object-oriented programming, you can create an instance of an object in any class you want. In order to access class variables from other classes, you can use accessor methods.
i.e.
public class PressureInput {
private static int sysAvrg;
public PressureInput(int sysAvrg){
this.sysAvrg = sysAvrg;
}
public void setSystolic(int sys){
this.sysAvrg = sys;
}
public int getSystolic() {
return this.sysAvrg;
}
}
You have a variable called sys so if you want to set it with the average create a setter Method:
public void setSystAve(float sysAvrgParameter){
sysAvrg = sysAvrgParameter;
}
if you want to get the sysAvrg create a getter Method:
public float getSystAve(){
return sysAvrgParameter;
}
now somewhere in your code:
sys = yourObject.getSystAve();

Getting code error for a simple ChatBot program

I'm getting an error at the 2nd class c.getResponse
The method getResponse(String) is undefined for the type BotTest
If anyone wants to see what the assignment was heres the pdf:
http://www.cs.stonybrook.edu/~tashbook/fall2013/cse110/project-1.pdf
import java.util.*;
public class ChatBot {
public String getResponse(String input) {
int i = 0;
int found = input.indexOf("you", i);
if (found == -1)
return "I'm not important. Let's talk about you instead.";
int x = longestWord(input).length();
if (x <= 3) {
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
if (x == 4) {
return "Tell me more about" + " " + longestWord(input);
}
if (x == 5) {
return "Why do you think" + " " + longestWord(input) + " "
+ "is important?";
} else if (x > 5) {
return "Now we are getting somewhere. How does" + " "
+ longestWord(input) + " " + "affect you the most";
}
else
return "I don't understand";
}
private String longestWord(String input) {
String word, longestWord = "";
Scanner turtles = new Scanner(input);
while (turtles.hasNext()) {
word = turtles.next();
if (word.length() > longestWord.length())
longestWord = word;
}
return longestWord;
}
}
Second Class to test the code
import java.util.*;
public class BotTest {
public static void main(String[] args) {
Scanner newturtles = new Scanner(System.in);
System.out.println("What would you like to talk about?");
String input = newturtles.nextLine();
BotTest c = new BotTest();
while (!input.toUpperCase().equals("GOODBYE")) {
System.out.println(c.getResponse(input));
input = newturtles.nextLine();
}
}
}
getResponse is defined for ChatBot not BotTest
ChatBot c = new ChatBot();
The Class BotTest indeed does NOT have the .getResponse(String) function. ChatBot does though.

Categories

Resources