How do I loop my dice game program 3 times? - java

I'm trying to create a game that rolls 2 set of dice, three times in a row. It has the user guess a number between 2-12 just once. If that one guess matches any of the three rolls he/she wins, otherwise he/she loses. I have another class to display results and I have a counter for how many loops it's been through. It comes out 0 if the user correctly guessed it, otherwise it comes out as 1. I'm guessing the loop just loops once so if anyone can point out what I'm doing wrong to make it so it loops three times(and stopping if the user gets the answer right).
import javax.swing.JOptionPane;
/**
* #author Marcus
*
*/
public class Dice {
int randomDieNum1;//random number generator for dice
int randomDieNum2;//random number generator for dice
private final int MINVALUE1 = 1, //minimum die value
MAXVALUE1 = 6;//maximum die value
private final int MINVALUE2 = 1, //minimum die value
MAXVALUE2 = 6;//maximum die value
int userNum = Integer.parseInt(JOptionPane.showInputDialog(null, "Guess a number between 1-12", "Guess a Number",
JOptionPane.INFORMATION_MESSAGE));//gets user input
String result ; //results
int start = 0 ; //counter to see how many turns were taken
public Dice()
{
for (int i = 1 ; i <= 3; i++)
randomDieNum1 = ((int)(Math.random()* 100) % MAXVALUE1 + MINVALUE1);
randomDieNum2 = ((int)(Math.random()* 100) % MAXVALUE2 + MINVALUE2);
int total = randomDieNum1 + randomDieNum2;
if (randomDieNum1 + randomDieNum2 != userNum)
{
result = "You did not guess the \n number correctly";
++ start;
}
else if (randomDieNum1 + randomDieNum2 == userNum)
{
result = randomDieNum1 + "+" + randomDieNum2 + "=" + total + "\n" +
"You guessed the number correctly";
}
else
{
result = "You Did not guess the number correctly";
}
}
public String get() //used in another class to display count
{
String temp;
temp = "" + start;
return temp;
}
}
EDIT
Thanks guys. I added both suggestions and added a break to stop the loop after the user gets the answer right.
This is what it looks like:
public Dice()
{
for (int i = 1 ; i <= 3; i++)
{randomDieNum1 = ((int)(Math.random()* 100) % MAXVALUE1 + MINVALUE1);
randomDieNum2 = ((int)(Math.random()* 100) % MAXVALUE2 + MINVALUE2);
int total = randomDieNum1 + randomDieNum2;
if (randomDieNum1 + randomDieNum2 == userNum)
{result = randomDieNum1 + "+" + randomDieNum2 + "=" + total + "\n" +
"You guessed the number correctly";
++ turns; //
break; //stops the loop if condition is meet
}
else if(randomDieNum1 + randomDieNum2 != userNum)
{
result = "You did not guess the \n number correctly\n\n";
++ turns;
}
}
}

