poker dice in java - not giving scores properly - java

I want to create a poker dice game in java, and when the player rolls the dice, I want the program to tell the results and the current score. However, something is wrong. It isn't giving me properly the score. For example, I changed the the Math Random algorithm to always give me always (1,1,1,1,1), so the result would be 50. Unfortunately,it is giving me 0. Can I have some help please? Thanks.
This is my code:
public class DiceGame {
public static int [] rollDice() {
int [] diceSide = new int[5];
Random diceRoller = new Random();
for (int i = 0; i<diceSide.length; i++) {
int roll = diceRoller.nextInt(1) + 1;
diceSide[i] = roll;
}
System.out.print(diceSide[0] + "" + diceSide[1] + "" + diceSide[2] + "" + diceSide[3] + "" + diceSide[4]);
return diceSide;
}
public static int getResult(int[] dice) {
int resValue = 0;
for (int i = 0; i < dice.length; i++) {
if (dice[i] == 5) {
resValue = 50;
} else if (dice[i] == 4) {
resValue = 40;
} else if (dice[i] == 3) {
resValue = 30;
}
}
System.out.print(resValue);
return resValue;
}
public static void main(String[] args) {
int player1=0;
int player2;
int player3;
int player4;
int player5;
player1 += getResult(rollDice());
}
}

Math.Random returns a value thats between 0 and 1.
You have to multiply this value with the Max-Value you want to recieve - 1 and add +1 to the whole thing. Don't forget to cast this whole thing to (int).
It should look something like this:
(int) (Math.Random(5) + 1)
This way, you're getting values between 1 and 6.

In rollDice you take a value from java.util.Random. However, the upper limit is excluded, so you always end up with one by doing diceRoller.nextInt(1) + 1.
An array of integers is good for representing multiple dice, so if that's what you want, you could use diceRoller.nextInt(6) + 1 to set the value of each dice. If you want a single dice, you only need a single integer variable.

You are doing something different. You are creating random numbers from 0 to the max value of an integer.
diceRoller.nextInt(1)
This create a random number from 0 to 1. So it's rare you get 5 times 1. If you wanted to mock it, you should have put one as an assignment
Then, because this piece of code:
for (int i = 0; i < dice.length; i++) {
if (dice[i] == 5) {
resValue = 50;
} else if (dice[i] == 4) {
resValue = 40;
} else if (dice[i] == 3) {
resValue = 30;
}
}
Means that if the last of the dice[i] values are 3, 4 or 5, it gets a new value. What I think you were trying to do is this (adding ten times the value of the dice for the whole array):
int resValue = 0;
for (int i = 0; i < dice.length; i++) {
resValue += dice[i] * 10;
}
In the last case, if all the 5 direRoll results are 1, you would get 50.

Related

Java code stuck in infinitely repeating while loop

