【问题标题】:Java Hangman - replacing underscore with character [duplicate]Java Hangman - 用字符替换下划线[重复]
【发布时间】:2012-11-06 16:31:42
【问题描述】:

所以我正在为我的 java 类创建一个刽子手游戏,但是我在用字母替换单词中的下划线时遇到了麻烦。我让它打印出下划线中的单词,例如:

     for(int i = 0; i < GuessWord.length(); i++) { 
                if (guesses[GuessWord.charAt(i) - 'a']) { 
                    mainword.append(words[i].charAt(i));
                }
                else {
                    mainword.append("_");

                }
                mainword.append(" ");
            }

剩下的就是我的代码。我应该提到我正在使用 Netbeans IDE 7.2 并且我使用 JLayeredPane 来显示所有内容,而不是 System.out.print。谢谢!

    import java.util.Random;
    import java.util.Scanner;
    import javax.swing.JOptionPane;

    public class MainFrame extends javax.swing.JFrame {

        public MainFrame() {
            initComponents();
        }

    //declare variables                      
    static String SecretWord = "";
    static String Letters = "";
    double Result = 0;
    String SetMain = null;
    StringBuilder mainword = new StringBuilder();
    StringBuilder gletters = new StringBuilder();
    boolean[] guesses = new boolean[26];
    String[] words = {"technology", "computer", "camera", "graphic design", "digital", "media", "technician", "photography", "troubleshoot", "pixels", "application", "download"};
    Random r = new Random();
    int randvalue = r.nextInt(11);
    String GuessWord = words[randvalue];


        private void GoButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
    mainword.append(SecretWord);
    //make word in underscore form
        for(int i = 0; i < GuessWord.length(); i++) { 
                if (guesses[GuessWord.charAt(i) - 'a']) { 
                    mainword.append(words[i].charAt(i));
                }
                else {
                    mainword.append("_");

                }
                mainword.append(" ");
            }

   //put in label
   SetMain = mainword.toString();
   WordLabel.setText(SetMain);
   GuessButton.setEnabled(true);
   GoButton.setEnabled(false);
}                           


private void GuessButtonActionPerformed(java.awt.event.ActionEvent evt) {                                      
    //declare variables      
    String strGuess = GuessText.getText();
    String SetMain = null;
    String GuessedLetters = null;
    Result = 1;//(int)(Math.random() * 11) + 1;
    int errors = 0;
    int i = 0;
    char guess2 = strGuess.charAt(i);
    gletters.append(Letters);

    //*******MAJOR PROBLEM AREA FOCUS HERE*******
    do{
        //replace underscore with guessed letter
        for(i = 0; i < GuessWord.length(); i++) { 
                if (GuessWord.charAt(i) == guess2) { 
                   mainword.replace(0,i,strGuess.toUpperCase()); 
                }
                else {
                    mainword.append("_");

                }
                mainword.append(" ");
            }

    //put in labels
    SetMain = mainword.toString();
    GuessedLetters = gletters.toString();
    WordLabel.setText(SetMain);
    GuessedLabel.setText(GuessedLetters);
    GuessText.setText(null);
    GuessText.requestFocusInWindow();
    }//end of do

while(SetMain == null);
if (SetMain.equalsIgnoreCase(GuessWord)){
    //show winning message to user and reset game
    JOptionPane.showMessageDialog(null, "Congrats!");
    GuessButton.setEnabled(false);
    GoButton.setEnabled(true);
    WordLabel.setText(null);
    GuessedLabel.setText(null);
    WinsLabel.setText("1");
}
//if too many errors show lost message
else if (errors >= 5){
    JOptionPane.showMessageDialog(null, "You Lost!");
    GuessButton.setEnabled(false);
    GoButton.setEnabled(true);
    WordLabel.setText(null);
    GuessedLabel.setText(null);
    LossesLabel.setText("1");
}
    }//end of 1GAME
}                                           

任何帮助都会很棒!请不要太复杂。我还在上面的代码中标记了我的主要问题区域。

【问题讨论】:

  • 向我们展示错误的整个堆栈跟踪。
  • 已更新。但这不是主要关注点
  • “这不是重点” ?!?你想解决这个错误吗?
  • 不符合什么逻辑?例外情况是告诉您那里某处的内存不足。您应该改进您的代码,因为它不清晰、缩进且结构正确,如果您按照 oracle.com 上的教程进行操作就应该如此。你的 cmets 是徒劳的,甚至对你来说也是如此。
  • 我认为您的问题之一是 GuessWord.indexOf(i) 可能不是您想要的 - 阅读 documentation of the String class - 我猜你真的想要 charAt()。教授不教授编码标准,甚至不教授基本的设计实践是怎么回事?

