How do you do re-rolls in a yahtzee program in java? - java

I've been working at an assignment for my intro to Java class, and I can't figure out how to accomplish the two things I need to do.
What I have now: I have created an array that rolls five dice, and displays the results. The code I have is as follows...
package operation.pkg7;
import java.util.Random;
import java.util.Scanner;
public class Operation7 {
public static void main(String[] args)
{
int[] dice = new int[5];
Random r = new Random();
//This makes the dice
for (int i = 0; i < 5; i++) {
dice[i] = r.nextInt(6) + 1;
}
//This displays the dice rolls
for (int i = 0; i < 5; i++) {
System.out.print("Roll " + (i+1) + ":" );
System.out.print(" " + dice[i] + " ");
}
System.out.println();
//..........................................
int[] counts = new int[6];
for (int i = 0; i < 6; i++){
counts[i] = 0;
}
//count up the values
for (int i = 0; i < 5; i++) {
int diceIndex = dice[i] - 1;
counts[diceIndex]++;
}
System.out.println();
for (int i = 0; i < 6; i++){
System.out.println("The number of " + (i+1) + "s is : " +
counts[i]);
}
}
}
Now, I successfully gives me the results of the die rolls, but I'm having problems figuring out how to do re-rolls. This is an example of what I'm wanting the program to ask for after displaying the initial die roll...
Roll 1: 2 Roll 2: 6 Roll 3: 1 Roll 4: 4 Roll 5: 2
Would you like to re-roll any dice? y/n
y
Which dice would you like to re-roll? 1-5
2, 3, 4
Roll 1: 2 Roll 2: 3 Roll 3: 2 Roll 4: 3 Roll 5: 2
Would you like to re-roll any dice? y/n
n
Roll 1: 2 Roll 2: 3 Roll 3: 2 Roll 4: 3 Roll 5: 2
That's the goal. Once I do that, I need to make the program display the best possible score... For example, if there are two threes and three twos, it needs to say it's a full house, or display yahtzee if there are five of the same number etc.
Anyone have any advice?

Put your code in a do-while loop with the condition of the user's input placed before the do-while loops condition check.