Apart from the missing { in for (int i = 1 ; i <= 3; i++) {
You might have to reconsider the logic used in the if condition
if(x+y != c)
{// do operation A}
else if (x+y == c)
{// do operation B}
the else condition after the else-if will never get executed.

This isn't encapsulating everything in the loop
for (int i = 1 ; i <= 3; i++)
You're missing the brackets for encapsulating
for (int i = 1 ; i <= 3; i++) {
}

Related

How to repeat an array together with a counter

What I’m trying to do with the following code is to print numbers and to replace the number with a word for the number that are divisible for 3, for 5 and for both 3 and 5.
So, when the user starts the code, it has to choose how many players are going to play.
The problem is that my code print all the numbers from 1 to 100 four times, one time for every player.
Can someone kindly explain me where is the mistake? Thanks!
Here are two solutions to that problem.
Option 1
In your case, there is no player object needed. So you could make use of a counter. That one will start by 1 and be incremented until it equals the selected number of players. Then you have to reset it to 1 again.
int player = 1;
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("player " + player + " says: divisible for 3 and 5");
} else if (i % 3 == 0) {
System.out.println("player " + player + " says: divisible for 3");
} else if (i % 5 == 0) {
System.out.println("player " + player + " says: divisible for 5");
} else {
System.out.println("player " + player + " says: " + i);
}
if (player < playersNumber) {
player++;
} else {
player = 1;
}
}
Option 2
If you really need a player object, I will advise you to make use of a queue. Also therefore you do not need an extra for-loop.
final Queue<Integer> allPlayers = new LinkedList<>();
for (int i = 1; i <= playersNumber; i++) {
allPlayers.add(i);
}
for (int i = 1; i <= 100; i++) {
final int player = allPlayers.poll();
allPlayers.add(player);
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("player " + player + " says: divisible for 3 and 5");
} else if (i % 3 == 0) {
System.out.println("player " + player + " says: divisible for 3");
} else if (i % 5 == 0) {
System.out.println("player " + player + " says: divisible for 5");
} else {
System.out.println("player " + player + " says: " + i);
}
}
Both solutions are not perfect, but there are working ones.
If something is unclear with these solutions do not hesitate to ask me.
I can post here a working example, but that will have no learning effect for you. So please answer my question.
What was your intention to use this:
for(int p = 0; p <= 100; p++){
for(int i = 1; i <= 100; i++){
}
}
Why do you think, you need two for-loop with each 100 iterations?
Keep it simple and don't overcomplicate things without a need. You alredy seem to be familiar with the modulo operator. Just use that to get the current player:
public static void main(String args[]) {
int playersNumber;
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter the number of players (min 2, max 6)");
playersNumber = scanner.nextInt();
//add so many players as user interd number
ArrayList<String> players = new ArrayList<>();
for (int i = 1; i <= playersNumber; i++) {
players.add("Player " + i);
}
// use modulo operator to get the current player.
// Note: list indexes are zero based, but your player number start with one,
// so you need to substract one from i
for(int i = 1; i <= 100; i++){
if(i % 3 == 0 && i % 5 == 0){
System.out.println(players.get((i-1) % playersNumber) + " says: divisible for 3 and 5");
} else if (i % 3 == 0) {
System.out.println(players.get((i-1) % playersNumber) + " says: divisible for 3");
} else if (i % 5 == 0) {
System.out.println(players.get((i-1) % playersNumber) + " says: divisible for 5");
} else {
System.out.println(players.get((i-1) % playersNumber) + " says: " + i);
}
}
}

Making sure the logic of my code is sound. This code will eventually lead into a java representation of yahtzee

I'm making a class for the Straight category of Yahtzee. Yahtzee has 2 options for a straight, small or larger. A small straight would be a sequence of 4 consecutive die faces such as 1, 2, 3, 4. A larger straight would be a sequence of 5 consecutive die faces. If a player get a small straight they receive 30 points and if they get a larger that is 40 points.
My Straight class inherits from a class called Scores and only uses one method called getDiceScore. The getDiceScore will accept an argument of type DieInterface. I will attach the DieInterface interface code below.
I just want to make sure the logic of my code is sound for this project I am working on.
public interface DieInterface
{
public static String[] dieFaces =
{"+---+\n| |\n| o |\n| |\n+---+",
"+---+\n|o |\n| |\n| o|\n+---+",
"+---+\n|o |\n| o |\n| o|\n+---+",
"+---+\n|o o|\n| |\n|o o|\n+---+",
"+---+\n|o o|\n| o |\n|o o|\n+---+",
"+---+\n|o o|\n|o o|\n|o o|\n+---+"};
public static String toDieString(DieInterface aDie)
{
return dieFaces[aDie.getFaceValue()-1];
}
// Do not modify above this line
public static String toDiceString(DieInterface[] dice)
{
StringBuilder result = new StringBuilder();
String sideBySide = "";
String die1 = dieFaces[dice[0].getFaceValue()-1];
String die2 = dieFaces[dice[1].getFaceValue()-1];
String die3 = dieFaces[dice[2].getFaceValue()-1];
String die4 = dieFaces[dice[3].getFaceValue()-1];
String die5 = dieFaces[dice[4].getFaceValue()-1];
//String die6 = dieFaces[dice[5].getFaceValue()-1];
String splitter = die1 + "\n" + die2 + "\n" + die3 + "\n"+ die4 + "\n"+ die4+ "\n"+ die5;
String [] temp = splitter.split("\n");
for(int i = 0; i < (temp.length/6); i++)
{
result.append(temp[0*(5)+i] + " " + temp[1*(5)+i] + " " + temp[2*(5)+i] +" " + temp[3*(5)+i] +" "+ temp[4*(5)+i] +"\n");
}
return result.toString();
}
// Do not modify below this line
public int roll();
public int getFaceValue();
}
public class Straight extends Scores
{
protected String name;
protected int numConsecutiveFaces; // indicates how many consecutive faces that a player should have to satisfy this scoring category
public Straight(String aName, int numConsecutiveFaces)
{
super(aName);
this.numConsecutiveFaces = numConsecutiveFaces;
}
public int getDiceScore(DieInterface[] dice)
{
boolean ones = false;//determines that only one side of a die appeared once
int[] straight = new int[numConsecutiveFaces]; // array used to store numbers in the correct straight format
int [] counter = {0, 0, 0, 0, 0 ,0}; //using to track how many times a die appeared
//looping through dice array to determine how many times a die appeared
for(int i = 0; i < dice.length; i++)
{
counter[dice[i].getFaceValue()-1]++;
}
//sorting the die in sequential order
sort(counter);
//determining that a die only appeared once and they are no larger than by one value. ex 1, 2, 3, 4, 5 not 2, 3, 5, 6
for(int i = 0; i < counter.length; i++)
{
if(counter[i] == 1 && byAFactorOfOne(counter, counter) == true)
{
ones = true;
byAFactorOfOne(counter, counter);
counter[i] = straight[i];
}
}
//if 4 die in a row are in correct sequential order return 30 points back
if(straight[numConsecutiveFaces] == 4)
return 30;
//if 5 die in a row are in correct sequential order return 40 points back
else if(straight[numConsecutiveFaces] == 5)
return 40;
else
return 0;
}
private void sort(int[] counter)
{
for (int i = 0; i <counter.length; i++)
{
for (int j = 0; j < counter.length - i - 1; j++)
{
if (counter[j] > counter[j + 1])
{
int temp = counter[j];
counter[j] = counter[j + 1];
counter[j + 1] = temp;
}
}
}
}
private boolean byAFactorOfOne(int[] counter, int[] counter2)
{
int value;
int counting = 0;
boolean repeat = true;
int i = 0;
while(repeat && counting < counter.length)
{
value = counter[i] - counter[i + 1];
i++;
if(value != 1)
{
repeat = false;
return false;
}
counting ++;
}
return true;
}
}
First of all, the following code won't work:
if(straight[numConsecutiveFaces] == 4)
... because you aren't setting any values into the straight array.
You are counting the number of times each die value is displayed:
//looping through dice array to determine how many times a die appeared
for(int i = 0; i < dice.length; i++)
{
counter[dice[i].getFaceValue()-1]++;
}
... and the index of the array is the value on the die. This makes sense.
But as soon as you sort these values, you lose which die value each count represents. Don't do this:
//sorting the die in sequential order
sort(counter);
If you did that, you no longer know which die value was displayed n times.
Instead of sorting counter, what you need to do is look for 4 or 5 consecutive entries that are not 0. In other words, 4 or 5 consecutive entries that had at least one die showing that value.
You can take some shortcuts:
If counter[3] or counter[4] is zero, it's not possible for either a 4-length or 5-length straight
If counter[2] and counter[5] are both 0, it's not possible for a 5-length straight
If there are any counter values > 1, then it's not possible for a 5-length straight to have occurred
And if there are more than 1 counter values > 1, then it's not possible for a 4-length straight to have occurred.
A simpler way to solve this problem that doesn't involve counting values or sorting (uses binary values to represent the presence of a die value):
public class Straight extends Scores
{
static final int valueForOneToFour = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3);
static final int valueForTwoToFive = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
static final int valueForThreeToSix = Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);
static final int valueForOneToFive = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
static final int valueForTwoToSix = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);
...
public int getDiceScore(DieInterface[] dice)
{
// calculate a binary representation of the values available
int occurrenceValue = 0;
for (int i = 0; i < 6; i++) {
occurrenceValue |= Math.pow(2, dice[i] - 1));
}
if (occurrenceValue & valueForOneToFive == valueForOneToFive
|| occurrenceValue & valueForTwoToSix == valueForTwoToSix) {
return 40;
}
if (occurrenceValue & valueForOneToFour == valueForOneToFour
|| occurrenceValue & valueForTwoToFive == valueForTwoToFive
|| occurrenceValue & valueForThreeToSix == valueForThreeToSix) {
return 30;
}
return 0;
}
}

