简体   繁体   中英

Loop through random letters without repeats

For each row of JRadioButtons I've created through a loop, I'm finding it difficult to ensure that no letters are repeated for each row. I don't mind if the same letters exist on different rows though.

Any ideas?

Thanks in advance.

Below is the relevant code:

    //loop for making flow layout for each line of random letters
    //counter for having number of the row next to each row in order of selection
    int counter = x;
    //array of booleans 
    boolean[] responses = new boolean[x];
    for(int i = 0; i < x; i++)
    {

        //new jpanel created for every row needed for the word
        JPanel jpLine = new JPanel(new FlowLayout());

        //new jlabel made with counter number for each row
        JLabel count = new JLabel(Integer.toString(counter));
        jpLine.add(count);
        counter--;
        //random number from 0-5 generated for each row
        Random number = new Random();
        int low = 0;
        int high = 5;
        int ranNumber = number.nextInt((high - low) + low);

        //buttongroup outside loop so only one button can be pressed for each row
        ButtonGroup bg = new ButtonGroup();

        //get selected button's index in any group with bg.getSelection().getActionCommand()
        final int row = i;

        ActionListener listener = new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {

                String action = e.getActionCommand();

                if (action.equals("Incorrect")) {
                    responses[row] = false;
                }
                else {
                    responses[row] = true;
                    //System.out.println("row " + row);
                    //System.out.println("btn " + action);
                }

                if(checkAnswers(responses) == true)
                {
                    correct.setText("<html><font color = 'white'>correct</font></html>");
                }

            }
        };

        //loop for making the number of letters in each row - always going to be 6 letters to choose from in each row
        for(int j = 0; j < 5; j++)
        {
            //if the random number generated for each row equals the loop
            //then new radiobutton will be created for the ith letter of the reversed
            //answer, starting from charAt 0 and going to the last character
            if(ranNumber == j)
            {
                JRadioButton answerLetter = new JRadioButton("<html><font color = 'white'>" + answerForGrid.charAt(i) + "</font></html>");

                bg.add(answerLetter);
                answerLetter.setBackground(Color.decode("#566771"));
                answerLetter.setOpaque(true);
                jpLine.add(answerLetter);

                //use setActionCommand("" + j) on each button to associate each button with its index
                answerLetter.setActionCommand("" + j);
                answerLetter.addActionListener(listener);

            }

            //ranLetter is generated randomly from the alphabet string, so random letters are
            //created for each jradiobutton
            final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            final int N = alphabet.length();

            Random letter = new Random();
            char ranLetter;

            while(true) 
            {
                ranLetter = alphabet.charAt(letter.nextInt(N));
                break;
            }

            JRadioButton k = new JRadioButton("<html><font color = 'white'>" + ranLetter + "</font></html>");

            bg.add(k);
            k.setBackground(Color.decode("#566771"));
            k.setOpaque(true);
            jpLine.add(k);
            k.setActionCommand("Incorrect");
            k.addActionListener(listener);


        }
        //add each row of letters (jpLine) to this loops jpanel
        jpCenterCenter.add(jpLine);


    }
  1. Use an ArrayList<Character> of letters you can choose from.
  2. Generate a random index for the list based on the list size() for each row.
  3. remove the letter as you select it from the list

For example:

// One possible way of creating your list
// Reset your list within each "i" loop, just before the "j" loop, 
//   or you'll never repeat letters across rows
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ArrayList<Character> possibleLetters = new ArrayList<Character>(alphabet.length);
for (char c : alphabet) possibleLetters.add(c);

// now select randomly "without replacement"
for (int j = 0; i < 5; j++) {
    int index = number.nextInt(possibleLetters.size());
    String letter = possibleLetters.remove(index);
}

You could also just do:

String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ArrayList<Character> possibleLetters = new ArrayList<Character>(alphabet.length);
for (char c : alphabet) possibleLetters.add(c);
Collections.shuffle(possibleLetters); // optionally: shuffle(possibleLetters, number)

for (int j = 0; i < 5; j++) {
    String letter = possibleLetters.get(j);
}

If you do that you don't need to reset it each time, you can just shuffle it each time.

You could use a combination of List and Collections.shuffle to randomise the list of available characters, for example...

String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
List<String> values = new ArrayList<>(Arrays.asList(alphabet.split("")));
for (int row = 0; row < 10; row++) {

    Collections.shuffle(values);
    for (int col = 0; col < 5; col++) {
        System.out.print(values.get(col));
    }
    System.out.println("");

}

Because, each character only appears within the List once, it is impossible to get duplicates, but the use of Collections.shuffle takes care of the randomisation process for each row.

Of course, this is reliant on the fact that you're allowed to use these libraries ;)

无需深入研究JRadioButtons和其他内容的代码,我会认为随机排列是您要锁定的对象。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM