From 9ef01f8755c4cdcc4d0f8ece8543aeea6f5f1a50 Mon Sep 17 00:00:00 2001 From: Balint Balku Date: Mon, 13 Apr 2015 17:58:05 +0200 Subject: [PATCH] smarter hangman player --- src/main/java/com/hangman/HangmanRunner.java | 2 +- .../java/com/hangman/players/YourPlayer.java | 62 ++++++++++++++++++- .../com/hangman/players/YourPlayerTest.java | 45 ++++++++++---- 3 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/hangman/HangmanRunner.java b/src/main/java/com/hangman/HangmanRunner.java index 5b28717..fe07f82 100644 --- a/src/main/java/com/hangman/HangmanRunner.java +++ b/src/main/java/com/hangman/HangmanRunner.java @@ -43,7 +43,7 @@ public static void main(String [] args) throws Exception { HangmanRunner runner = new HangmanRunner(game, display, - new YourPlayer(), + new YourPlayer(WordList.words), new SleepTicker()); runner.run(); } diff --git a/src/main/java/com/hangman/players/YourPlayer.java b/src/main/java/com/hangman/players/YourPlayer.java index ddcfbd3..a89584b 100644 --- a/src/main/java/com/hangman/players/YourPlayer.java +++ b/src/main/java/com/hangman/players/YourPlayer.java @@ -1,13 +1,71 @@ package com.hangman.players; import com.hangman.Player; +import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedList; import java.util.List; +import java.util.regex.Pattern; + public class YourPlayer implements Player { + + private final List charsNotGuessedYet = new ArrayList<>(); + private final List charsAlreadyGuessed = new ArrayList<>(); + + private final List wordsList = new ArrayList<>(); + + + public YourPlayer(String[] wordsList) { + // initialize non-guessed characters + for (char c = 'a'; c <= 'z'; ++c) { + this.charsNotGuessedYet.add(c); + } + + // copy the word list + this.wordsList.addAll(Arrays.asList(wordsList)); + } + @Override public char GetGuess(List currentClue) { - return 'a'; + Character guess = null; + + StringBuilder pattern = new StringBuilder(currentClue.size()); + int nextYetUnknownCharacterIndex = 0; + int i = 0; + for (Character c : currentClue) { + if (c.equals('_')) { + nextYetUnknownCharacterIndex = i; + pattern.append("."); + } else { + // known character, act like if it was already guessed + this.charsNotGuessedYet.remove(c); + this.charsAlreadyGuessed.add(c); + pattern.append(c); + } + ++i; + } + Pattern wordPattern = Pattern.compile(pattern.toString()); + + for (String word : this.wordsList) { + if ((word.length() == currentClue.size()) && wordPattern.matcher(word).matches()) { + guess = word.charAt(nextYetUnknownCharacterIndex); + if (!this.charsAlreadyGuessed.contains(guess)) { + break; + } + } + } + + if (guess == null) { + // no word matching, just get the next not-yet-guessed character + guess = this.charsNotGuessedYet.isEmpty() ? + 'a' : + this.charsNotGuessedYet.get(0); + } + + // store char as already guessed + this.charsNotGuessedYet.remove(guess); + this.charsAlreadyGuessed.add(guess); + return guess; } + } diff --git a/src/test/java/com/hangman/players/YourPlayerTest.java b/src/test/java/com/hangman/players/YourPlayerTest.java index d613f6b..80e57c0 100644 --- a/src/test/java/com/hangman/players/YourPlayerTest.java +++ b/src/test/java/com/hangman/players/YourPlayerTest.java @@ -1,34 +1,57 @@ package com.hangman.players; import org.junit.Test; + import java.util.Arrays; + import static org.junit.Assert.assertEquals; public class YourPlayerTest { + + private static final String[] wordsForTest = { + "abc", + "acc", + "something_longer", + "somethingshorter" + }; + + @Test - public void GuessesAWhenThereAreNoSuccessfulCharactersGuessedYet() { - YourPlayer player = new YourPlayer(); + public void GuessesWhenThereAreNoSuccessfulCharactersGuessedYet() { + YourPlayer player = new YourPlayer(wordsForTest); - char guess = player.GetGuess(Arrays.asList('_', '_', '_')); + // last character of the first 3 chars long word + char shortGuess = player.GetGuess(Arrays.asList('_', '_', '_')); + assertEquals('c', shortGuess); - assertEquals('a', guess); + // last character of the first 16 chars long word + char longGuess = player.GetGuess(Arrays.asList('_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_')); + assertEquals('r', longGuess); } @Test - public void GuessesAWhenThereAreSuccessfulCharactersGuessedThatAreNotA() { - YourPlayer player = new YourPlayer(); + public void GuessesWhenThereAreSuccessfulCharactersGuessedAndThereIsNoMatchingKnownWord() { + YourPlayer player = new YourPlayer(wordsForTest); - char guess = player.GetGuess(Arrays.asList('m', '_', 'n')); + char guess1 = player.GetGuess(Arrays.asList('m', '_', 'n')); + assertEquals('a', guess1); + } - assertEquals('a', guess); + @Test + public void GuessesWhenThereAreSuccessfulCharactersGuessedAndThereIsAMatchingKnownWord() { + YourPlayer player = new YourPlayer(wordsForTest); + + char guess2 = player.GetGuess(Arrays.asList('a', '_', 'b')); + assertEquals('c', guess2); } @Test - public void GuessesAWhenAIsThereAreAsInTheClueAsWell() { - YourPlayer player = new YourPlayer(); + public void GuessesFirstCharacterOfACompleteClue() { + YourPlayer player = new YourPlayer(wordsForTest); - char guess = player.GetGuess(Arrays.asList('_', 'a', '_')); + char guess = player.GetGuess(Arrays.asList('a', 'b', 'c')); assertEquals('a', guess); } + }