JOptionPane Looping

I have an issue. My lecturer wants me to make a loop, with an input of JOptionPane and an output of console. How can I use loop for JOptionPane and send an output through console.
Here's my code:
int even = 0;
int odd = 0;
int e_e = 0;
int o_o = 0;
String a1 = JOptionPane.showInputDialog(null, "Type in 10 integer");
for (int counter = 0; counter < 10; counter++){
int a = Integer.parseInt(a1);
if (a % 2 == 0) {
even++;
e_e += a;
} else {
odd++;
o_o += a;
}
}
System.out.println("\n\nNumber of even numbers : " + even);
System.out.println("Number of odd numbers : " + odd);
System.out.println("Total of even numbers : " + e_e);
System.out.println("Total of odd numbers : " + o_o);
I would try using a DO-WHILE loop with and an int[], example:
int size = 10;
int count = 0;
int[] yourNumbers = new int[size];
do {
yourNumbers[count] = Integer.parseInt(JOptionPane.showInputDialog(null,
"Your message here."));
count++;
} while (count < 10);
This way you can loop through and grab all the numbers. Then you can use a FOR-LOOP to cycle through and print what you need
System.out.println("Even Numbers are: ");
for(int i = 0; i < yourNumbers.length; i++) {
if (yourNumbers[i] % 2 == 0) {
System.out.println(yourNumbers[i]);
}
}
System.out.println("Odd Numbers are: ");
for(int i = 0; i < yourNumbers.length; i++) {
if (yourNumbers[i] % 2 != 0) {
System.out.println(yourNumbers[i]);
}
}
The problem with your current code is that you only ask the user one time to input a number but you actually seem to want 10 values. So you parse ten times the same value.
The solution is simple, put the dialog inside the loop (only changed the lines with comments):
int even = 0;
int odd = 0;
int e_e = 0;
int o_o = 0;
// No return type, just a message
JOptionPane.showMessageDialog(null, "Type in 10 integer");
for (int counter = 0; counter < 10; counter++) {
// Dialog inside the loop, asking to
// input a number in every iteration
String value = JOptionPane.showInputDialog(null, "Type in "
+ (counter + 1) + ". value");
int a = Integer.parseInt(value);
if (a % 2 == 0) {
even++;
e_e += a;
} else {
odd++;
o_o += a;
}
}
System.out.println("\n\nNumber of even numbers : " + even);
System.out.println("Number of odd numbers : " + odd);
System.out.println("Total of even numbers : " + e_e);
System.out.println("Total of odd numbers : " + o_o);

