Симулятор Dice Roller с использованием массивов в java

Я пытаюсь создать программу, которая попросит пользователя ввести количество 6-гранных игральных костей, которые нужно бросить, а затем сколько бросков (испытаний) они хотят запустить. В конце кода он должен отображать для пользователя, сколько существует каждого возможного числа и была ли полоса (если была, то должно быть указано, что это была за полоса и с какого числа броска она началась.

Пока что для простоты моя программа должна только спрашивать, сколько испытаний нужно выполнить с двумя 6-гранными кубиками, и отображать дисплеи, как указано выше.

Проблема в том, что на дисплее не отображаются проценты, как должна позволять моя математика, и когда дело доходит до полосы, я понятия не имею, как указать, с какого испытания она началась и какой номер был на полосе.... Любая помощь будет высоко ценится.

import java.util.*;

открытый класс RollThoseDice {

public static void main(String[] args) {
    //start of method

    //variables needed for program
    int total;
    int newStreak = 1;
    int streak = 1;
    int totalIs2 = 0;
    int totalIs3 = 0;
    int totalIs4 = 0;
    int totalIs5 = 0;
    int totalIs6 = 0;
    int totalIs7 = 0;
    int totalIs8 = 0;
    int totalIs9 = 0;
    int totalIs10 = 0;
    int totalIs11 = 0;
    int totalIs12 = 0;
    double  twoPercent = 0;
    double  threePercent = 0;
    double  fourPercent = 0;
    double  fivePercent = 0;
    double  sixPercent = 0;
    double  sevenPercent = 0;
    double  eightPercent = 0;
    double  ninePercent = 0;
    double  tenPercent = 0;
    double  elevenPercent = 0;
    double  twelvePercent = 0;

    //intro to program and purpose
    System.out.println("Today we are going to generate 2 random dice and tally the results of their random combined rolls");
    System.out.println("At the bottom of the results, the longest streak will also be listed");

    //variable for while loop
    boolean validInput = true;
    //declaration of scanner before try/catch
    Scanner userInput = new Scanner(System.in);

    //test for valid input
    while (validInput){
        try {
            System.out.print(" \n" + "Please enter the number of trials you would like to be performed:");
            int numberOfRolls = Integer.parseInt(userInput.nextLine());

            //Stop from calling for anything else
            userInput.close();

            //declaring of variables for die 1 and die 2
            int die1[] = new int[numberOfRolls];
            int die2[] = new int[numberOfRolls];


            //create an array for each die roll so that they can each be saved for recalling streak
            int[] array = new int[numberOfRolls];   
            for (int i=1; i<array.length; i++ ) {
                die1[i] = (int) ((Math.random() * 6) + 1);
                die2[i] = (int) ((Math.random() * 6) + 1);
                total = die1[i] + die2[i];

                //streak checker
                int lastTotal = die1[i-1] + die2[i-1];          
                if (lastTotal == total) {
                    streak++;
                    if (streak > newStreak) {
                        newStreak = streak;
                    } 
                } else {
                    streak = 1;
                }

                //count total of each numbered possibility rolled
                if (total == 2) {
                    totalIs2++;
                }
                if (total == 3) {
                    totalIs3++;
                }
                if (total == 4) {
                    totalIs4++;
                }
                if (total == 5) {
                    totalIs5++;
                }
                if (total == 6) {
                    totalIs6++;
                }
                if (total == 7) {
                    totalIs7++;
                }
                if (total == 8) {
                    totalIs8++;
                } 
                if (total == 9) {
                    totalIs9++;
                }
                if (total == 10) {
                    totalIs10++;
                }
                if (total == 11) {
                    totalIs11++;
                }
                if (total == 12) {
                    totalIs12++;

                    //calculate percent of each number rolled
                    twoPercent = (totalIs2 / numberOfRolls);
                    threePercent = (totalIs3 / numberOfRolls);
                    fourPercent = (totalIs4 / numberOfRolls);
                    fivePercent = (totalIs5 / numberOfRolls);
                    sixPercent = (totalIs6 / numberOfRolls);
                    sevenPercent = (totalIs7 / numberOfRolls);
                    eightPercent = (totalIs8 / numberOfRolls);
                    ninePercent = (totalIs9 / numberOfRolls);
                    tenPercent = (totalIs10 / numberOfRolls);
                    elevenPercent = (totalIs11 / numberOfRolls);
                    twelvePercent = (totalIs12 / numberOfRolls);
                }
            }

            //results
            System.out.println("\n" + "Total Results:");
            System.out.println("\n" + "Total 2  happened " + totalIs2 + " times which is " + twoPercent + "%");
            System.out.println("Total 3  happened " + totalIs3 + " times which is " + threePercent + "%");
            System.out.println("Total 4  happened " + totalIs4 + " times which is " + fourPercent + "%");
            System.out.println("Total 5  happened " + totalIs5 + " times which is " + fivePercent + "%");
            System.out.println("Total 6  happened " + totalIs6 + " times which is " + sixPercent + "%");
            System.out.println("Total 7  happened " + totalIs7 + " times which is " + sevenPercent + "%");
            System.out.println("Total 8  happened " + totalIs8 + " times which is " + eightPercent + "%");
            System.out.println("Total 9  happened " + totalIs9 + " times which is " + ninePercent + "%");
            System.out.println("Total 10 happened " + totalIs10 + " times which is " + tenPercent + "%");
            System.out.println("Total 11 happened " + totalIs11 + " times which is " + elevenPercent + "%");
            System.out.println("Total 12 happened " + totalIs12 + " times which is " + twelvePercent + "%");
            System.out.println("The longest run was a run of " + newStreak + " *number that was on a streak*" + " that began at roll" + "*where it started*");

            //stop the loop
            validInput = false;
        }

        //catch exception and call for new input
        catch(Exception e){
            System.out.println("\n" + "Your input was not a number. Please try again: ");
        }
    }
}

person Jdub    schedule 06.02.2015    source источник
comment
Почему ваш цикл for не начинается с 0? Вы должны сохранить общее количество двух кубиков в массиве «массив».   -  person Neha Agrawal    schedule 06.02.2015
comment
когда у вас есть длинная череда таких операторов IF, вам следует рассмотреть возможность использования оператора switch для ясности.   -  person Bryan Devaney    schedule 06.02.2015


Ответы (5)


Как упоминалось в первом ответе lifus, используйте массив. Кроме того, полосу и с какой попытки она начинается, можно достаточно легко сохранить. Сохраните начало как start = current_trial_no - current_longest_streak. Это означает, что ваше назначение переменной входит в ту часть, где вы сохраняете самое длинное значение полосы.

import java.util.*;
import java.lang.*;
import java.io.*;
import java.text.DecimalFormat;

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Scanner cin = new Scanner(System.in);
        boolean run = true ;
        int[] sum = new int[13] ;
        float[] percent = new float[13];
        int streak = 0, streakValue = 0, currentStreak = 0, streakStart = 0, trials = 0 ;
        int dice1 = 0, dice2 = 0 ;
        for(int i = 0; i < sum.length; ++i)
        {
            sum[i] = 0 ;
            percent[i] = 0.0f;
        }
        do
        {
            trials = cin.nextInt();
            int prevSum = 0 ;

            for(int t = 0; t < trials; ++t)
            {
                dice1 = (int) ((Math.random() * 6) + 1);
                dice2 = (int) ((Math.random() * 6) + 1);
                sum[dice1 + dice2]++ ;
                if((dice1 + dice2) == prevSum)
                {
                    ++currentStreak ;
                    streakValue = prevSum ;
                    if(currentStreak > streak)
                    {
                        streak = currentStreak ;
                        streakStart = t - streak ;
                    }
                }
                else {
                    currentStreak = 1 ;
                }
                prevSum = dice1 + dice2 ;
            }

            System.out.println("Continue ? (y/n) : ");
            run = cin.nextLine().equals("y");
        } while(run);

        DecimalFormat df = new DecimalFormat("###.##");

        // Start from 2 - the minimum sum possible.
        for(int i = 2; i < 13; ++i)
        {
            percent[i] = (float)sum[i] / (float)trials * 100.0f ;
            System.out.println("The sum " + i + " has occurred " + df.format(percent[i]) + "% of times");
        }
        System.out.println("Longest streak of " + streakValue + " has occurred for " + streak + " times");
        System.out.println("It started at : " + streakStart);
    }

}