I have some code that shuffles a deck of cards by assigning randomly chosen cards from a 2D array cards into an ArrayList deck, but when I run the code it gets stuck in an infinite loop.
It was working fine at first but seemed to randomly stop working with little change to the code.
cards is a 13 x 4 array with a different card in each position.
ArrayList<String> deck = new ArrayList<String>();
for (int i = 0; i < 52; i++) {
int v = 0;
int s = 0;
Boolean notInDeck = false;
while (!notInDeck) {
v = rand.nextInt(13);
s = rand.nextInt(4);
if (!deck.contains(cards[v][s])) {
notInDeck = true;
deck.add(cards[v][s]);
}
}
}
I tried adding outputs at different points to try and track what was happening
ArrayList<String> deck = new ArrayList<String>();
for (int i = 0; i < 52; i++) {
System.out.println("1");
int v = 0;
int s = 0;
Boolean notInDeck = false;
while (!notInDeck) {
System.out.println("2");
v = rand.nextInt(13);
s = rand.nextInt(4);
if (!deck.contains(cards[v][s])) {
System.out.println("3");
notInDeck = true;
deck.add(cards[v][s]);
}
System.out.println("4");
}
System.out.println("5");
}
System.out.println("6");
There are no error messages.
The output is fine for the first bunch of run-throughs, being 1 2 3 4 5 1 2 3 4 5, but ends up infinitely repeating 2 4 2 4 2 4...
It should be like 1 2 3 4 5 1 2 3 4 5 then maybe sometimes 1 2 4 2 3 4 5 when it repeats a set of random numbers.
Here is my code for the cards 2D array.
String[][] cards = new String[13][4];
String suit = " ";
String value = "";
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 4; j++) {
if (j == 0) {
suit = "C";
} else if (j == 1) {
suit = "H";
} else if (j == 2) {
suit = "S";
} else if (j == 3) {
suit = "D";
}
if (i == 0) {
value = "A";
} else if (i == 10) {
value = "J";
} else if (i == 11) {
value = "Q";
} else if (i == 12) {
value = "K";
} else {
value = Integer.toString(i+1);
}
cards[i][j] = value;
}
}
Edit:
I realised the issue was with this line
cards[i][j] = value;
It should be
cards[i][j] = value + " " + suit;
You are making your life harder.
In real life, you are not taking gazillion of cards and you are not randomly picking cards until you complete full 52 cards deck. In fact, you start with 52 cards and you suffle them. Do the same here
Create collection of 52 cards
Shuffle that collection (eg. with Collections.shuffle)
While this is simply linear operation, your solution is indeterministic.
It shouldn't run indefinitely unless you are having an unlucky day or have initialized cards array with wrong values.
So, this is what happening. Since you are using a random guess to put a card into the deck, with each attempt it's harder and harder for random generator to find, so to say, a card that was not placed in the deck yet. At the of the day you will have more and more attempts to place last cards correctly. The number of those attempts could reach hundreds and even thousands.
I have added a couple of lines to your code and visualized the problem on Ideone.
ArrayList<String> deck = new ArrayList<String>();
HashMap<Integer, Integer> guesses = new HashMap<>();
for (int i = 0; i < 52; i++) {
int guess = 0;
int v = 0;
int s = 0;
Boolean notInDeck = false;
while (!notInDeck) {
v = rand.nextInt(13);
s = rand.nextInt(4);
guess++;
if (!deck.contains(cards[v][s])) {
notInDeck = true;
deck.add(cards[v][s]);
guesses.put(i, guess++);
}
}
}
for (Map.Entry<Integer, Integer> entry: guesses.entrySet()) {
System.out.printf("%2s : %s\n", entry.getKey(), entry.getValue());
}
If you execute the code several times, you will clearly see the pattern—the number of guesses grows significantly at the end.

Why does my program not work as expected?

I am working on problem twelve on project Euler. It is all about triangle numbers; I am trying to find the first triangle number with more than 500 divisors. I have written a program to find this, however, it is not giving me the correct answer and I can not see why. I have provided my code below:
public class problemTwelve {
public static void main(String [] args) {
int i = 1;
int number = 1;
while(getDivisors(number) < 500) {
number += i;
i++;
}
System.out.println("The first triangle number to have greater than 500 divisors is: " + number);
}
private static int getDivisors(int triangleNum) {
int noOfDivisors = 0;
int numToTest = (int) Math.sqrt(triangleNum);
for(int i = 1; i <= numToTest; i++) {
if((triangleNum % i) == 0) {
noOfDivisors += 2;
}
}
if((numToTest * numToTest) == triangleNum) {
noOfDivisors--;
}
return noOfDivisors;
}
}
The output given by the program upon running it is as follows:
The first triangle number to have greater than 500 divisors is: 146611080
Upon entering this number as the answer on project Euler, we can see that it is wrong. I don't know where I have gone wrong in my program...
It seems that the number you are checking are not triangle. Just at looking at the code, the second number checked is 2 which is not a triangle number.
Try moving the line i++; before the line number+=i;
you have to start your numbers from 0 not 1 , here is the correct code :
int i = 1;
int number = 0;
while(getDivisors(number) < 500) {
number += i;
i++;
}
System.out.println("The first triangle number to have greater than 500 divisors is: " + number);
}
private static int getDivisors(int triangleNum) {
int noOfDivisors = 0;
int numToTest = (int) Math.sqrt(triangleNum);
for(int i = 1; i <= numToTest; i++) {
if(triangleNum % i == 0) {
noOfDivisors += 2;
}
}
if((numToTest * numToTest) == triangleNum) {
noOfDivisors--;
}
return noOfDivisors;
}

How to make the loop run again if boolean is false

