Java Hangman — проверка ошибок

Для моей игры с палачом я хотел бы иметь кучу сообщений об ошибках, чтобы проверять такие вещи, как ввод более одной буквы, угадывание одной и той же буквы дважды и т. д. Мой полный код на данный момент:

    import java.awt.Color;
    import java.awt.Font;
    import java.util.Random;
    import javax.swing.JOptionPane;
    import javax.swing.UIManager;
    import javax.swing.plaf.FontUIResource;

    public class MainFrame extends javax.swing.JFrame {

        public MainFrame() {
            initComponents();
        }
        //declare variables
        static String secretWord = "";
        double result = 0;
        StringBuilder mainWord = new StringBuilder();
        StringBuilder xletters = new StringBuilder(); // letters guessed
        String[] words = {"technology", "computer", "camera", "graphic", "digital", "media", "technician",
            "photography", "troubleshoot", "pixels", "application", "download"};
        Random r = new Random();
        int randValue = r.nextInt(12);
        String guessWord = words[randValue];
        int errors = 0;
        public static int wins = 0, losses = 0;
        String foundWord = null;
        private void GuessButtonActionPerformed(java.awt.event.ActionEvent evt)         {                                            
            String strGuess = GuessText.getText(); //user input           
            String letter = strGuess;
            xletters.append(strGuess.toUpperCase());
            String GuessedLetters = xletters.toString();

            try {
    //replace underscores with letters as they are guessed
                do {
                    for (int i = 0; i < 1; i++) {
                        secretWord = secretWord + letter.charAt(0);
                        foundWord = words[randValue].replaceAll("[^" + secretWord + "]", "_ ");
                        //if user entered more than one letter
                        if (strGuess.length() > 1) {
                            JOptionPane.showMessageDialog(null, "Only one letter at a time!");
                            xletters.append("");
                            GuessedLetters = null;
                            GuessText.setText(null);
                            GuessText.requestFocusInWindow();
                        } //if letter isn't in word
                        else if (guessWord.indexOf(strGuess) == -1) {
                            JOptionPane.showMessageDialog(null, "Sorry, that wasn't in the word.");
                            errors++;
                            if (errors == 1) {
                                Hangman0.setVisible(false);
                            }
                            if (errors == 2) {
                                Hangman1.setVisible(false);
                            }
                            if (errors == 3) {
                                Hangman2.setVisible(false);
                            }
                            if (errors == 4) {
                                Hangman3.setVisible(false);
                            }
                            if (errors == 5) {
                                Hangman4.setVisible(false);
                            }
                            if (errors == 6) {
                                Hangman5.setVisible(false);
                            }
                            if (errors == 7) {
                                Hangman6.setVisible(false);
                            }
                            if (errors == 8) {
                                Hangman7.setVisible(false);
                            }
                            if (errors == 9) {
                                Hangman8.setVisible(false);
                            }
                            if (errors == 10) {
                                Hangman9.setVisible(false);
                                JOptionPane.showMessageDialog(null, "You lost! The word was: " + guessWord);
                                losses++;
                                DirectionsFrame DFrame = new DirectionsFrame();
                                DFrame.setVisible(true);
                                setVisible(false);
                                MainFrame MFrame = new MainFrame();
                                MFrame.dispose();
                                xletters.delete(0, 100);
                                secretWord = "";
                                foundWord = null;
                                strGuess = null;
                                String strLosses = Integer.toString(losses);
                                String strWin = Integer.toString(wins);
                                DirectionsFrame.WinsLabel.setText(strWin);
                                DirectionsFrame.LossesLabel.setText(strLosses);
                            }
                }
            }
                    WordLabel.setText(foundWord.toUpperCase());
                    GuessedLabel.setText(GuessedLetters);
                    GuessText.setText(null);
                    GuessText.requestFocusInWindow();
                } while (foundWord == null);
                if (foundWord.equalsIgnoreCase(guessWord)) {
                    JOptionPane.showMessageDialog(null, "Yay!");
                    wins++;
                    DirectionsFrame DFrame = new DirectionsFrame();
                    DFrame.setVisible(true);
                    setVisible(false);
                    MainFrame MFrame = new MainFrame();
                    MFrame.dispose();
                    xletters.delete(0, 100);
                    secretWord = "";
                    foundWord = null;
                    String strWin = Integer.toString(wins);
                    String strLosses = Integer.toString(losses);
                    DirectionsFrame.WinsLabel.setText(strWin);
                    DirectionsFrame.LossesLabel.setText(strLosses);
                }
            } catch (StringIndexOutOfBoundsException e) {
                JOptionPane.showMessageDialog(null, "Please enter a letter.");
                GuessedLabel.setText(GuessedLetters);
                GuessText.setText(null);
                GuessText.requestFocusInWindow();
            }
        }                                           


        private void GetButtonActionPerformed(java.awt.event.ActionEvent evt) {
            //print out underscores to begin game
            for (int i = 0; i < guessWord.length(); i++) {
                mainWord.append("_ ");
            }
            String SetMain = mainWord.toString();
            mainWord.append(secretWord);
            WordLabel.setText(SetMain);
            GuessButton.setEnabled(true);
            GetButton.setEnabled(false);
        }

Больше всего у меня возникают проблемы с проверкой того, дважды ли пользователь ввел одну и ту же букву. Таким образом, вы можете только один раз угадать одну букву в алфавите. Кроме того, я считаю, что код, в котором он проверяет, ввел ли пользователь более одной буквы, имеет ошибку, потому что там, где я хочу, чтобы он не добавлял эти буквы в поле угаданных букв, он все равно добавляется. (т.е. пользователь угадывает "hf" и в угаданных буквах идет "hf", где должно быть просто ничего)

Я чувствую, что ответ лежит в методе indexOf(), но я не совсем уверен в том, что скажет условие if...

Я использую Netbeans IDE 7.2 для компиляции своего кода. Пожалуйста помоги! Спасибо.


person JavaProdigy    schedule 10.11.2012    source источник
comment
Кстати: Hangman0...Hangman9 можно заменить на Hangman[errors]. Просто мысль.   -  person Yanick Rochon    schedule 11.11.2012
comment
... и почему бы вам просто не иметь 26 кнопок, помеченных от A до Z, и позволить пользователю нажимать их (button.setEnabled(false);) вместо использования текстового поля?   -  person Yanick Rochon    schedule 11.11.2012
comment
@YanickRochon это названия лейблов с изображениями палача. Я собирался сделать это с самого начала, но думал, что это будет сложно. Как мне установить кнопку равной букве?   -  person JavaProdigy    schedule 11.11.2012
comment
посмотрите на команду действия кнопки   -  person Yanick Rochon    schedule 11.11.2012
comment
@YanickRochon, например, у меня есть кнопка с именем A. тогда, когда эта кнопка нажата ..... что тогда? Другими словами, как мне установить его равным букве а, а затем мне придется копировать цикл for в каждую из букв?   -  person JavaProdigy    schedule 11.11.2012
comment
если вы установите один и тот же прослушиватель действий для каждой из этих кнопок, и каждая кнопка имеет свою команду действия, установленную на заданную букву (например, A), то внутри метода actionPerformed вы можете получить, какая кнопка была нажата, используя evt.getActionComment() (пример: который верните строку A, если эта кнопка нажата), и вы сможете получить данный JButton с помощью (JButton) evt.getSource()   -  person Yanick Rochon    schedule 11.11.2012


Ответы (3)


В ситуации, когда вы хотите узнать, использовалось ли что-то уже, вам пригодится Set. Например, если использовать буквы в игре «Виселица», у вас будет Set<String> collection :

Set<String> lettersUsed = new HashSet<String>();

Если вы хотите узнать, было ли что-то уже выбрано:

String inputLetter = "Z";  // test for the letter Z

if (!lettersUsed.contains(inputLetter)) {
    lettersUsed.add(inputLetter);

    // process letter in word
} else {
    // letter has already been used!
}

Если вы хотите разрешить только определенный набор букв, уже изначально заданный:

if (lettersAllowed.contains(inputLetter)) {
   lettersAllowed.remove(inputLetter);

   // process letter in word
} else {
   // letter is not allowed (anymore)
}
person Yanick Rochon    schedule 10.11.2012
comment
я пытался использовать if (guessedLetters.contains(strGuess)), но это не сработало. aggedLetters — это список угаданных букв, а strGuess — их ввод. - person JavaProdigy; 11.11.2012
comment
как бы я использовал lettersUsed для сбора букв, которые угадал пользователь? - person JavaProdigy; 11.11.2012
comment
@JavaProdigy, можете ли вы уточнить, может ли пользователь указывать более одной буквы для ввода? Я предполагаю, что пользователь может вводить только одну букву за раз прямо сейчас. - person Yanick Rochon; 11.11.2012
comment
они могут угадывать только по одному, теперь вместо этого я установил кнопки az - person JavaProdigy; 11.11.2012

Чтобы увидеть, угадали ли они что-то, у вас может быть String, который сначала пуст, и когда они делают предположение, вы можете добавить эту букву в String:

String guesses = "";
...
guesses+= letter;

Похоже, вы уже делаете что-то подобное, но обязательно просто добавьте букву, а не создавайте для нее новую строку. Таким образом, вы можете каждый раз проверять, содержит ли ваша догадка String уже новую угаданную букву (if(guesses.contains(letter)).

Кроме того, я не уверен, почему у вас есть цикл for только с одной итерацией, но в случае с несколькими буквами вы можете попробовать выйти из цикла или продолжить, если вы чувствуете

person awolfe91    schedule 10.11.2012

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

List<String> usedletters = new List<String>(26);

boolean checkLetterUsed(String input){
    boolean tempvariable = false;
    for(String letter: usedletters){
        if(letter==input){
            tempvariable = true;
        }
    }
    if(tempvariable){
        return true;
    }else{
        usedletters.add(input);
        return false;
    }
}
person caveman    schedule 10.11.2012
comment
не могли бы вы объяснить используемый там цикл for? это отличается от того, к чему я привык. также я использую StringBuilder для добавления угаданных букв в jLabel, имеет ли это значение? - person JavaProdigy; 11.11.2012
comment
цикл for говорит: для каждой строки, которую вы найдете в цикле используемых букв списка, и присвойте текущей строке переменную букву. и не имеет значения, используете ли вы строку или построитель строк. пока можно сравнить. - person caveman; 11.11.2012