Java / javaFX Hangman帮助倒数错过的尝试

时间:2016-01-21 17:13:06

标签: java javafx javafx-8

所有Stackoverflowers都好。我是Java和编程的新手,这是我在StackOverflow上的第一个问题所以请原谅我可能写的任何错误或愚蠢的代码。

我在Java / JavaFX中制作一个Hangman游戏。 到目前为止,我已经能够阅读并随机从文本文件中选择一个单词。用'%'替换单词的每个字符,然后检查隐藏单词中是否存在输入的字母,并用正确的字母替换'%'符号。

基本上游戏的工作不仅仅是计算错误的数量,而且当你犯了一定数量的错误时,你就失败了。

让我们从这里开始: 我有一个从文件中生成随机单词的类。 然后将该单词返回到另一个类,该方法将所有字符替换为'%'

private loadWord LW = new loadWord();   
private String unGuessedWord;
private String correctWord;
private StringBuffer sb;

public String replaceWord(){
    correctWord = LW.readWords();

    char pos[] = new char[correctWord.length()];
    for(int i = 0; i < correctWord.length(); i++){
        pos[i] += '%';
    }
    unGuessedWord = new String(pos);
    return unGuessedWord;
}

此方法现在已将“correctWord”中的每个字母都变为'%'。

下一个方法将检查播放器猜到的字母是否在“correctWord”中,如果是,则在正确的位置显示正确的字母:

    public String letterMatch(char guess){

    sb = new StringBuffer(unGuessedWord);

    for (int i = 0; i < correctWord.length(); i++) {
        if(correctWord.charAt(i) == guess){
            sb.setCharAt(i, guess);
        }
    }
    unGuessedWord = new String(sb);
    return unGuessedWord;
}

按预期工作。让我只展示“FX”部分:

play.setOnAction(e->{
        gE = new GenerateWord();
        hiddenText.setText(gE.randomWord());
        play.setText("RESTART");
        guesses.clear();
    });

这是一个Button,当按下时会生成并将“unGuessedWord”显示为'%'符号。

playerField.setOnAction(e->{
        hiddenText.setText(gE.letterMatch(guessField.getText().charAt(0)).toUpperCase());
        }
    });

“playerField”是javaFX中的普通TextField,用户可以在其中输入文本。 “hiddentext”是一个Text,它是要猜的单词,它只显示'%',直到猜到正确的字母。

我需要帮助的是计算用户所犯的错误/错误猜测量,以及例如6个错误的字母后游戏结束。并且对于每个错误,画出“男人”的身体部分。

(我怎么在脑海中看到它):

int lives = 6;
int dead = 0;
//some code
lives--;
if(lives == dead);
//end game

我被困在这里,我不知道该做什么,我尝试的任何工作或不按预期工作..请帮助我在这里。 对于我在这个问题上犯的任何错误,或者我的代码只是简单可怕,我道歉。

2 个答案:

答案 0 :(得分:1)

JavaFX提供observable properties and collections以及相关的绑定API,用于管理JavaFX UI中显示的数据。因此,虽然您可以使用您拥有的代码类型来制作游戏,但更惯用的方法是创建一个&#34;模型&#34;表示游戏状态的类,使用这些类。

所以你可能会想到写一个这样的课:

public class HangmanGameState {

    private final StringProperty word = new SimpleStringProperty();

    public StringProperty wordProperty() {
        return word ;
    }

    public final String getWord() {
        return wordProperty().get();
    }

    public final void setWord(String word) {
        wordProperty().set(word);
    }

    private final ObservableList<Character> guesses = FXCollections.observableArrayList();

    public ObservableList<Character> getGuesses() {
        return guesses ;
    }


    // this value determined by wordProperty() and guesses, 
    // so we make it "read only":
    private final ReadOnlyIntegerWrapper wrongGuesses = new ReadOnlyIntegerWrapper();

    public final ReadOnlyIntegerProperty wrongGuessesProperty() {
        return wrongGuesses.getReadOnlyProperty();
    }

    public final int getWrongGuesses() {
        return wrongGuessesProperty().get();
    }