My issue is the when boolean is false it still returns i and places it in the array lotto. How do I fix it so that when boolean is false it will drop i and run a another random number for that element.
package LottoNumbers;
import java.util.Arrays;
public class LottoNumbers {
//check for duplicates in each array
public static boolean isFound(int[] lotto, int number) {
for (int i = 0; i < lotto.length; i++) {
if (lotto[i] == number ) {
return true;
}
}
return false;
//DO SOMETHING IF FALSE THAT WILL GET RID OF THE NUMBER
}
public static void main(String[] args) {
//specify length of array
int[] lotto = new int[6];
//determine how many arrays
for (int Set = 1; Set <= 5; Set++) {
//assign random numbers to each array element
for (int i = 0; i < lotto.length; i++) {
int number= 0;
isFound(lotto, number = (int) (Math.random() * 50));
lotto[i] = number;
}
Arrays.sort(lotto);
//sort elements in array
//Sort arrays to specified Set numbers
if (Set == 1) {
System.out.printf("LOTTO Numbers for set 1 --> ");
} else if (Set == 2) {
System.out.print("LOTTO Numbers for set 2 --> ");
} else if (Set == 3) {
System.out.print("LOTTO Numbers for set 3 --> ");
} else if (Set == 4) {
System.out.print("LOTTO Numbers for set 4 --> ");
} else if (Set == 5) {
System.out.print("LOTTO Numbers for set 5 --> ");
}
System.out.printf(Arrays.toString(lotto).replace("[", "").replace(",", "").replace("]", "") + "\n");
}
}
}
I'm not entirely sure what you're trying to do - you don't actually do anything at all with the boolean value returned by isFound. But, if you're asking whether you can only assign lotto[i] if isFound evaluates to true, one way you could do that is to change the for loop as follows:
for (int i = 0; i < lotto.length; i++) {
int number;
Boolean wasFound = isFound(lotto, number = (int) (Math.random() * 50));
if (!wasFound)
{
lotto[i] = number;
}
else
{
// perform the previous iteration again
i--;
}
}
Your design is not terrifically efficient or well-designed - you're counting on a random number you generate not having been seen before, which gets significantly worse performance-wise the more numbers you've already created. A better way you could do this would be to just take a single element of a pre-existing collection of non-repeating integers in the range you want:
// define numbersArrayList as { 1, 2, 3, 4, ... n }
ArrayList<int> yourLottoNumbers = new ArrayList<int>()
for (int i = 0; i < yourLimit; i++)
{
int randomIndex = (int)(Math.random() * numbersArrayList.length()) - 1;
int newNumber = numbersArrayList[randomIndex];
yourLottoNumbers.add(newNumber);
yourLottoNumbers.remove(randomIndex);
}
This code executes in an amount of time directly proportional to the number of elements you need to get, rather than in a totally random amount of time, and you don't need to fudge around with repeating for loops.
You don't want your function to loop if it's false, because then the function would never end.
public static boolean IsFound(int number)
{
//You don't need to pass the array, because it's a class level variable
for (int i = 0; i < lotto.length; i++)
{
if (lotto[i] == number)
return true;
return false;
}
}
Once you've done that, you can simply do something like this to add to your array:
for (int i = 0; i < lotto.length; i++)
{
int randomNumber = (Math.random() * 50);
while(IsFound(randomNumber))
{
randomNumber = (Math.random() * 50);
}
lotto[i] = randomNumber;
}

Using loops and an array to generate a list of random numbers in Java

I'm trying to get five random numbers printed that never repeat, based on a certain range provided by the user. Posted below is the code I have so far. I asked a similar question last night and got some great answers, but now I'm trying to accomplish this using only arrays and loops. Thanks.
package h1p2;
public class test{
public void method (int min, int max){
//Declare and initialize arrays and index variables
int rangeOne[];
int rangeMinMax[];
rangeOne = new int[5];
rangeMinMax = new int[max - min];
int z = min;
int i = 0;
int q = 0;
int rangeLength = rangeMinMax.length;
//need minimum/max differential of 50 or > to execute method
if (max - min < 50){
System.out.println("Please enter numbers with a differential of 50 or greater.");
}
//run if differential checks out
else{
//populate MinMax array with range specified by user
while (i < rangeLength){
rangeMinMax[i] = z;
z++;
i++;
}
}
//pick random number from MinMax array
int randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
int r = 0;
//populate rangeOne array with lotto numbers, forbidding duplicates
while (r < 5){
randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
rangeOne[r] = randomNumber;
randomNumber = (rangeMinMax[(int) (rangeLength * Math.random())]);
if (r == 1 && randomNumber == rangeOne[0]){
r--;
}
if (r == 2 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1])){
r--;
}
if (r == 3 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1] ||
randomNumber == rangeOne[2])){
r--;
}
if (r == 4 && (randomNumber == rangeOne[0] || randomNumber == rangeOne[1] ||
randomNumber == rangeOne[2] || randomNumber == rangeOne[3])){
r--;
}
else{
r++;}
}
//create string with results
String results = Integer.toString(rangeOne[0]) + " " + Integer.toString(rangeOne[1])
+ " " + Integer.toString(rangeOne[2]) + " " + Integer.toString(rangeOne[3]) +
" " + Integer.toString(rangeOne[4]);
//print results
System.out.println("MegaNumbers: " + results);
}
}
If all you need is a small amount of numbers, just use a linear search to simulate a set. Then keep generating random numbers until you've generated enough unique ones to suffice. Obviously this isn't the most efficient, but it is simple.
private static Random rand = new Random();
public static boolean contains(int [] data, int value)
{
for (int i = 0; i < data.length; i++)
{
if (data[i] == value)
{
return true;
}
}
return false;
}
public static int[] getRandom(int size, int lowerBound, int upperBound)
{
if (upperBound - lowerBound <= size)
{
throw new IllegalArgumentException("Range is too small!");
}
int totalRandoms = 0;
int[] randoms = new int[size];
while (totalRandoms != size)
{
int randNumber = rand.nextInt(upperBound - lowerBound) + lowerBound;
if (! contains(randoms, randNumber))
{
randoms[totalRandoms] = randNumber;
}
}
return randoms;
}
P.S. I've left some of the details up to you, I've just included a couple non-OO functions to give you a feel for a possible algorithm.
I wrote randomList() to accept three parameters:
1) the minimum random value
2) the maximum random value
3) and the number of random values the array should have.
The method first creates an array called choices filled with all the values from the min value to max value. It then starts a loop that fills a new array with values from choices. Whenever the loop chooses a random value from choices, it moves that value to the back of the choices array and updates lastIndex so it doesn't choose any values from the back of choices anymore.
An easier way to do this would be to make choices an ArrayList and simply delete the already taken values from it. But because we can't use ArrayLists, this code should work fine.
public static int[] randomList(int min, int max, int number) {
// fills an array with all numbers from min to max
int[] choices = new int[max - min + 1];
int lastIndex = choices.length - 1;
for(int i = min; i <= max; i++) {
choices[i - min] = i;
}
// fills the new array with values from choices
Random r = new Random();
int[] randomList = new int[number];
for(int i = 0; i < number; i++) {
int index = r.nextInt(lastIndex + 1);
randomList[i] = choices[index];
int copy = choices[lastIndex];
choices[lastIndex] = randomList[i];
choices[index] = copy;
lastIndex--;
}
return randomList;
}

Having trouble producing two seperate outputs using Random

I'm trying to create two separate outputs of 10 columns and 10 rows of numbers. The first output using numbers 4 through 7 and the second output using numbers 10 through 90 (e.g. 10, 20, 30 and so on). But calling these numbers randomly, not in a special order. Below is the Java code I have:
import java.util.Random;
public class LabRandom
{
private static final Random rand = new Random();
public static void main(String[] args)
{
int number;
int i = 1;
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(4) + 4);
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
System.out.println();
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(10 *(80) + 10));
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
}
}
I just can't figure out what I am missing, The code only runs the first while statement and not the second while statement.
You haven't reinitialised i, and after the first loop, it will already equal 101, so the second loop will not be entered.
As was mentioned in the comments on your question, a for loop would be a more appropriate construct here.
Also, in that second loop, the statement:
rand.nextInt(10 *(80) + 10)
Doesn't seem like it will do what you want. You probably need something like:
rand.nextInt(9) * 10 + 10
You need to reset i before your second while.
set the value of i before the second while loop.
import java.util.Random;
public class LabRandom
{
private static final Random rand = new Random();
public static void main(String[] args)
{
int number;
int i = 1;
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(4) + 4);
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
System.out.println();
i = 1;//modified here
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(10 *(80) + 10));
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
}
}

Categories

Resources