This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 5 years ago.
I am required to implement an interface as part of my final school assignment for my Java class. The overridden interface is supposed to print a short message describing how a football player celebrates being drafted in the NFL, something like this:
System.out.println("name dances to celebrate his draft");
However my interface is not printing the message when I put it into the methods which allow the user to add a player to their roster. Here is the overridden interface in the program:
//Overridden celebrate method
#Override
public void celebrate(int i, int place){
int randomInteger;
if (place == 0) //Player is offensive
{
randomInteger = random1Thru6();
//players() is a method that contains all the players in the team
//'place' refers to the players location in the array of players on the team
switch (randomInteger)
{
case 1: System.out.println(players(i).get(place) + " dances to celebrate his draft!");
break;
case 2: System.out.println(players(i).get(place) + " cartwheels to celebrate his draft!");
break;
case 3: System.out.println(players(i).get(place) + " throws a party to celebrate his draft!");
break;
case 4: System.out.println(players(i).get(place) + " sings to celebrate his draft!");
break;
case 5: System.out.println(players(i).get(place) + " gets root beer for everyone to celebrate his draft!");
break;
case 6: System.out.println(players(i).get(place) + " gets donuts to celebrate his draft!");
}
}
else if (place == 1) //Player is defensive
{
randomInteger = random1Thru6();
switch (randomInteger)
{
case 1: System.out.println(players(i).get(place) + " dances to celebrate his draft!");
break;
case 2: System.out.println(players(i).get(place) + " cartwheels to celebrate his draft!");
break;
case 3: System.out.println(players(i).get(place) + " throws a party to celebrate his draft!");
break;
case 4: System.out.println(players(i).get(place) + " sings to celebrate his draft!");
break;
case 5: System.out.println(players(i).get(place) + " gets root beer for everyone to celebrate his draft!");
break;
case 6: System.out.println(players(i).get(place) + " gets pizza to celebrate his draft!");
}
}
}
I am supposed to have one different celebratory response for offensive and defensive positions as is shown in the code above.
Here is the referenced random1Thru6() method:
public int random1Thru6() { //used to get a random number from 1 to 6
int randomInteger = (int)Math.random() * 10;
//this is supposed to call the method over and over again until it gives a number from 1-6 but it has been printing 7-9 as well
if (randomInteger > 6)
random1Thru6();
return randomInteger;
}
And here is the players() method:
//holds and prints all the players
public ArrayList<String> players(int i) {
ArrayList<String> returnedList = new ArrayList<>();
// Christian McCaffrey is a Running Back, Corn Elder is a Corner Back for the Carolina Panthers
ArrayList<String> Players1 = new ArrayList<String>();
Players1.add("Christian McCaffrey");
Players1.add("Corn Elder");
//Jake Butt is a Tight End, Brendan Langley is a Corner Back for the Denver Broncos
ArrayList<String> Players2 = new ArrayList<String>();
Players2.add("Jake Butt");
Players2.add("Brendan Langley");
//Ryan Switzer is a Wide Receiver, Taco Charlton is a Defensive End for the Dallas Cowboys
ArrayList<String> Players3 = new ArrayList<String>();
Players3.add("Ryan Switzer");
Players3.add("Taco Charlton");
//Dalvin Cook is a Running Back, Ifeadi Odenigbo is a Defensive Line for the Minnesota Vikings
ArrayList<String> Players4 = new ArrayList<String>();
Players4.add("Dalvin Cook");
Players4.add("Ifeadi Odenigbo");
switch (i)
{
case 1: returnedList.addAll(Players1);
break;
case 2: returnedList.addAll(Players2);
break;
case 3: returnedList.addAll(Players3);
break;
case 4: returnedList.addAll(Players4);
break;
}
return returnedList;
}
Here is how the celebrate() method is called:
for (int l = 0; l < players(i).size(); l++)
{
if (choosePlayer.equalsIgnoreCase(players(i).get(l)))
{
addPlayer(players(i).get(l));
celebrate(i, l);
enterRoster();
}
}
And:
addPlayer(players(i).get(place));
celebrate(i, place);
enterRoster();
addPlayer(int i, int place) is a method that adds the player for team 'i' in the position of 'place' in the team's player array into the ArrayList of the user's roster.
NOTE: I checked what number was being called by random1Thru6() as suggested in a comment and now I understand why it wasn't printing the celebrate message, since I had (int)Math.random() * 10 it was always returning 0 so I changed it to:
double randomDouble = Math.random() * 10;
int randomInteger = (int)randomDouble;
Now it prints the celebrate messages but random1Thru6() is now returning all numbers 1-9, please explain how I can make this method call itself recursively until it will return a number 1-6.
Thank you delephin for your comment!
NOTE: I have accepted delephin's answer shown below, thank you all for the help!
Add to your main class:
static Random r = new Random();
static {
r.setSeed(System.currentTimeMillis());
}
and change your randomizer method to something like this:
public int random1Thru6() {
return r.nextInt(6) + 1;
}
From a quick test, your previous randomizer was returning zeros.
Related
I am creating a game of rock paper scissors, on the playGame() method I cannot get the code to work, it only prints out what the user and computer has chosen. I have tried to figure out where i am going wrong and all i could get it to do was the print out a draw but it made the game always draw!
I haven't finished the method yet, i also need to add a score counter up to 3.
import java.util.Random;
public class RockPaperScissors
{
private InputReader reader;
private int yourScore;
private int computerScore;
private Random ran;
/**
* Constructor for objects of class RockPaperScissors
*/
public RockPaperScissors()
{
reader = new InputReader();
yourScore = 0;
computerScore = 0;
ran = new Random(1);
}
/**
* An example of a method - replace this comment with your own
*/
public void printPrompt()
{
System.out.println();
System.out.println();
System.out.println("Enter your choice, paper, rock or scissors >");
}
public String userChoice()
{
String input = reader.getInput();
input = input.trim().toLowerCase();
return input;
}
public String computerChoice()
{
Random ran = new Random();
int myRanInt = ran.nextInt(3);
String computerRanChoice ="";
switch(myRanInt) {
case 0: computerRanChoice = "paper";
break;
case 1: computerRanChoice = "scissors";
break;
case 2: computerRanChoice = "rock";
break;
}
return computerRanChoice;
}
public void playGame()
{
printPrompt();
String userMove = this.userChoice();
System.out.println("you have chosen " + userMove + " and the computer has chosen " + computerChoice());
int roundWinner = 0;
int count = 1;
switch(roundWinner) {
case 0: computerChoice().equals(userChoice());
System.out.println("This game is a draw");
break;
case 1: computerChoice().equals("rock");
System.out.println(userMove.equals("paper") ? "The computer is the winner" : "You are the winner");
break;
case 2: computerChoice().equals("paper");
System.out.println(userMove.equals("scissors") ? "The computer is the winner" : "You are the winner");
break;
case 3: computerChoice().equals("scissors");
System.out.println(userMove.equals("rock") ? "The computer is the winner" : "You are the winner");
break;
}
}
}
In the switch block of playgame() method, you have initialised the value of roundWinner as 0, so it will always print out case 0, i.e. the draw statement.
Using switch in this case seems a bit tricky, as you are working with two variables, the computer's and the player's choice, while switch works on only one variable. Try using some if statements first and then work your logic to switch if needed
So, I made a burger class with a method for extra stuff, my question is how can I use case 0,1,2 only 1 time, like if I use case 0, I can't use it anymore, I can use only 1 and 2, If I use case 1 after 0 , then I can use only case 2 since I used case 0 and 1 before , It's possible to do something like that ? If yes how ?
The code:
boolean flag=true;
while(flag){
System.out.println("Enter your choice for extra toppings ");
int choice=scanner.nextInt();
scanner.nextLine();
switch(choice) {
case 0:
double salad = 0.35;
setAdditional(getAdditional() + salad);
System.out.println("salad added\n");
break;
case 1:
double bacon=1.05;
setAdditional(getAdditional()+bacon);
System.out.println("Bacon added \n");
break;
case 2:
double fries=0.79;
setAdditional(getAdditional()+fries);
System.out.println("fries added \n");
break;
case 3:
System.out.println("Done");
flag=false;
}
}
} ```
boolean flag = true;
Set<Integer> set = new HashSet<>();
while (flag) {
System.out.println("Enter your choice for extra toppings ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 0:
if (!set.contains(choice)) {
double salad = 0.35;
setAdditional(getAdditional() + salad);
System.out.println("salad added\n");
break;
}
else {
System.out.println("Added already");
}
continue;
case 1:
double bacon = 1.05;
setAdditional(getAdditional() + bacon);
System.out.println("Bacon added \n");
break;
case 2:
double fries = 0.79;
setAdditional(getAdditional() + fries);
System.out.println("fries added \n");
break;
case 3:
System.out.println("Done");
flag = false;
}
set.add(choice);
}
}
so I did it with Set in the end, only for salad, but it's the same for the rest, if someone else needs it.
your cases go by integer numbers, so an array of boolean with 1 element for every option.
boolean[] allowed = new boolean[options]; (faster than hasMap of string to boolean).
add a check just before the "switch" statement:
if(allowed[choice] && choice != 3) {...}
you should also create an integer constant STOP_OPTION or something like that and use it in the above if-statement and in the final "case" of your switch statement. in your example, set it to 3. then later you can change it without replacing all instances of "3" in your code. but that's more of a styling suggestion.
the "flag" boolean is also redundant, the while loop can just check if choice != 3. be careful of NumberFormatExceptions!
good luck!
Prompt: "Write a program to play the pig game against the computer. At each turn, the current player will
roll a pair of dice and accumulates points. The goal is to reach to 100 or more points before your
opponent does. (For the testing purposes use 30 instead of 100 points) If, on any turn, the player
rolls a 1, all the points accumulated for that round are forfeited and the control of the dice
moves to the other player. If the player rolls two 1s in one turn, the player loses all the points
accumulated thus far are forfeited and the control moves to the other player. The player may
voluntarily turn over the control of the dice after each roll. Therefore player must decide to roll
again (be a pig) and risk losing points, or relinquish control of the dice, possibly allowing the
other player to win. Computer is going to flip a coin to choose the first player "
My problem: I got the program to output that either the computer or the player is going first based on a coin flip. However, how would I actually prompt the program to run a method of the person chosen to start first, and then how would I switch between the computer and player at the end of each turn? Btw, I know this code is incomplete, but I hope that my question makes sense.
Code so far:
import java.util.*;
public class NavaiPigGame
{
public static final int POINT = 30;
public static final int FORFEIT_POINTS = 20;
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
Random rand = new Random();
play(rand,input);
}
// desription of game
public static void description()
{
System.out.println("***********************************************************************************");
System.out.println("Write a program to play the pig game against the computer. At each turn, the current player will");
System.out.println("roll a pair of dice and accumulates points. The goal is to reach to 100 or more points before your");
System.out.println("opponent does. (For the testing purposes use 30 instead of 100 points) If, on any turn, the player");
System.out.println("rolls a 1, all the points accumulated for that round are forfeited and the control of the dice");
System.out.println("moves to the other player. If the player rolls two 1s in one turn, the player loses all the points");
System.out.println("accumulated thus far are forfeited and the control moves to the other player. The player may");
System.out.println("voluntarily turn over the control of the dice after each roll. Therefore player must decide to roll");
System.out.println("again (be a pig) and risk losing points, or relinquish control of the dice, possibly allowing the");
System.out.println("other player to win. Computer is going to flip a coin to choose the first player");
System.out.println("***********************************************************************************");
System.out.println("lets start the fun");
}
//flips a coin and decides who starts the game
public static String flipCoin(Random rand)
{
int coin = rand.nextInt(2);
String comp = "";
switch (coin)
{
case 0: comp = "heads";
break;
case 1: comp = "tails";
break;
}
return comp;
}
public static int rollDice(Random rand)
{
int dice1 = rand.nextInt(6)+1;
int dice2 = rand.nextInt(6)+1;
System.out.println("Dice 1: " +dice1);
System.out.println("Dice 2: " +dice2);
return dice1+dice2;
}
// select a random name of the computer via arrays
public static String nameComputer(Random rand)
{
int name = rand.nextInt(10);
String compName = "";
switch (name)
{
case 0: compName = "Lisa";
break;
case 1: compName = "Kathy";
break;
case 2: compName = "Hali";
break;
case 3: compName = "Jack";
break;
case 4: compName = "Alex";
break;
case 5: compName = "Max";
break;
case 6: compName = "Jill";
break;
case 7: compName = "James";
break;
case 8: compName = "Martha";
break;
case 9: compName = "Lauren";
break;
}
return compName;
}
public static void play(Random rand, Scanner input)
{
int playerScores = 0;
int playerTotal = 0;
int computerScores = 0;
int computerTotal = 0;
boolean gameOver = false
boolean turnOver = false
description();
String compName = nameComputer(rand);
System.out.println("Hi my name is " + compName);
System.out.print("What is your name? ");
String name = input.nextLine();
System.out.println("Hi " + name + ", I am flipping the coin to determine who goes first");
System.out.print("press any key to start the game. ");
input.nextLine();
String flip = flipCoin(rand);
int turn;
if (flip.equals("heads"))
{
turn = 1;
System.out.println("You are going to start the game");
}
else
{
turn = 0;
System.out.println(compName + " is going to start the game");
}
}
}
Create :
A playTurn(int turn) function (1 for the player, 0 for the computer) that handle a play turn (roll dice, calculate point etc.)
A boolean function that check wether there is a winner or not. Example : isWinner(int player) (again, 1 for the player, 0 for the computer)
Use the function a first time in your if() else statment like that :
if (flip.equals("heads"))
{
turn = 1;
System.out.println("You are going to start the game");
playTurn(turn);
}
else
{
turn = 0;
System.out.println(compName + " is going to start the game");
playTurn(turn);
}
Then you can add :
do {
if(turn == 1){
turn = 0;
playTurn(turn);
}else{
turn == 1;
playTurn(turn);
}
while ( !isWinner(1)|| !isWinner(0) );
This is not very well designed, but it should hopefully give you a hint on what to do next.
I'm trying to write a small game to help with my Java skills. I have a class called "Zombie" and "Player" and I created instances of these classes as so:
Zombie zombie = new Zombie(50, "Infected Zombie", "Slash");
Player defaultPlayer = new Player(100, "Default Player");
Next I requested user input for the attack style of the player:
System.out.println("Which attack style would you like to use?");
defaultPlayer.printAttackStyles();
int option = scanner.nextInt();
scanner.nextLine();
switch(option) {
case 0:
System.out.println("You backed out of the fight.");
break;
case 1:
System.out.println("Punching...");
defaultPlayer.attack(1);
break;
case 2:
System.out.println("Kicking...");
defaultPlayer.attack(2);
break;
case 3:
System.out.println("Headbutting...");
defaultPlayer.attack(3);
break;
case 4:
System.out.println("Tackling...");
defaultPlayer.attack(4);
break;
default:
System.out.println("Not a valid attack style");
}
In my "Player" class I have a method called attack which inflicts a certain amount of damage based on attack style:
public int attack(int attackStyle) {
int damage = 0;
switch(attackStyle) {
case 0:
damage = 0;
break;
case 1:
damage = random.nextInt(20) + 1;
zombie.removeHealth(damage);
break;
case 2:
damage = random.nextInt(25) + 1;
zombie.removeHealth(damage);
break;
case 3:
damage = random.nextInt(30) + 1;
zombie.removeHealth(damage);
this.health -= random.nextInt(5) + 1;
break;
case 4:
damage = random.nextInt(45) + 1;
zombie.removeHealth(damage);
this.health -= random.nextInt(10) + 1;
break;
}
return damage;
}
In each case of the attack method, I have a line of code that says
zombie.removeHealth(damage);
Since the instance is only declared in the Main class how can I access that instance in order to access the method removeHealth() in the zombie class? Sorry if this question is simple but I can't figure this out.
In your method attack you need to add 1 more argument which can be used to pass your instance of Zombie class to attack method.
Make your method signature as
public int attack( int attackStyle, Zombie zombie )
Now in switch block when you call defaultPlayer.attack pass the int value as you was passing earlier and instance of your Zombie class like this
defaultPlayer.attack ( your int value, zombie)
This will pass the zombie instance to attack method then you can the same zombie instance there to call your removeHealth(damage) method.
Hope this solve your query.
pass the reference of Zombie in attack method? like this: defaultPlayer.attack(3, zombie ); Now inside attack method, you can use the reference of zombie and invoke methods on it.
Hello my program fails to run with ArrayIndexOutofBoundsExeption. I get this error when I run it:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -35
at RoulleteChecker.main(RoulleteChecker.java:134)
Here is my code:
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
public static void main( String args[] )
{
int a[] = new int[37];
for ( long roll = 1; roll <=99999999; roll++ ) {
a[0] = 1 + ( int ) ( Math.random() * 34);
switch ( a[0] ) {
case 0:
++a[1];
break;
case 1:
++a[2];
break;
case 2:
++a[3];
break;
case 3:
++a[4];
break;
case 4:
++a[5];
break;
case 5:
++a[6];
break;
case 6:
++a[7];
break;
case 7:
++a[8];
break;
case 8:
++a[9];
break;
case 9:
++a[10];
break;
case 10:
++a[11];
break;
case 11:
++a[12];
break;
case 12:
++a[13];
break;
case 13:
++a[14];
break;
case 14:
++a[15];
break;
case 15:
++a[16];
break;
case 16:
++a[17];
break;
case 17:
++a[18];
break;
case 18:
++a[19];
break;
case 19:
++a[20];
break;
case 20:
++a[21];
break;
case 21:
++a[22];
break;
case 22:
++a[23];
break;
case 23:
++a[24];
break;
case 24:
++a[25];
break;
case 25:
++a[26];
break;
case 26:
++a[27];
break;
case 27:
++a[28];
break;
case 28:
++a[29];
break;
case 29:
++a[30];
break;
case 30:
++a[31];
break;
case 31:
++a[32];
break;
case 32:
++a[33];
break;
case 33:
++a[34];
break;
case 34:
++a[35];
break;
}
}
JTextArea outputArea = new JTextArea();
outputArea.setText( "Lets see: " + a[0-35] );
JOptionPane.showMessageDialog( null, outputArea,
"Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE );
System.exit( 1 );
}
}
Please my head is going to blow with this. I think that my error is on the a variable.
The error is from this line:
outputArea.setText( "Lets see: " + a[0-35] );
The - sign is the arithmetic minus operator. So, 0 - 35 is -35, which is, of course, not a valid index. I'm guessing you wanted to print the range of 0 to 35, which could be done with Arrays.toString:
outputArea.setText( "Lets see: " + Arrays.toString(a));
First, all that gigantic switch could be replaced by this:
++a[a[0] + 1];
Then, as other people already pointed out, a[0 - 35] do not means what you want, it will not magically grab the positions 0 to 35 of the array. It is just the math result of 0 subtracted to 35, which is -35. There is no position -35 on an array.
To represent the array as a String, we can use Java 8 Streams:
IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n")
What this does:
This will convert the int[] to a IntStream (the IntStream.of(a) part).
Lets limit to get only the first 36 elements (since you wanted the elements from 0 to 35). This is what the .limit(36) does.
Then the IntStream will be converted to a Stream<Integer> (the .boxed()) part.
Then it will be converted to a List<Integer> (the .collect(Collectors.toList())) part.
Then it will be converted to a String (the .toString() part).
Since that String will be too long to be presented on a single line, it is a good idea to add some line breaks, this is what the .replace(", ", "\n") does.
Finally, you don't need the System.exit(1);, it has no purpose here.
With that, this is your resulting code:
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
public static void main(String args[]) {
int a[] = new int[37];
for (long roll = 1; roll <= 99999999; roll++) {
a[0] = 1 + (int) (Math.random() * 34);
++a[a[0] + 1];
}
JTextArea outputArea = new JTextArea();
outputArea.setText("Lets see: " + IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n"));
JOptionPane.showMessageDialog(null, outputArea,
"Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE);
}
}
New improved answer:
To show line numbers, I think that the Streams approach will not work or it would be overly complex. So lets use an specialized method instead:
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
private static final int TIMES = 99999999;
public static void main(String args[]) {
int a[] = new int[36];
for (long roll = 1; roll <= TIMES; roll++) {
int r = (int) (Math.random() * a.length);
++a[r];
}
JTextArea outputArea = new JTextArea();
outputArea.setText("Lets see:\n" + asString(a));
JOptionPane.showMessageDialog(null, outputArea,
"Searching for the frequency: " + TIMES + " times", JOptionPane.INFORMATION_MESSAGE);
}
private static String asString(int[] s) {
StringBuilder sb = new StringBuilder(8 * s.length);
for (int i = 0; i < s.length; i++) {
sb.append(i + 1).append(": ").append(s[i]).append("\n");
}
return sb.toString();
}
}
There is a few more differences here:
Since the 0th position of the array is just to temporarily hold the newly generated number, lets get it out of the array entirely. This is what the r variable is. And since I removed the 0th position of the array, so I removed the + 1 on the ++a[a[0] + 1] which became simply ++a[r].
I moved the number of times (99999999) to a constant. This makes it easier to make it changeable if needed.
Again, since I removed the 0th position of the array, I also removed the 1 + from the line that calculated a random number. Further, I made it grab the size of the array dynamically, so you don't need to track the array size both when creating it and when randomly accessing one of its positions.
The asString method should be pretty easy straightforward. The only gotcha is the i + 1, where the + 1 has the purpose to show the indexes starting at 1 instead of 0.
The parameter on the StringBuilder's constructor in the asString method is just a total String size estimative for performance, it is not an important thing.
This is Java:
a[0-35]
actually means:
a[-35]
What makes you think -35 is a valid index? You see --- all the information that you need to fix the bug is there - you just have to read the exception message carefully. It tells you the position of the error, and it tells you the invalid index!
And btw: consider your switch statement.
Do you really think you need to write down a switch that more or less does
case i:
i++;
?