You have the results of your rolls store in the dice array you simply need to create new random results for the dice in those positions. E.g. if you re-roll #2 then put a new random in index 1.
As for determining the various types of rolls such as full house you will want to define generic logic for each. You might for example define a method like:
public static boolean isFullHouse(int[] diceRoll){
//return true if the roll is a full house, false otherwise
}
However, I think what you really want is not just to determine if a roll is a full house but to also calculate the total score using the scoring rules for that scenario.
EDIT #1:
Before going any further please, at a minimum, read the section on this page titled "Asking about homework".
I will try to illustrate how I think you could accomplish a re-roll without providing full code at this point. As I stated above, since you need to prompt the user for which dice they intend to re-roll you can process that input and use it as indicies into your dice array. So if the users 2,3,4 as in your example you use Scanner.getLine() to read that input and then use String methods to break it apart. Once you have the individual pieces you can convert them to int values using the Integer class. Finally, subtract 1 from them to adjust for the fact that your dice array indicies begin at 0.
Now you have an array containing indicies into your dice array. Each item in this new array is just used to refer to an index of the dice array. So let's call this second array userInput. Continuing the 2,3,4 example userInput[0]=1, userInput[1]=2, userInput[2]=3.
All you need to do is loop through userInput and each time through the loop generate a new random number. This random number is then stored in the dice array at the index stored in the current position of your userInput array.
As for determining the best possible score you could, as I suggested, write individual methods for each to determine if they are present and then another method to invoke each of them and report the greatest score possible.
Let's take one of them as an example like 3 of a Kind. Perhaps the simplest way to think about it would be to loop through all the possible rolls of the die (0 to 6) so that each time through the loop you're counting how many of each roll appear in the current dice roll. So in loop 1 you're looking for three 1's and in loop 2 you're looking for three 2's and so on.
Inside of this loop you create another loop to iterate through all of the dice in the current dice roll (your dice array) and each time through the loop you check to see if the current die is the number you're currently looking for from your outer loop. If it is the number from the outer loop then you increment a counter (which is defined and initialized in the outer loop but outside the inner loop so that it resets each time the outer loop increments) to represent how many of that number you have found so far.
If the counter reaches 3 before the inner loop ends you know you have 3 of a Kind, so have the method return true since you have no reason to continue (can't possibly have 2 different 3 of a Kind). Otherwise your method should return false to indicate there was no match.
Note that if you want to be ambitious you could exercise good programming practice and reuse code by making the limit of your counter a parameter to your method so that you can use the same logic for both 3 of a Kind and 4 of a Kind.
Hint there is a more clever way of doing this but I thought this approach would be more consistent with the constructs you already know.
I hope this helps to get you started!

Related

After generating an array, how to filter out specific numbers I need?

I have an assignment that I can´t solve for a couple of days. I am very frustrated and feel too dumb for java. The Problem is the extract of the code below (my Professor wrote it). My task is to complete the code. So that when I write in my terminal for example "java Yahtzee 1 1 1 2 3" I should receive "sum of ones: 3".
Why did I stick to this problem? - because I don´t really understand these brackets [i] and how to deal with them.
import java.util.Arrays;
public class Yahtzee {
/**
* ones
* #param dice rolled numbers, sorted in ascending order
* #return the sum of the numbers on all dice showing a 1
*/
private static int aces(int[] dice) {
return -1;
}
public static void main(String[] args) {
// it is allowed to change the main method
if(args.length != 5) {
// the array length should be 5
System.out.println("ERROR: nicht genau 5 Zahlen übergeben");
return;
}
// read the passed numbers
int[] dice = new int[args.length];
for(int i = 0; i < args.length; i++) {
dice[i] = Integer.parseInt(args[i]);
if(dice[i] < 1 || dice[i] > 6) {
System.out.println("Error: invalid number " + dice[i]);
return;
}
}
System.out.println("sum of ones: " + aces(dice));
}
}
I think I should filter out the three ones. My first thought is to make an if-statement in main-method that could look like this: if(dice[i] == 1) and find only those ones. But I dont have idea how to work further. Can some one explain how to solve this problem or give an idea?
I started first programming 1 month ago and learned already some about loops and booleans and arrays. I red other questions like mine, but I do not understand what they do (I only worked with integers and doubles). I think I should work with loops or something like that.
To begin with, it's helpful to know how Yahtzee is played and this link. As you can see in the links, the game of Yahtzee is played with five dice which a player rolls. The value of each dice is held within a int[] Array as an integer element value:
Knowing this and once the dice array is filled, you can iterate through the dice[] Array and sum whatever you like within the aces() method. Obviously, because the method is named aces, it would be any dice[] element that has a value of 1 that is summed, for example:
private static int aces(int[] dice) {
int sum = 0;
/* Read each element of the supplied dice[] Array...
We start `i` at 0 because the first element in any
array is at index 0 (not 1) and we will iterate
through until we reach the array length which is
a literal value. There is no index 5 which is why
it will keep looping for as long as `i` is less
than (<) dice.length. */
for (int i = 0; i < dice.length; i++) {
// Does the current array element contain a value of 1?
if (dice[i] == 1) {
//Yes ... then sum it
sum += dice[i]; // Same as: sum = sum + {value in dice[i] (which is 1)}
}
// No...continue looping.
}
/*
// Can also be done this way with an Enhanced `for` loop:
for (int v : dice) {
if (v == 1) { sum += v; }
}
*/
return sum; // Return the sum of 1's.
}
If you apply the above exampled dice roll to the command-line then the console window should display something like:
Sum of ones: 3
On a side:
When creating your dice[] Array from the command-line arguments (varArgs) you should validate the fact that valid values have been supplied before you add them into the Array. It may not be a big problem in this use-case because the application halts when an invalid value is detected but in the future, this may not always be the situation in another application you develop. Checking for non-numerical (integer) values would be a good idea as well. You application will crash if a letter was supplied in the command-line instead of a integer number. You cover the upper and lower inclusive numerical boundaries but nothing if there is a non-numerical value. This can be solved with a little change to your code:
int[] dice = new int[args.length];
for(int i = 0; i < args.length; i++) {
// If the command-line argument is anything other than 1 to 6...
if(!args[i].matches("[1-6]")) {
System.out.println("Error: Invalid value (" + dice[i]
+ ") in Command-Line arguments!");
return;
}
dice[i] = Integer.parseInt(args[i]);
}
You will notice that the String#matches() method is used for the condition of the if statement and passed to it is a small Regular Expression (regex) of "[1-6]". What this expression does is it will see if the value passed to the current (args[i]) argument it's checking is nothing more than a string representation of a integer numerical value consisting of a inclusive value from 1 to 6. Anything else and the validation fails. You will also note that the NOT operator (!) is used at the beginning of the condition. This would be the same as saying,
"If args[i] does not contain a string representation of a integer value
inclusively between 1 and 6 then, inform the User of an Invalid Argument
and shut down the application, otherwise, add it to the `dice[]` Array."

Code chef Beginner (lead game) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
The Siruseri Sports Club organises an annual billiards game where the top two players of Siruseri play against each other. The Manager of Siruseri Sports Club decided to add his own twist. In his version, at the end of each round the leader and her current lead are calculated. Once all the rounds are over the player who had the maximum lead at the end of any round in the game is declared the winner.
The total scores of both players, the leader and the lead after each round for this game is given below:
Round Player 1 Player 2 Leader Lead
1 140 82 Player 1 58
2 229 216 Player 1 13
3 319 326 Player 2 7
4 431 432 Player 2 1
5 519 522 Player 2 3
The winner of this game is Player 1 as he had the maximum lead (58 at the end of round 1) during the game.
Your task is to help the Manager find the winner and the winning lead. You may assume That is, there are no ties.
Input
The first line of the input will contain a single integer N (N ≤ 10000) indicating the number of rounds in the game. Lines 2,3,...,N+1 describe the scores of the two players in the N rounds. Line i+1 contains two integer Si and Ti, the scores of the Player 1 and 2 respectively, in round i. You may assume that 1 ≤ Si ≤ 1000 and 1 ≤ Ti ≤ 1000.
Output
Your output must consist of a single line containing two integers W and L, where W is 1 or 2 and indicates the winner and L is the maximum lead attained by the winner.
My code:
import java.util.Scanner;
class billardsDemo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int rounds = in.nextInt();
int i = 0;
int lead = 0;
int flag = 0;
while (i < rounds) {
int score1 = in.nextInt();
int score2 = in.nextInt();
if (score1 > score2 && score1 - score2 > lead) {
flag = 1;
lead = score1 - score2;
} else if (score2 > score1 && score2 - score1 > lead) {
flag = 2;
lead = score2 - score1;
}
i++;
}
System.out.println(flag +" "+ lead);
in.close();
}
}
I am getting the right output in eclipse, but code chef says wrong answer.
One thing that immediately stands out is your println statement at the end. You're printing one integer instead of two since flag and lead get combined. The correct code should be:
System.out.println(flag + " " + lead);
In my opinion, you should try to parse the input line by line as intended, not nextInt by nextInt as this might lead to unknown complications. You should read the whole line, then tokenize it and get the first two integers.
Also, online judges are usually very finicky about class and method names so make sure you name your class how they want you to (for example on HackerRank your class must be named Solution for the code to work).
Finally, how do you handle ties in the lead? In your problem statement it says there are no ties but does this mean no ties in the round or no ties in the leads as well? What I mean is this: suppose player 1 wins the first round with a lead of 1. Then player 2 wins the second round also with a lead of 1. What should your flag be, 1 or 2?
It seems your input doesn't total the scores, but replace the last score with the new scan.
I would suggest declaring the variable score1 and score2 before the loop and change the code inside the loop to:
score1 += in.nextInt();
which is equal to
score1 = score1 + in.nextInt();
The same goes for score2, of course.
See this accepted solution on their website for a complete code:
https://www.codechef.com/viewsolution/8684978
//edit: I think you should also add a space character between the integers in the output. Otherwise the output will be "158" instead of "1 58".
Why did you solve it this way? Please explain. And is it a problem with code chef of with your programming?
My way of solving would be this:
create helper class that hold the matches, with the values:
Player1 score, Player2 score, difference in score.
make an array of said matches and iterate thou them to find the
largest value.
now you have the winning match, go and find the player who won it.
Print the winning player and the points.