Breaks in printing long contents JAVA

I have written a small program that takes user input, n (int), and calculates every prime number up to n, using a loop in a loop. If the user inputs forexample 85023, it will be a very long series of numbers. How do i make the output break every 10th number? this would make the output alot more proffesional and neat to look at.
Relevant code:
for (i = 1; i <= n; i++)
{
int counter=0;
for(num =i; num>=1; num--)
{
if(i%num==0)
{
counter = counter + 1;
}
}
if (counter ==2)
{
// Append prime numbers to string
primeNumbers = primeNumbers + i + " ";
}
}
// Print Number
System.out.println("Primtallene fra 1 til " + n + " er: ");
System.out.println(primeNumbers);
}
You could have a separate counter which counts the number of prime numbers you have currently found, like this:
int primeCount = 0;
for (i = 1; i <= n; i++)
{
int counter=0;
for(num =i; num>=1; num--)
{
if(i%num==0)
{
counter = counter + 1;
}
}
if (counter ==2)
{
// Append prime numbers to string
primeNumbers = primeNumbers + i + " ";
// Increment prime counter
primeCount++;
// If 10 primes have been printed then add new line and reset counter
if ((primeCount % 10) == 0) {
primeNumbers += "\n";
}
}
}
// Print Number
System.out.println("Primtallene fra 1 til " + n + " er: ");
System.out.println(primeNumbers);
}
\n is the newline character, hope this helps.

java simulator simple horse race game using only arrays and loops