    public HangmanGameState() {

        // bind wrong guesses to other object state:
        wrongGuesses.bind(Bindings.createIntegerBinding(() -> 
            (int) guesses.stream()
                .map(c -> c.toString())
                .filter(word.get::contains)
                .count(),
            guesses, word);

    }

    public void restartGame(String newWord) {
        guesses.clear();
        word.set(newWord);
    }
}

(作为&#34;读者练习&#34;,您可以创建ReadOnlyBooleanWrapper wordGuessedword绑定的guesses。)

现在,您可以在用户界面中执行以下操作:

HangmanGameState game = new HangmanGameState();
Label wordLabel = new Label();

wordLabel.textProperty().bind(Bindings.createStringBinding(() -> {
    StringBuilder text = new StringBuilder();
    for (char c : game.getWord().toCharArray()) {
        if (game.getGuesses().contains(new Character(c))) {
            text.append(c) ;
        } else {
            text.append('%');
        }
    }
    return text.toString();
}, game.wordProperty(), game.getGuesses());

TextField guessField = new TextField();
guessField.setOnAction(e -> {
    if (guessField.getText().length > 0) {
        game.getGuesses().add(guessField.getText().charAt(0));
    }
});



IntegerProperty livesRemaining = new SimpleIntegerProperty();
final int totalLives = 6 ;
livesRemaining.bind(games.wrongGuessesProperty().multiply(-1).add(totalLives));

Label livesRemainingLabel = new Label();
livesRemainingLabel.textProperty().bind(livesRemaining.asString("Lives Remaining: %d"));
livesRemaining.addListener((obs, oldValue, newValue) -. {
    if (newValue.intValue() <= 0) {
       // show "You lose, play again?" alert...
    }
});

这只是输入,所以可能有拼写错误等,但它应该让你知道如何在JavaFX中构建它。

答案 1 :(得分:0)

您已经有一个方法( letterMatch()方法),它检查提供的字符是否在正确的单词中。这有效,但在同一方法中,您实际上也知道提供的字母不起作用。在检查了正确单词中的所有字符后,您需要保留该事实并对其进行操作。

您需要假设在方法开头的 letterMatch()方法的guess参数中提供的任何Character参数都是错误的。为此,请建立布尔变量(我们将其命名为: letterCorrect )并将其初始化为 false

boolean letterCorrect = false;

现在我们假设无论提供什么,都是错误的。我们需要证明它是正确的,这就是 for-loop 发挥作用的地方。当 for-loop 迭代正确的Word并检查提供的字符时,我们确定字符是否正确,如果是,那么我们的假设是错误的,因此我们设置 letterCorrect 变量 true 。我们还希望此时 中断 退出 for-loop (稍后会详细介绍)。所以我们的 for-loop 应如下所示:

boolean letterCorrect = false;  // Assume the supplied character is wrong.
for (int i = 0; i < correctWord.length(); i++) {
    if(correctWord.charAt(i) == guess) {
        // The supplied character is Correct!
        sb.setCharAt(i, guess);
        letterCorrect = true;  //change our assumption to true.
        break;  
    }
}

在我们使用提供的字符检查了正确单词中的所有字符之后,它是我们的布尔 letterCorrect 变量,它很快告诉我们提供的猜测字符是否正确< / em>或错误。那么,我们检查它的状况,是 true 还是 false ?:

if (!letterCorrect) { 
    lives--; 
    if(lives == dead) {
        System.out.println("YOUR DEAD!");
        //end the game code or Method call here...
    }
}

如果它是正确的字符,那么我们只是以快乐的方式继续,并让代码在 letterMatch()方法中完成。但是,如果我们的初始假设是正确的并且提供的字符确实错误那么我们的假设不会改变,我们的布尔 letterCorrect 变量仍然是 false 如果它是 false ,那么我们会减少全局声明的生命整数变量。我们还会快速检查生命是否已达到死亡,但如果已经退出游戏。

现在,您注意到我们在 for-loop 中使用了 break; 语句。我们实际上需要这个,以防有正确的单词,其中包含两个或多个相同的字符。例如,使用循环一词,如果用户提供的字符为“ o ”,这是一个正确的字符, letterMatch()方法会在单个调用方法中处理单词循环(loo)中的 o ,这将是第四个字符可能是什么的赠品。通过在 for-loop 中放置 break; 语句,我们确保用户必须提供正确Word的每个字符,无论其中有多少相同的字符正确的话语。

以下是完整的 letterMatch()方法:

public String letterMatch(char guess){
    sb = new StringBuffer(unGuessedWord);
    boolean letterCorrect = false;
    for (int i = 0; i < correctWord.length(); i++) {
        if(correctWord.charAt(i) == guess){
            sb.setCharAt(i, guess);
            letterCorrect= true;
            break;  
        }
    }
    if (!letterCorrect) { 
        lives--; 
        if(lives == dead) {
            System.out.println("YOUR DEAD!");
            //end the game code or method call here...
        }
    }
    unGuessedWord = new String(sb);
    return unGuessedWord;
}

作为旁注,您可能还想要照顾Upper&amp;低写字母。