【问题标题】:How to populate an array (like hangman) based on a guess如何根据猜测填充数组(如hangman)
【发布时间】:2018-04-16 15:59:26
【问题描述】:

我要做的是获取一个隐藏的字符串,然后在用户每次按下提示按钮时以随机顺序逐个字母地显示它。目前,每次按下提示按钮时,整个解决方案都会针对解决方案的每个字符显示一次。

我正在尝试这样做,以便在按下提示按钮时,字符串解决方案中的随机字符会出现在正确的位置。我不确定如何将生成字符的位置与字符串位置进行比较。

  public String letterGenerator(int count, String word) {
//String word is taken from another function and it is based on the current displayed card and associated answer
    StringBuilder string = new StringBuilder();
    Random rng = new Random();

    char[] letters = word.toCharArray();
    char[] answers = new char[letters.length];

   int selected = rng.nextInt(letters.length);

    for (int i = 0; i < word.length(); i++) {
        if (i == selected) {
                letters[i] = answers[i];
            }
        string.append(letters);
    }
    return string.toString();
}

例如,如果答案是“钱包”,则此代码将解决方案输出为“a walleta walleta walleta walleta walleta walleta walleta walleta”(它显示输出 8 次,因为它会为每个字符打印一次解决方案,包括空格)

每次按下提示按钮时应该做的是以随机顺序显示每个字符,如下所示: 按 1:“_ _ _ l_ _ _” 按 2:“一个 _ _ l_ _ _” 按 3:“a _ _ l _e _”,依此类推,直到整个单词出现在屏幕上

感谢任何帮助!

【问题讨论】:

    标签: java


    【解决方案1】:

    好吧,你 append(letters) 到你的循环的每次迭代的输出,letters 是一个数组所有你的字母,而不仅仅是其中一个。所以当然你最终会得到你得到的输出。

    但我认为你可以用更优雅、更面向对象的方式来设计它。而不是两个字符数组的答案和显示的内容,也许只制作一个“字母”数组。这意味着您创建一个自定义class Letter,它可以保存信息,无论它是否“已解决”。像这样:

    public class Letter{
       char character;
       boolean solved;
       // ... Constructor, Getters, Setters
    }
    

    然后,您可以将您的字母数组传递给一个选择尚未解决的随机字母的方法,并将其solved 属性切换为true。您用于向用户显示内容的代码将如下所示:

    for(Letter letter : letterArray){
       System.out.print(letter.isSolved() ? letter.getCharacter() : "_");
    }
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,那么这里有几件事要改变;

      1) 您想记住最后显示的提示,但您已将其存储在局部变量中。 您需要一种方法来存储显示的字母。你如何做到这一点取决于你的类的其余部分是如何设置的,但是要么将它作为方法返回的一部分传回,要么设置一个全局变量应该这样做

      2) 由于您还记得之前的提示,因此您需要确保之前没有显示“已选择”。也许存储之前显示的字母位置并与它们进行比较。

      3)我会把循环的内部更多地放在

      for (int i = 0; i < word.length(); i++) {
          if(i == selected){
              string.append(letters[i]);
          }else{
              string.append("_");
          }
      }
      

      希望对你有帮助

      编辑: 我已经更改了 for 循环,现在它应该可以按您的意愿工作了。抱歉,我一开始应该更加小心。

      至于存储之前显示的字母,如果您使用的是 Singleton 类,则可以将此值存储在另一个列表中。我的建议是保留一个显示值的 ArrayList,然后执行类似的操作;

      List<Integer> revealed = new ArrayList<>();
      Random rng = new Random();
      
      public int getNextSelected(int length){
          int selected = rng.nextInt(length);
          if(revealed.contains(selected)){
              return getNextSelected(length);
          }
          return selected;
      }
      
      public String letterGenerator(int count, String word) {
          ...
          int selected = getNextSelected(letters.length);
          for (int i = 0; i < word.length(); i++) {
              if (i == selected){
                  string.append(letters[i]);
              } else if (revealed.contains(i)) {
                  string.append(letters[i]);
              } else{
                  string.append("_");
              }
          }
          revealed.add(selected);
          return string.toString();
      }
      

      这应该可以满足您的需要。清理代码的方法有很多,user3237736 的建议非常好,因为它遵循“告诉不问”的原则,但类的设计决定取决于你

      【讨论】:

      • 我将我的 for 循环更改为您建议的内容,它仍然为我提供了每个字符的完整解决方案。至于您的其他观点,存储先前显示的字母的最有效方法是什么,因为我尝试使用基本计数器并从一开始就逐个字母地遍历解决方案(并将其更改为随机遍历解决方案而是)?
      【解决方案3】:
      public class SOEN_student {
      public static void letterGenerator(String word) {
          //String word is taken from another function and 
          //it is based on the current displayed card and associated answer
              StringBuilder string;
              Random rng = new Random();
              char[] letters = word.toCharArray();
              char[] answers = new char[letters.length];
              boolean[] visited=new boolean[letters.length];
              int selected;
              for (int i = 0; i < word.length(); i++) {
                  do{
                      selected=rng.nextInt(letters.length);
                  }while(visited[selected]);
                  string=new StringBuilder();
                  for(int j=0;j<word.length();j++){
                      if(visited[j] | j==selected){
                          visited[selected]=true; 
                          string.append(letters[j]);
                      }else{
                          string.append("_");
                      }
                  }
                  System.out.print(string.toString()+" ");
              }
          }
      public static void main(String... args){
              letterGenerator("a wallet");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-25
        • 2015-10-16
        • 2015-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多