-2

I've been using JForm for this code, but I somehow can't get the for loop to work. I'm not even quite sure if the for loop is the problem here. There should be a maximum of 3 attempts, submitting 3 different answers on the same button, trying to guess a single character from an array. Plus, despite me entering the random element as displayed, it would still display that I got it wrong :(( I would really appreciate help on this for a project!

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    //Scanner gags = new Scanner(System.in); 
            String newr = ans.getText();
            
    
    for (int i = 0; i < 3; i++) {
                
                if (ans.getText() == randomElement) {
                    
                    finalAns.setText("You got it right!");
                    
                } 
                
                else {
        
                    for (int j = 0; j < 0; j++){
                        if (arriba[j] == newr){
                            if (j > go){
                                guesses.setText("guess lower");
                            }
                            if (j < go){
                                guesses.setText("guess higher");
                            }
                        }
                    }
                             }  
            } while  (++attemptsNum < maxAttempts );

             if (attemptsNum == maxAttempts)
                ambotGags.setText("You lose. The letter was : " + randomElement);
    //}
            
            
} 

1 Answers1

1

You would not use a loop, because you would be awaiting user input.

Your button's action listener would wait for the user to click a button. There would be no loops inside the hander function, unless you are iterating over the buttons.

All you need to do is subtract the guessed letter from the target letter. If the delta (difference) is 0, and the player has not exhausted all their guesses, then they win. Else, if they run out, let them know they lost and reveal the letter. If they still have guesses let them now if they guessed too low/high.

In the Swing app below, if the player guesses too high, all buttons after the button (including the guessed button) will be disabled. This is a simple UX design to make guessing easier for the user.

Note: I created an interface called InputAcceptor that has an acceptInput(input:String):void signature. I then gave this interface to the ButtonListener's constructor for handling buttons input and passing its text around.

GuessApp.java

import java.util.List;
import java.util.OptionalInt;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GuessApp implements InputAcceptor, Runnable {
    private static final char[] alphabet;

    private List<JButton> buttons;
    private ButtonListener buttonListener;

    private char letterToGuess;
    private int guessesLeft;
    private int maxGuesses;

    static {
        alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    }

    public GuessApp(int maxGuesses) {
        this.maxGuesses = maxGuesses;
        this.buttonListener = new ButtonListener(this);

        setup();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GuessApp(3));
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Guess a Letter");
        frame.setContentPane(initializeContent());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    @Override
    public void acceptInput(String input) {
        int buttonIndex = indexOf(buttons, input, JButton::getText).orElse(-1);
        char guessed = input.toUpperCase().charAt(0);
        int diff = guessed - letterToGuess;

        guessesLeft--;

        if (diff == 0) {
            int response = JOptionPane.showConfirmDialog(null,
                    String.format("You won with %d guess(es) left! Restart?", this.guessesLeft),
                    "Congratulations!",
                    JOptionPane.INFORMATION_MESSAGE);
            if (response == JOptionPane.OK_OPTION) {
                setup();
            } else if (response == JOptionPane.NO_OPTION || response == JOptionPane.CANCEL_OPTION) {
                System.exit(0);
            }
        } else {
            if (guessesLeft < 1) {
                int response = JOptionPane.showConfirmDialog(null,
                        String.format("You ran out of guesses! The answer was %c. Restart?", this.letterToGuess),
                        "You Lose!",
                        JOptionPane.ERROR_MESSAGE);
                if (response == JOptionPane.OK_OPTION) {
                    setup();
                } else if (response == JOptionPane.NO_OPTION) {
                    System.exit(0);
                }
            } else {
                if (diff > 0) {
                    JOptionPane.showMessageDialog(null,
                            String.format("You need to guess lower than %c", guessed),
                            "Too High",
                            JOptionPane.WARNING_MESSAGE);
                    disableButtons(buttonIndex, buttons.size());
                } else {
                    JOptionPane.showMessageDialog(null,
                            String.format("You need to guess higher than %c", guessed),
                            "Too Low",
                            JOptionPane.WARNING_MESSAGE);
                    disableButtons(0, buttonIndex + 1);
                }
            }
        }
    }

    protected void setup() {
        this.guessesLeft = maxGuesses;
        this.letterToGuess = randomValue(alphabet);
        if (buttons != null && !buttons.isEmpty()) {
            buttons.forEach(button -> {
                if (!button.isEnabled()) {
                    button.setEnabled(true);
                }
            });
        }
        System.out.printf("Answer: %c%n", this.letterToGuess);
    }

    protected JPanel initializeContent() {
        JPanel container = new JPanel(new GridLayout(4, 8));
        buttons = generateButtons();
        buttons.forEach(button -> {
            button.addActionListener(buttonListener);
            container.add(button);
        });
        return container;
    }

    private List<JButton> generateButtons() {
        return IntStream
                .range(0, alphabet.length)
                .mapToObj(i -> alphabet[i])
                .map(letter -> new JButton(Character.toString(letter)))
                .collect(Collectors.toList());
    }

    private void disableButtons(int from, int to) {
        for (int i = from; i < to; i++) {
            if (buttons.get(i).isEnabled()) {
                buttons.get(i).setEnabled(false);
            }
        }
    }

    public static char randomValue(char[] arr) {
        int index = (int) (Math.random() * arr.length);
        return arr[index];
    }

    private static <E> OptionalInt indexOf(List<E> list, String text, Function<E, String> predicate) {
        return IntStream.range(0, list.size())
                .filter(i -> text.equals(predicate.apply(list.get(i))))
                .findFirst();
    }
}

InputAcceptor.java

public interface InputAcceptor {
    void acceptInput(String input);
}

ButtonListener.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

public class ButtonListener implements ActionListener {
    private InputAcceptor inputAcceptor;

    public ButtonListener(InputAcceptor inputAcceptor) {
        this.inputAcceptor = inputAcceptor;
    }

    public void actionPerformed(ActionEvent e) {
        if (!(e.getSource() instanceof JButton)) {
            throw new IllegalArgumentException("Event source must be a JButton");
        }
        this.inputAcceptor.acceptInput(((JButton) e.getSource()).getText());
    }
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132