Обратите внимание на внутреннюю часть условия if внутри цикла. Вот рабочая версия того же.

person a_pradhan    schedule 06.02.2015
comment
Я очень ценю помощь каждого (даже сохранил этот последний код в качестве ссылки на потом с этой опцией продолжения). Спасибо вам, ребята! Это в основном то, где я сейчас нахожусь, но я, вероятно, еще немного подправлю его в будущем. Спасибо еще раз! - person Jdub; 06.02.2015
comment
4 пробела вместо табуляции для отступа. - person a_pradhan; 07.02.2015

Вы должны перенести свои //calculate percent of each number rolled расчеты непосредственно перед //results. Обратите внимание, что вы поместили его внутрь if (total == 12). На самом деле это должно быть percents[i] = (total[i] * 100 / numberOfRolls);

В следующий раз вы напишете что-то вроде:

int totalIs2 = 0;
int totalIs3 = 0;
...

Вы должны использовать массив

и вы можете написать цикл for вместо линейного повторяющегося кода


то есть вы можете заменить:

//calculate percent of each number rolled
twoPercent = (totalIs2 / numberOfRolls);
...

а также

System.out.println("\n" + "Total 2  happened " + totalIs2 + " times which is " + twoPercent + "%");
...

с

for (int i = 2; i < totalCount.length; i++) {
    double percent = totalCount[i] * 100/ numberOfRolls;
    System.out.println("\n" + "Total " + i + "  happened " + totalCount[i] + " times which is " + percent + "%");
}