I'm trying to make a simple java simulator horse race game using only arrays and loops. My program was nearly finished. My only problem is that when you enter the number of horses who will join in the contest, that particular number you enter will win even if other horses are finished. Example, when you type 5 horses that will join in the contest, that "5" number will win even if the other number finished first. i can't really determine the winner. My program seems to work well. Any advice would be appreciated. Thank You!
Here's my code:
public static void main(String[] args) throws InterruptedException {
Scanner input = new Scanner(System.in);
int[] tracks = new int[70];
int bet;
System.out.println("==============");
System.out.println("||HORSE RACE||");
System.out.println("==============");
System.out.println("WHO'S GONNA WIN IN THIS EPIC RACE?");
System.out.println("ENTER HOW MANY HORSES WOULD YOU LIKE TO JOIN:"
+ "\n 2-10 HORSES are allowed to join!");
int horses;
do {
horses = input.nextInt();
} while (horses < 2 || horses > 10);
int[] move = new int[horses];
double[] betHorse = new double[horses];
System.out.println("Enter how many person will bet?");
int number = input.nextInt();
for (int i = 1; i <= number; i++) {
do {
for (int j = 1; j <= horses; j++) {
System.out.println("[" + j + "]" + " for HORSE " + j);
}
System.out.println("Person no." + i + ": Enter the number of horse:");
bet = input.nextInt();
} while (bet < 1 || bet > horses);
for (int p = 1; p <= horses; p++) {
if (bet == p) {
System.out.println("Enter the amount of your bet?");
betHorse[bet - 1] += input.nextDouble();
}
}
for (int j = 1; j <= horses; j++) {
System.out.println("Bet for HORSE " + j + ":P" + betHorse[j - 1]);
}
}
System.out.println("OKAY THAT'S SETTLED");
System.out.println("Race begins in:");
int num3 = 3;
for (int i = 1; i <= num3; num3--) {
System.out.println(num3);
Thread.sleep(1000);
}
do {
Thread.sleep(100);
int[] numbers = new int[horses];
for (int i = 0; i < horses; i++) {
numbers[i] = 1 + (int) (Math.random() * 6);
}
for (int i = 0; i < horses; i++) {
if (numbers[i] >= 1 && numbers[i] <= 3) {
move[i]++;
} else if (numbers[i] == 4 && numbers[i] == 5) {
move[i] = move[i] + 3;
} else if (numbers[i] == 6) {
move[i] = move[i] + 5;
}
}
System.out.println("\n\n\n");
for (int i = 1; i <= horses; i++){
System.out.println("Horse " + i +" position:" + move[i-1]);
}
for (int i = 1; i <= horses; i++) {
for (int j = 0; j < move[i - 1]; j++) {
System.out.print("--");
}
System.out.println(i + "H" + move[i - 1]);
}
} while (move[horses-1] < tracks.length );
for (int i = 1; i <= horses; i++) {
if (move[i - 1] > tracks.length) {
System.out.println("HORSE " + i + " finished the track! One who bets for HORSE " + i + " won P" + betHorse[i - 1] * 2);
}
}
}
}
The condition in your while loop :
while (move[horses-1] < tracks.length)
means that the loop will end once the last horse (whose index is horses-1) finishes. You should change the condition to end the loop when any horse finishes.
Whenever you update move[i], you should test if move[i]>=tracks.length, and if it is, set some boolean variable to true - ended = true;.
Then change the loop's condition to while (!ended) .
There are several problems with your simulation.
As #Eran said, you most serious problem is the termination condition. The loop stops when the horse in the horses - 1 position finishes, even if other horses were actually winning.
You may wonder why it was always winning, though. After all, your printing loop at the end should have seen another horse if the horses - 1 one finished but the other one finished first. This is probably because you actually gave all the horses very little chance to advance.
The horses have a 50% chance of advancing one step (numbers[i] is between 1 and 3). Then they have a 33% of not advancing at all ( numbers[i] is 4 or 5, but you asked for numbers[i] == 4 && numbers[i] == 5, and it can't be both at the same time so this if is never entered). They have a 16% chance of advancing 5 steps. So most of the time, the other horses are advancing as much or less than the horses - 1 horse. If you change that condition to || instead of &&, there are higher chances that you'll see another winning horse even if you don't correct your while condition (but you should correct it, of course).
That loop at the end is really not necessary. When you keep your ended boolean, you can also keep an int winner and set it to the i of the horse that finished. Then you don't have to loop, just give the results for that particular winner.
Your tracks variable is set to be an array, but you are not actually using it. You are only using the moves array for the horses. So you should really just keep a simple int that says what the length of the track is, because that's the only thing that's interesting you - have the horses made enough moves to cover the whole length of the track?
You also don't need the numbers array. You can loop on the horses, and roll a single number for the current horse, and make your decision based on that number.
for (int i = 0; i < horses; i++) {
int die = 1 + (int)(Math.random()*6);
if (die >= 1 && die <= 3) {
move[i]++;
} else if (die == 4 || die == 5) { // Note the || condition
move[i] = move[i] + 3;
} else { // Note that 6 is the only possibility remaining
move[i] = move[i] + 5;
}
}
The most important things are the loop condition and the ||, of course.

Categories