How do i convert an if-else statement to a switch statement - java

I have this program of rolling dice by 1000000 and finding the number of 1's, 2's, 3's, 4's, 5's, 6's`but i need to make a switch statement as well. Im having trouble using the scanner input
import java.util.Random;
public class DiceRoll_NP {
public static void main(String[] args) {
Random rand = new Random();
final double NUMBER_OF_ROLLS = 1000000.0;
int x = rand.nextInt();
// System.out.println(x);
int ones = 0, twos = 0, threes = 0, fours = 0, fives = 0, sixes = 0;
for (int i = 1; i <= NUMBER_OF_ROLLS; i = i + 1) {
int y = rand.nextInt(6) + 1;
if (y == 1) ones++;
else if (y == 2) twos++;
else if (y == 3) threes++;
else if (y == 4) fours++;
else if (y == 5) fives++;
else if (y == 6) sixes++;
System.out.print(y + " ");
}
System.out.printf("\nOnes: %.2f%%\n", 100 * ones / NUMBER_OF_ROLLS);
System.out.printf("Twos: %.2f%%\n", 100 * twos / NUMBER_OF_ROLLS);
System.out.printf("Threes: %.2f%%\n", 100 * threes / NUMBER_OF_ROLLS);
System.out.printf("Fours: %.2f%%\n", 100 * fours / NUMBER_OF_ROLLS);
System.out.printf("Fives: %.2f%%\n", 100 * fives / NUMBER_OF_ROLLS);
System.out.printf("sixes: %.2f%%\n", 100 * sixes / NUMBER_OF_ROLLS);
}
}
This i what i have so far. When i run it, nothing comes up
import java.util.Random;
public class DiceRoll_Switch {
public static void main(String[] args) {
Random rand = new Random();
int ones = 0, twos = 0, threes = 0, fours = 0, fives = 0, sixes = 0;
int y = rand.nextInt(6) + 1;
for (int i = 1; i <= 1000000; i = i + 1)
switch (y){
case 1: ones++;
break;
case 2: twos++;
break;
case 3: threes++;
break;
case 4: fours++;
break;
case 5: fives++;
break;
case 6: sixes++;
break;

In the early days of programming, the goto statement was heavily used. It works like this:
if ( true )
goto label;
System.out.println("A");
label:
System.out.println("B");
The above code would jump to the label, skipping printing the A. It's pretty simple.
Now, why did I mention this? Here's an example of an if statement:
if ( y == 1 )
System.out.println("It is 1");
else
System.out.println("It is not 1");
and here's how it works using goto:
if ( y != 1 )
goto not_1;
// this is the 'then' part:
System.out.println("It is 1");
goto done; // we don't want to run the 'else' part!
not_1:
// this is the 'else' part
System.out.println("It is not 1");
done:
If you understand this, then a switch statement won't be any trouble.
A switch statement looks like this:
switch (y) {
case 1: ones++; break;
case 2: tows++; break;
default: System.out.println("Unexpected number of eyes: " + y);
}
It compares the value of y with all the values after the case, and if it is a match, starts executing the code at that case. The break indicates that that case is done. The default 'case' gets executed when none of the cases is a match.
And here's how it basically works using goto:
if ( y == 1 ) goto case_1;
if ( y == 2 ) goto case_2;
// here comes the default:
default:
System.out.println("Unexpected number of eyes: " + y);
goto switch_done;
case_1:
ones++;
goto switch_done; // this is the 'break' statement.
case_2:
twos++;
goto switch_done;
switch_done: // end of the switch.
I hope this makes things a bit more clear as to how it works!
That said, you're better off using an array:
int eyes[] = new int[] { 0,0,0,0,0,0 };
for ( int i = 1; i <= NUMBER_OF_ROLLS; i++ )
{
int y = rand.nextInt(6) + 1;
eyes[y] ++;
}
This also makes your printing much shorter:
for ( int i = 0; i < eyes.length; i ++ )
System.out.printf( (i+1) + ": %.2f%%\n", 100 * eyes[i] / NUMBER_OF_ROLLS );
You are basically doing the same thing for each y, and you should want to write as little code as possible: it is easier to maintain and to understand, and, there is less chance of bugs.

It's very similar. These two are pretty much doing the exact same thing:
int x = 2;
if(x == 1) {
System.out.println("1");
}
else if(x == 2) {
System.out.println("2");
}
else {
System.out.println("None of the above");
}
int x = 2;
switch(x) {
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("None of the above");
break;
}

A switch statement consists in:
switch (y) {
case 1:
ones++;
break;
case 2:
twos++;
break;
...
}
and so on, where the value inside the parenthesis is the variable name you want to check, and the number after "case" is the cases it may happen. You MUST put a break after your instruction is over to tell the program it can exit the switch statement after he founds the correct one and stops executing. Otherwise, if you don't put the break; command in the "case 1" block, it'll keep executing every line until it finds a break, and both "ones" and "twos" will be added

Related

Random Math Question Generator not following while loop

I'm a new java coder getting into it doing a project. I coded it how i believe the system would execute it and yet it doesn't seem to be following the While loops requirements. I want it to generate random number, do a random operation, then ask the user for an answer. The answer must be not decimal and the random numbers must be below 10 to make the questions easier as its for a lower target audience. I'm kind of stuck now on this piece. Apologies if this doesn't make sense as i say it is a first attempt for me.
import java.util.Random;
import java.lang.Math;
import java.util.Scanner;
public class RandomisedQuestions{
public static void QuestionGenerator(){
Random r = new Random();
Scanner s = new Scanner(System.in);
int intA = 0;
int intB = 0;
char operator ='?';
double value = 1.2;
for (int i = 0; i < 3; i++) {
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
if (intA <= 0 && intB <= 0){
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
System.out.println(intA + intB);
}
while ((value % 1) !=0 && value > 1){//Runs while value is not whole
switch (r.nextInt(4)){
case 0: operator = '+';
value = intA+intB;
break;
case 1: operator = '-';
value = intA-intB;;
break;
case 2: operator = '*';
value = intA*intB;;
break;
case 3: operator = '/';
value = intA/intB;;
break;
default: operator = '?';
}
//System.out.println(operator);
}
System.out.println(intA +""+ operator +""+ intB);
System.out.println("Enter the answer");
int uGuess = s.nextInt();
if (uGuess == value){
System.out.println("Correct");
}
else{
System.out.println("Incorrect");
}
}
}
}
It's better to use ThreadLocalRandom.nextInt to generate your numbers:
// At the start of your program initialize the generator:
ThreadLocalRandom r = ThreadLocalRandom.current();
// Later use it:
do {
intA = ThreadLocalRandom.nextInt(1, 10);
intB = ThreadLocalRandom.nextInt(1, 10);
switch (r.nextInt(4)) {
case 0: operator = '+';
value = intA + intB;
break;
case 1: operator = '-';
value = intA - intB;
break;
case 2: operator = '*';
value = intA * intB;
break;
case 3: operator = '/';
value = (double)intA / intB;
break;
default: operator = '?';
}
} while (value != (int)value || value <= 1);
Also note the conversion to double in division case, otherwise the division will be performed for integer types.

How can I use percentages in a switch condition to represent player status based on health?

I should preface this by saying I'm VERY new to coding and Java in general; forgive my stupidity! I'm attempting to set up a status system for the player based on how much health they have, wherein their current Status is a String involved in a switch function which changes from "You are doing fine!" to "You are dying!". However, rather than doing it with single digits, I want to do it with percentage of health so the message does not change when they reach 50 or 25 percent health, whether the player has 50 or 10 health max.
Essentially, I want to make it so in place of single variables representing certain values of health in the switch function, percentages of PCHealth do. This is what I don't want, but what I know how to do:
int PCHealth = 10;
String Status = "";
switch (PCHealth) {
case 5: Status = "You're fine!";
case 2: Status = "You're dying!";
}
Here's what I want sketched out in fake code:
int PCHealth = 10;
String Status = "';
switch (PCHealth) {
case [50% of PCHealth] = "You're fine!";
case [20 % of PCHealth] = "You're dying!";
}
Thank you!
Just do it with if-else. Its very simple and good to understand.
public String getStatus(int PChealth, int maxValue) {
float percent = (PChealth * 1.0f) / maxValue;
if (percent > 75) return "great";
else if (percent > 50) return "mid";
else if (percent > 25) return "not good";
else if (PChealth == 0) return "dead";
else return "bad";
}
Side notes: The first if that evalute true will return the correct value.
Savvy?
/*
Things that you will need to know
- integer division vs double
- type casting
- Math.ceil()
# int division
10/25 --> 0
# double division
10.0/25 --> 0.4
# Math.ceil()
Math.ceil(0.4) --> 1.0
0-25 XXX
25-50 fine
50-75 good
75-100 great
*/
Play with this code, printout things that you don't understand or what value they are holding... I tried to keep things simple.
public class MyClass {
private static int maxHealth = 100;
public static String getPlayerHealthStatus(double pHealth){
String pHStatus = "";
int pHealth_case = (int) Math.ceil( pHealth / (maxHealth / 4));
switch (pHealth_case) {
case 4:
pHStatus = "You're doing great!";
break;
case 3:
pHStatus = "You're doing good!";
break;
case 2:
pHStatus = "You're fine!";
break;
case 1:
pHStatus = "You're dying!";
break;
case 0:
pHStatus = "You died!";
break;
default:
pHStatus = "invalid player health";
}
return pHStatus;
}
public static void main(String args[]) {
int playerHealth = 90;
System.out.println("player health: "+playerHealth+" status: "+getPlayerHealthStatus(playerHealth));
playerHealth = 70;
System.out.println("player health: "+playerHealth+" status: "+getPlayerHealthStatus(playerHealth));
playerHealth = 40;
System.out.println("player health: "+playerHealth+" status: "+getPlayerHealthStatus(playerHealth));
playerHealth = 20;
System.out.println("player health: "+playerHealth+" status: "+getPlayerHealthStatus(playerHealth));
playerHealth = 0;
System.out.println("player health: "+playerHealth+" status: "+getPlayerHealthStatus(playerHealth));
}
}
Output:
player health: 90 status: You're doing great!
player health: 70 status: You're doing good!
player health: 40 status: You're fine!
player health: 20 status: You're dying!
player health: 0 status: You died!
Its not possible to have expressions in case statements, use if-else statements or like #Onkar said store them in a separate variable.
if-else should be cleaner for your use case.
I would store the max health in the variable MaxHealth then try the following switch! :)
Here we have if statement in the switch statement, that will do case 1 if the health is between 0 and 20% and so on
double PCHealth = __ ;
switch (((0 <= PCHealth && PCHealth <= (0.2 * MaxHealth)) ? 0 :
((0.2 * MaxHealth) > PCHealth && (0.5 * MaxHealth) < PCHealth) ? 1 : 2)
{
case 0:
Status = "You're dying!";
break;
case 1:
Status = "You're fine!";
break;
case 2:
Status = "You're doing excelent";
break;
}

Need help coming up with an algorithm to generate a random boolean in Java depending on count and percentages

I'm not sure if I even titled this post correctly. If I didn't, let me know and I'll edit the title.
What I am trying to do is simulate a "real-world" situation for charging batteries:
1st charge == 100% chance of an error (a.k.a., boolean false)
2nd charge == 90% chance of an error
3rd charge == 80% chance of an error
4th charge == 70% chance of an error
5th charge == 60% chance of an error
6th charge == 50% chance of an error
7th charge == 40% chance of an error
8th charge == 30% chance of an error
9th charge == 20% chance of an error
10th charge == 10% chance of an error
So, what I need is an algorithm to generate a true or false depending on these percentages, but I have no idea how to do it. I know there is Random and ThreadLocalRandom but there is no way to input any bounds or values for nextBoolean(). I figured I could do something like this:
switch(charge){
case 1:
if(ThreadLocalRandom.nextInt(10,10) > 10) return ThreadLocalRandom.nextBoolean();
break;
case 2:
if(ThreadLocalRandom.nextInt(9,10) > 9) return ThreadLocalRandom.nextBoolean();
break;
case 3:
if(ThreadLocalRandom.nextInt(8,10) > 8) return ThreadLocalRandom.nextBoolean();
break;
case 4:
if(ThreadLocalRandom.nextInt(7,10) > 7) return ThreadLocalRandom.nextBoolean();
break;
case 5:
if(ThreadLocalRandom.nextInt(6,10) > 6) return ThreadLocalRandom.nextBoolean();
break;
case 6:
if(ThreadLocalRandom.nextInt(5,10) > 5) return ThreadLocalRandom.nextBoolean();
break;
case 7:
if(ThreadLocalRandom.nextInt(4,10) > 4) return ThreadLocalRandom.nextBoolean();
break;
case 8:
if(ThreadLocalRandom.nextInt(3,10) > 3) return ThreadLocalRandom.nextBoolean();
break;
case 9:
if(ThreadLocalRandom.nextInt(2,10) > 2) return ThreadLocalRandom.nextBoolean();
break;
case 10:
if(ThreadLocalRandom.nextInt(1,10) > 1) return ThreadLocalRandom.nextBoolean();
break;
}
As you can see, I have no idea what I am doing, so I need some help.
Thanks!
1. Explanation and solution :
What you need is :
generate a random number (use Random class) between 0 and 10
depending on the value of charge, find the range of acceptance for the random number :
example : if the charge is 4, to get an error the random has to be is [0;7] (70% of the range) so return random >=7;
private static boolean isError(int charge) {
int random = new Random().nextInt(10);
switch (charge) {
case 1: return random >= 10;
case 2: return random >= 9;
case 3: return random >= 8;
case 4: return random >= 7;
case 5: return random >= 6;
case 6: return random >= 5;
case 7: return random >= 4;
case 8: return random >= 3;
case 9: return random >= 2;
case 10: return random >= 1;
default: return false;
}
}
2. Shorter Solution
This can be simplified in :
private static boolean isError(int charge) {
return new Random().nextInt(10) >= (11 - charge);
}
3. Tests & Demo : Demo
With this main, you can test the validity of the method, it tests nbTest times, each charge, and see how many times you got an error
public static void main(String[] args) {
DecimalFormat df = new DecimalFormat("##.##%");
double nbError, nbTest = 100000;
for (int charge = 1; charge < 11; charge++) {
nbError = 0;
for (int j = 0; j < nbTest; j++) {
nbError += (isError(charge) ? 0 : 1);
}
System.out.println(charge + " -> " + df.format(nbError / nbTest));
}
}
1 -> 100 % ~100%
2 -> 90,06% ~ 90%
3 -> 80,31% ~ 80%
4 -> 69,97% ~ 70%
5 -> 59,92% ~ 60%
6 -> 49,9 % ~ 50%
7 -> 39,9 % ~ 40%
8 -> 30,08% ~ 30%
9 -> 19,84% ~ 20%
10 -> 10,18% ~ 10%
One simple mechanism would be to calculate a value between 0.0 and 1.0 dependent on the charge count and then just compare that with a random double.
public void test() {
// Test each charge.
for (int charge = 0; charge < 10; charge++) {
// Using ints here so output is clearer - could just as easily use bool.
List<Integer> results = new ArrayList<>();
for (int test = 0; test <= 100; test++) {
// Use 0 or 1 debending on random biased boolean.
results.add(biasedBoolean(1.0 - ((float) charge / 10)) ? 0 : 1);
}
System.out.println("Charge " + (charge + 1) + " -> " + results);
}
}
Random random = new Random();
private Boolean biasedBoolean(double bias) {
return random.nextDouble() < bias;
}
You may need to tweak the maths to make sure you get the right statistics on your values but this certainly shows one technique.

Beginner level Java - Zellers algotrithm

I have an assignment in Java (intro to programming) based on Zellers algorithm, Write input as integers, loop and counter code and I have to use a while loop to get the day and year first then the month, treating Jan & Feb as prior year. I thought I was at least in the ballpark, but cannot get my code to work. Any suggestions on how to improve?
import java.util.Scanner;
import java.text.NumberFormat;
public class ZellersAlgorithm {
public static void main(String[] args) {
//declarations go here
int count, Month, Day, Year;
int C = (int)(Year / 100.0); // the century
int D = (int) (Year % 100); // The year of the century
int K = Day;
int M = Month;
int G = (K + (int)((26 * (M + 1)) / 10.0) + C + (int)(C / 4.0)
+ (int)(D / 4.0) + (5 * D)) % 7;
Month = (M);
Day = (K);
Year = (C + D);
Scanner scan = new Scanner(System.in);
//Title
System.out.println("Project 2 - Zellers Algorithm");
while(M != 0){
System.out.print("Enter a numberic day: ");
K = scan.nextInt();
if (K == 0)
System.out.print("Saturday");
else if (K == 1)
System.out.print("Sunday");
else if (K == 2)
System.out.print("Monday");
else if (K == 3)
System.out.print("Tuesday");
else if (K == 4)
System.out.print("Wednesday");
else if (K == 5)
System.out.print("Thursday");
else
System.out.print("Friday");
System.out.print("Enter a nummeric year: ");
///Need to convert 4 digit year to C & D variable
// Add counter, possibly include length counter 1st 2 digits are century/C last 2 are year
Year = scan.nextInt();
System.out.print("Enter a numeric month: ");
M = scan.nextInt();
switch (M) {
case 1:
System.out.println("March");
break;
case 2:
System.out.println("April");
break;
case 3:
System.out.println("May");
break;
case 4:
System.out.println("June");
break;
case 5:
System.out.println("July");
break;
case 6:
System.out.println("August");
break;
case 7:
System.out.println("September");
break;
case 8:
System.out.println("October");
break;
case 9:
System.out.println("November");
break;
case 10:
System.out.println("December");
break;
case 11:
System.out.println("January" + D + count--);
break;
case 12:
System.out.println("February" + D + count--);
break;
default:
System.out.println("Invalid month.");
break;
}
}
//formula one
//G =([2.6M-.2]+K+D+[D/4]+[C/4]-2C mod 7;
//display as integer
String result = "Day of the week is ";
System.out.println();
Please clarify on what but cannot get my code to work means.
Some comments though
int count, Month, Day, Year; -- variables should be lower case (this does not change the behaviour of your program but is common code style for Java programs - Most people would read Year as a class name). The same goes for "all uppercase" like C, which is normally used for constants
Use variable names that express meaning. M, K, C, D do not help the reader to understand, what they mean.

Generate sets of numbers which only have a difference of 1 from the last set of numbers in a 2d array

Problem: I want to generate random locations on a grid which are touching. The total number of locations is 5. Is there a more efficient/different way of doing the following code:
/*
* 8 1 2
* 7 [original] 3
* 6 5 4
*/
int rand = 1 + (int)(Math.random() * ((8 - 1) + 1));
if(rand >= 2 && rand<= 4)
{
newx++;
}
else if(rand >=6 && rand<=8)
{
newx--;
}
//change y according to number
if(rand == 8 || rand == 1 || rand==2)
{
newy++;
}
else if(rand >= 4 && rand<= 6 )
{
newy--;
}
According to this Thread a switch statement seems to be more efficient for your case. Also it makes your code way more readable.
switch (rand){
case 1: newy++; break;
case 2: newx++; newy++; break;
case 3: newx++; break;
case 4: newx++; newy--; break;
case 5: newy--; break;
case 6: newx--; newy--; break;
case 7: newx--; break;
case 8: newx--; newy++; break;
}
I would advise on the use of Random.nextInt(8) Vs Math.random()*8 (see here why). Because your current requirements seem to allow one "seed" only, you could declare a static Random random = new Random(); in your class, so you just call random.nextInt(8) in your method.
int rand = random.nextInt(8); //0..7
if (rand < 3) //0,1,2
{
newx++;
}
else if (rand < 6) //3,4,5
{
newx--;
}
//change y according to number
if(rand % 3 == 0) //0,3,6
{
newy++;
}
else if(rand % 3 == 1) //1,4,7
{
newy--;
}
As you may notice, the above has the same impact with your approach, but uses the modulo operation mainly for readability purposes, cause mod is not as fast as an if checking.
Small Edit by OP: (result of random represented graphically on x and y axis)
6 3 0
5 [origin] 2
4 7 1

Categories

Resources