标签: java arrays char stringbuilder


【解决方案1】:

这是一种不同的方法。我们不会尝试用占位符替换未猜到的字母。在这里,我们记住到目前为止(在一组中)已经猜到的所有字母,并为每一轮重新创建秘密单词的“视图”。演示代码包含一个愚蠢的玩家,它只是随机猜测字母表中的所有字母。

public static void main(final String[] args) {

    String secretWord = "fibonacci";
    Set<Character> guessedLetters = new HashSet<>();

    // (1) create some test input (all letters randomized)
    List<Character> chars = new ArrayList<>();
    for (char c = 'a'; c <= 'z'; c++) {
        chars.add(c);
    }
    Collections.shuffle(chars);

    // (2) Let's guess
    for (char guessedLetter : chars) {
        // (3) memorize all letters that have been guessed
        guessedLetters.add(guessedLetter);

        // (4) print the display version of the secret word
        boolean guessedCompletely = true;
        System.out.print("My guess: [" + guessedLetter + "] -> ");
        for (char letterOfSecretWord : secretWord.toCharArray()) {
            if (guessedLetters.contains(letterOfSecretWord)) {
                // (4a) - we already guessed this letter
                System.out.print(letterOfSecretWord);
            } else {
                // (4b) - we haven't guessed it so far
                guessedCompletely = false;
                System.out.print('_');
            }
        }
        System.out.println();
        // (5) check, if the game is won
        if (guessedCompletely) {
            System.out.println("Yeah!");
            break;
        }
    }
}

【讨论】:

  • 是java 7。如果你不能用javac 7编译,只需将&lt;&gt;替换为&lt;Character&gt;
  • 好的,所以guessedletters 变量保存了所有的guessedletters,如果其中一个字母在秘密词中,那又如何呢?它取代了吗?例如单词 hello:如果猜到字母 e,“_ _ _ _ _”将变为“_ e _ _ _”
  • 编译,运行看看。不需要用占位符“替换”字符。诀窍是为每一轮重新创建秘密单词的“可见”部分(替换也会创建新字符串,顺便说一句)
  • 好的,我知道它是如何工作的,但是你如何将它从完全随机变为真正让人们猜测?
  • 将外部 for 循环替换为捕获用户输入的内容。就像一个带有一些代码的 do-while 循环来获取用户输入。或者采取“想法”并在您自己的代码中实现它:)
【解决方案2】:

我会尝试一种更简单的方法,在该方法中,您可以保存一组字符,您可以根据输入进行更改。这是对这个想法的总体描述:

char guess[] = {'_', '_', '_', '_', '_', ' ', '_', '_', '_', '_', '_'};
// It's "Hello World" :)
if(input == answer.getCharAt(inputIndex))
    guess[inputIndex] = answer.getCharAt(inputIndex); 
    //replace the underscore with the correct character
else
    //Add it to a list of used characters, ignore it or do as you've been asked to    

在您的情况下,通过调用 answer.toCharArray() 创建此 guess 数组,其中 answer 是具有正确单词的字符串。您需要使用replaceAll("[A-Za-z0-9]", "_") 将该字符串中的所有字符替换为下划线(请记住也要保留原始答案)。第一个参数是一个正则表达式,意思是“从 A 到 Z、从 a 到 z 和从 0 到 9 的所有字符组”,你需要检查一些 Regular Expressions 来习惯它们,并相信我,你迟早会用得上的。

然后,您只需在每次猜测正确时将guess[i] 替换为answer.getCharAt(i),避免了逐字符构建字符串的繁琐工作,这可能很棘手。

这是对另一种方法的简要描述,因为它是一个分配,您可以决定是否要尝试它,一般实施取决于您。我只是描述一个想法。

【讨论】:

  • 我需要为我的每一个字都做 char guess[] 吗?
  • inputIndex 只是一个决定猜测索引的变量。当您进行猜测时,您尝试的每个字符都与猜测词中的特定位置相关联。例如,如果您在第三个空格尝试AinputIndex 是 2(数组从 0 开始)。关于guess 数组,您可以拥有一个并将其分配给当前单词,例如guess = createGuessArray(word),其中createGuessArray 是一种替换下划线字符并返回“掩码”猜测词的方法,将其转换为带有@987654335 的char 数组@.
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 2023-04-03
  • 1970-01-01
  • 2020-12-22
相关资源
最近更新 更多