I am having Problems with Arrays

I am having issues with this array code. It needs to have a number count that displays the numbers that are entered by the user. So for instance, if the user enters three four's it will say "4 3." I already have the majority of the code done, but it is just returning the first number that's entered.
import java.util.Scanner;
public class NumberCounts
{
public static void main(String args[])
{
int[] answer = new int [100];
inputArray(answer);
}
public static void inputArray(int[] Numbercounts)
{
System.out.println("This Program is written by Benjamin Barcomb\n");
Scanner kb = new Scanner(System.in);
System.out.print("How many numbers will you enter? : ");
kb.nextInt();
//int[] answer = new int[100];
int arryNum[] = new int[] {};
System.out.println("\nEnter numbers in [0, 100] range separated by a space:");
int input = kb.nextInt();
System.out.println("Number Count");
int[] counter = new int[] {input};
for (int i = 0; i < arryNum.length; i++) {
System.out.println(" " + (i + 1) + " " + counter[i]);
}
for (int i = 0; i < counter.length; i++) {
System.out.println(" " + (i + 1) + " " + counter[i]);
}
}
}
Where to start...
1) You create an array answer of length 100, pass it to your method, then never use it anywhere.
2) You ask the user to tell you how many numbers they are going to enter, you get that input with kb.nextInt(), then do nothing with it. You never assign that int to a variable.
3) You create an array arryNum and leave it empty. You never put anything into it, ever.
4) You ask the user to input numbers separated by spaces. You then take only the first int they enter.
Since it seems like you are just learning I will leave the coding to you. Hopefully if you can now see what certain parts of your code are doing you will be able to move on from there. My one tip would be to use more descriptive variable names. It makes it easier for you to read what is going on when you look at your code.
Some Solutions
1) Unless the requirements say you must pass an array into the inputArray() method, I would just remove it all together since you are doing all the other work in the method. I would remove int[] answer = new int [100]; call the method with no parameters inputArray() and change the signature of the method to just
public static void inputArray() { ... }
2) When you ask the user how many numbers they are going to enter you are basically asking them "How long should my array be?" When you get this int you should use it to make your new array. Something like
System.out.print("How many numbers will you enter? ");
int usersNumbers = new int[kb.nextInt()];
Notice I have changed the name of arrayNum to usersNumbers. It's more descriptive and makes reading your code easier.
3) Now you want to get all those numbers and put them into that array. Since you need to get multiple numbers you will need a loop. Again, unless the requirements say you have to, I would do this a bit differently. Instead of entering all the numbers on one line separated by spaces, I would ask for the numbers individually. Since we know the length of the array (how many numbers they are going to enter), we know how many times to prompt them.
System.out.println("\nEnter numbers in [0, 100] range.\n");
for (int i = 0; i < usersNums.length; i++) {
System.out.println("Enter Your Number:");
usersNums[i] = kb.nextInt();
}
4) Now onto counting the number of occurrences of each int entered. Since the user can enter their numbers in any random order it makes things tougher. Again, I'm not sure what exactly your requirements allow or not, but here is what I did. First I want to get a list of the unique numbers. For example, if the array is {2, 4, 2, 5, 2, 4} I want to get a list with {2, 4, 5}. Once I have that I can look at each of those numbers and go through the array counting how many times I see each one. An easy way to get a list of unique numbers is to put them into a Set. It is a data structure which doesn't allow duplicates. A TreeSet is a Set which puts the numbers in order, just to make it easier to read.
Set<Integer> uniqueNumbers = new TreeSet<Integer>();
for (int i : usersNums) { uniqueNumbers.add(i); }
Now that I have the list of unique numbers I can start counting. I start count at 0. Then for every number in the set, I look at every number in the array and see if they are the same. If they are, count goes up by 1. Once I get to the end of the array I print my results for that number, then reset count to 0.
int count = 0;
for (Integer i : uniqueNumbers) { //For every number in the Set
for (int j = 0; j < usersNums.length; j++) { //Look at every number in the array
if (i == usersNums[j]) { count++; } //If the same, count++
}
System.out.print(i + " - " + count + "\n"); //Print results
count = 0; //Reset Count
}
It seems you're only getting the first value because you only called nextInt() on your scanner once. You should ideally have a while loop to keep gathering user input. Also, I think you're trying to store your answers in an array, which really isn't ideal since you don't know how big your input will be. You should really use a list. Something along the lines of
List<Integer> data = new ArrayList<Integer>();
while (kb.hasNext()) {
data.add(kb.next());
}
Explain your code hope you understand how to fix it.
First, I assume you want your user to enter more than one number but you use nextInt which means
The java.util.Scanner.nextInt() method Scans the next token of
the input as an int.An invocation of this method of the form
nextInt() behaves in exactly the same way as the invocation
nextInt(radix), where radix is the default radix of this scanner.
Suggestion: try to use to while loop to read more number and quite when your user enter -999999 for example as a termination for your while loop.
Second, use Array is not right data structure to use because you do not know the size of array.
There are 2 ways to fix this issue:
1. first to ask the size of array from the user like how many numbers the user wants to input which is not what you want.
2. use another data structure that shrinks and expands by itself which is ArrayList
Third, you did not say whether you gonna have different numbers in your input like
1 1 2 3 3 4 4 5 or unsorted like `1 2 1 4 3 4 5`
or just your input includes the same numbers like
2 2 2 2 2 2 2
More info for third point is here