Вот вся программа:

public class RollThoseDices {
    private int lastTotal;
    private int streak;
    private int longestStreak;
    private int startOfTheLongestStreak;

    private int[] totalCount = new int[13];

    RollThoseDices(int numberOfRolls) {
        run(numberOfRolls);
    }

    public void run(int numberOfRolls) {
        for (int i=0; i<numberOfRolls; i++ ) {
            int die1 = (int) ((Math.random() * 6) + 1);
            int die2 = (int) ((Math.random() * 6) + 1);
            int total = die1 + die2;
            totalCount[total]++;

            if (lastTotal == total) {
                streak++;
                if (streak > longestStreak) {
                    longestStreak = streak;
                    startOfTheLongestStreak = i - longestStreak;
                }
            } else {
                streak = 1;
            }
            lastTotal = total;
        }
    }

    private static int readInt(Scanner scanner) {
        System.out.print(" \n" + "Please enter the number of trials you would like to be performed:");
        while (!scanner.hasNextInt()) {
            scanner.next();
            System.out.println("\n" + "Your input was not a number. Please try again: ");
        }
        return scanner.nextInt();
    }

    public static void main(String[] args) {
        //intro to program and purpose
        System.out.println("Today we are going to generate 2 random dice and tally the results of their random combined rolls");
        System.out.println("At the bottom of the results, the longest streak will also be listed");

        // read number of rolls
        int numberOfRolls = 0;
        try(Scanner userInput = new Scanner(System.in)) {
            numberOfRolls = readInt(userInput);
        }

        RollThoseDices results = new RollThoseDices(numberOfRolls);

        //results
        System.out.println("\n" + "Total Results:");
        System.out.println("The longest run was a run of " + results.longestStreak + " that began at roll " + results.startOfTheLongestStreak);
        for (int i = 2; i < results.totalCount.length; i++) {
            double percent = (results.totalCount[i] * 100.0) / numberOfRolls;
            System.out.println("\n" + "Total " + i + "  happened " + results.totalCount[i] + " times which is " + percent + "%");
        }
    }
}
person lifus    schedule 06.02.2015

Похоже, вам дали незамедлительный совет по использованию массивов. Как продемонстрировали другие, это значительно сокращает количество строк кода и количество повторов при наборе текста. Еще одна вещь, которую я хотел бы выделить, это когда программисты пытаются мыслить более абстрактно. Разбейте функции на более мелкие более простые фрагменты. Иногда, когда думаешь о картине в целом, она становится немного поглощающей, и с ней приходится иметь дело. На практике это означает, например, что для этого броска кубиков, возможно, сначала нужно создать класс, который представляет кубик, что-то вроде;

public class Dice
{
    //declare values

    Public Dice()
    {
     //initialise values
    }

    public int rollDice(int times)
    {
     // some code here
    ]

    public int countStreaks()
    {
     // some code here
    }
}

Очевидно, что приведенный выше код является лишь быстрым примером, но дело в том, что приведенный выше класс предоставит вам все основные функции игры в кости, необходимые для создания остальной части вашей программы. Затем ваша точка входа может просто использовать этот класс для выполнения нужных вам функций. Вы обнаружите, что программирование таким образом дает целый ряд преимуществ, не ограничиваясь повышением производительности, и облегчает вам задачу, когда/если вы когда-нибудь захотите вернуться и добавить функциональность или расширить исходную программу за пределы ее первоначального объема. Соедините это с тем, что вы узнали выше об использовании массивов, и посмотрите, как вы справитесь. Как только вы это сделаете, я бы порекомендовал сравнить ваш новый код со старым, чтобы увидеть разницу.

Надеюсь, это поможет,

С уважением, В

person Vect0r    schedule 07.02.2015

 import javax.swing.*;

импортировать java.util.*;

открытый класс RollThoseDice {

public static void main(String[] args) {
    //start of method


    //variables needed for program
    int total;
    int newStreak = 1;
    int streak = 1;
    int totalIs2 = 0;
    int totalIs3 = 0;
    int totalIs4 = 0;
    int totalIs5 = 0;
    int totalIs6 = 0;
    int totalIs7 = 0;
    int totalIs8 = 0;
    int totalIs9 = 0;
    int totalIs10 = 0;
    int totalIs11 = 0;
    int totalIs12 = 0;
    double  twoPercent;
    double  threePercent;
    double  fourPercent;
    double  fivePercent;
    double  sixPercent;
    double  sevenPercent;
    double  eightPercent;
    double  ninePercent;
    double  tenPercent;
    double  elevenPercent;
    double  twelvePercent;

    //intro to program and purpose
    System.out.println("Today we are going to generate 2 random dice and tally the results of their random combined rolls");
    System.out.println("At the bottom of the results, the longest streak will also be listed");

    //variable for while loop
    boolean validInput = true;
    //declaration of scanner before try/catch
    Scanner userInput = new Scanner(System.in);

    //test for valid input
    while (validInput){
        try {
        int numberOfRolls = Integer.parseInt(JOptionPane.showInputDialog("Please Enter the number of trials you would like to be performed: "));

            //Stop from calling for anything else
            userInput.close();

            //declaring of variables for die 1 and die 2
            int die1[] = new int[numberOfRolls];
            int die2[] = new int[numberOfRolls];


            //create an array for each die roll so that they can each be saved for recalling streak
            int[] array = new int[numberOfRolls];   
            for (int i=1; i<array.length; i++ ) {
                die1[i] = (int) ((Math.random() * 6) + 1);
                die2[i] = (int) ((Math.random() * 6) + 1);
                total = die1[i] + die2[i];

                //streak checker
                int lastTotal = die1[i-1] + die2[i-1];          
                if (lastTotal == total) {
                    streak++;
                    if (streak > newStreak) {
                        newStreak = streak;


        /*              // Find-Max variant -- rather than finding the max value, find the
                        // *index* of the max value
                        public int findMaxIndex(int[] nums) {
                          int maxIndex = 0;  // say the 0th element is the biggest
                          int maxValue = nums[0];

                          // Look at every element, starting at 1
                          for (int i=1; i<nums.length; i++) {
                            if (nums[i] > maxValue) {
                              maxIndex = i;
                              maxValue = nums[maxIndex];
                            }
                          }
                          return maxIndex;
                        }
*/                      

                    } 
                } else {
                    streak = 1;
                }

                //count total of each numbered possibility rolled
                if (total == 2) {
                    totalIs2++;
                }
                if (total == 3) {
                    totalIs3++;
                }
                if (total == 4) {
                    totalIs4++;
                }
                if (total == 5) {
                    totalIs5++;
                }
                if (total == 6) {
                    totalIs6++;
                }
                if (total == 7) {
                    totalIs7++;
                }
                if (total == 8) {
                    totalIs8++;
                } 
                if (total == 9) {
                    totalIs9++;
                }
                if (total == 10) {
                    totalIs10++;
                }
                if (total == 11) {
                    totalIs11++;
                }
                if (total == 12) {
                    totalIs12++;
                }
            }



    //Apply decimal place rounder in order to get percentages rounded to 2 places       



            //calculate percent of each number rolled
            twoPercent = (totalIs2 / (double) numberOfRolls) * 100;
            threePercent = (totalIs3 / (double) numberOfRolls) * 100;
            fourPercent = (totalIs4 / (double) numberOfRolls) * 100;
            fivePercent = (totalIs5 / (double) numberOfRolls) * 100;
            sixPercent = (totalIs6 / (double) numberOfRolls) * 100;
            sevenPercent = (totalIs7 / (double) numberOfRolls) * 100;
            eightPercent = (totalIs8 / (double) numberOfRolls) * 100;
            ninePercent = (totalIs9 / (double) numberOfRolls) * 100;
            tenPercent = (totalIs10 / (double) numberOfRolls) * 100;
            elevenPercent = (totalIs11 / (double) numberOfRolls) * 100;
            twelvePercent = (totalIs12 / (double) numberOfRolls) * 100;

            //results
            System.out.println("\n" + "Total Results:");
            System.out.println("\n" + "Total 2  happened " + totalIs2 + " times which is " + twoPercent + "%");
            System.out.println("Total 3  happened " + totalIs3 + " times which is " + threePercent + "%");
            System.out.println("Total 4  happened " + totalIs4 + " times which is " + fourPercent + "%");
            System.out.println("Total 5  happened " + totalIs5 + " times which is " + fivePercent + "%");
            System.out.println("Total 6  happened " + totalIs6 + " times which is " + sixPercent + "%");
            System.out.println("Total 7  happened " + totalIs7 + " times which is " + sevenPercent + "%");
            System.out.println("Total 8  happened " + totalIs8 + " times which is " + eightPercent + "%");
            System.out.println("Total 9  happened " + totalIs9 + " times which is " + ninePercent + "%");
            System.out.println("Total 10 happened " + totalIs10 + " times which is " + tenPercent + "%");
            System.out.println("Total 11 happened " + totalIs11 + " times which is " + elevenPercent + "%");
            System.out.println("Total 12 happened " + totalIs12 + " times which is " + twelvePercent + "%");
            System.out.println("The longest run was a run of " + newStreak + " *number that was on a streak*" + " that began at roll" + "*where it started*");

            //stop the loop
            validInput = false;
        }

        //catch exception and call for new input
        catch(Exception e){
            System.out.println("\n" + "Your input was not a number. Please try again: ");
        }
    }
}

}