For loop stopping prematurely

I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
The input consists of:
first line is number of cases.
this line enters the length of a train ex: 4
this line enters the number of the wagons ex: 2 4 3 1
the next following lines correspond to the following test cases whose structure is the same as the example.
They ask you to arrange the train and tell the number of swaps made to make the train in order.

Counting instances of a value in an array

Homework. Dice Game. I've got an array that represents five rolls of a die. Consider:
diceRoll[] = {6,3,3,4,5}. I would LIKE to create a SECOND array that has the counts of values from one to six contained in diceRoll[], (e.g., occurence[] = {0,0,2,1,1,1} for the diceRoll[] above.) but I fear I'm getting lost in nested loops and can't seem to figure out which value I ~should~ be returning. occurence[] is a global variable, and the intent is that the array will contain six values...the count of ones (at index [0]), twos (at [1]), threes (at [2]), etc.
So Far:
for(i=1;i<7;i++) /* die values 1 - 6
{
for(j=0;j<diceRoll.length;j++) /* number of dice
{
if (diceRoll[j] == i) /* increment occurences when die[j] equals 1, then 2, etc.
occurence = occurence + 1;
}
}
return occurence;
}
I cannot, however, get the occurence=occurence+1 to work. bad operand types for binary operator is my most common error. I suspect I need to increment occurence OUTSIDE one or both of the for loops, but I'm lost.
Guidance? or perhaps the one-line easy way to do this?
d
The easiest way I have to do this is to create the second array in order so that
occurrence[0] = # of 1's occurrence[1] = # of 2's and so on. Then this becomes a 1 loop method.
//method to return number of occurrences of the numbers in diceRolls
int[] countOccurrences(int[] diceRolls) {
int occurrence[] = new int[6]; //to hold the counts
for(int i = 0; i < diceRolls.length; i++) { //Loop over the dice rolls array
int value = diceRolls[i]; //Get the value of the next roll
occurence[value]++; //Increment the value in the count array this is equivalent to occurrence[value] = occurrence[value] + 1;
//occurrence[diceRolls[i]]++; I broke this into two lines for explanation purposes
}
return occurrence; //return the counts
}
EDIT:
Then to get the count for any particular value use occurrence[value-1]

Categories