person Jdub    schedule 10.02.2015

импортировать java.text.DecimalFormat; импортировать java.util.*; //импорт утилит

открытый класс RollThoseDice {

//private variables for use in code
private int firstRoll; //initial total to compare with next to scan for streaks
private int streak; //streak
private int longestStreak; //longest streak if more than 1
private int beginningOfLongestStreak; //where in the code the longest streak started for display
private int[] combineTotal = new int[13]; //total of 2 randomly rolled 6-sided dice

RollThoseDice(int numberOfRolls) {
    run(numberOfRolls);
}

public void run(int numberOfRolls) {
    for (int i=0; i<numberOfRolls; i++ ) {
        int die1 = (int) ((Math.random() * 6) + 1); //random number between 1-6
        int die2 = (int) ((Math.random() * 6) + 1);
        int total = die1 + die2; //math for total
        combineTotal[total]++; //adding totals to the array

        if (firstRoll == total) { //comparing 2 rolls in order to see if there is a streak or not
            streak++;
            if (streak > longestStreak) { //comparing new streak to old streak to pick the larger of 2
                longestStreak = streak;
                beginningOfLongestStreak = i - longestStreak; //getting to the beginning of the streak in order to display to user
            }
        } else {
            streak = 1;
        }
        firstRoll = total;
    }
}

private static int readInt(Scanner scanner) {
    System.out.print(" \n" + "Please enter the number of trials you would like to be performed: "); //prompt user for number of trials (int only)
    while (!scanner.hasNextInt()) {
        scanner.next();
        System.out.println("\n" + "Your input was not a number. Please try again: "); //drop garbage input
    }
    return scanner.nextInt(); //return good input
}

public static void main(String[] args) {
    //intro to program and purpose
    System.out.println("Today we are going to generate 2 random dice and tally the results of their random combined rolls");
    System.out.println("At the bottom of the results, the longest streak will also be listed");

    // read number of rolls
    int numberOfRolls = 0; //casting the number of rolls as 0 initially
    try(Scanner userInput = new Scanner(System.in)) {
        numberOfRolls = readInt(userInput); //declaring that the above good input is variable number of rolls
    }

    RollThoseDice results = new RollThoseDice(numberOfRolls);
    DecimalFormat df = new DecimalFormat("###,##0.00"); //round the decimal values

    //results
    System.out.println("\n" + "Total Results:");
    for (int i = 2; i < results.combineTotal.length; i++) {
        double percent = (results.combineTotal[i] * 100.0) / numberOfRolls;
        System.out.println("Total " + i + "  happened " + results.combineTotal[i] + " times which is " + df.format(percent) + "%"); //display rolls info
}
    System.out.println("\n" +"The longest run was a run of " + results.longestStreak + " that began at roll " + results.beginningOfLongestStreak); //display streak info
}

}

person Jdub    schedule 10.02.2015