diff --git a/src/main/java/com/hangman/players/YourPlayer.java b/src/main/java/com/hangman/players/YourPlayer.java index f537169..8c81abd 100644 --- a/src/main/java/com/hangman/players/YourPlayer.java +++ b/src/main/java/com/hangman/players/YourPlayer.java @@ -1,13 +1,165 @@ package com.hangman.players; import com.hangman.Player; +import com.hangman.WordList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; +import java.util.*; public class YourPlayer implements Player { + private boolean hasOneRightGuess; + List attemptedCharacters; + char[] frequentUsedChars = "etaoinshrdlcumwfgypbvkjxqz".toCharArray(); + int index; + private char lastCharGuessed; + private String lastClue; + private boolean lastAttemptResult; + public static final boolean RIGHT_GUESS = true; + public static final boolean WRONG_GUESS = false; + private String[] words; + + public YourPlayer () { + attemptedCharacters = new ArrayList(); + index = 0; + hasOneRightGuess = false; + words = WordList.words.clone(); + for (int i=0; i < words.length; i++) { + words[i] = words[i].toLowerCase(); + } + + } + + public static List getWordMatchingLength(String[] words, int length) { + List matchingStrings = new ArrayList(); + for(String word : words) { + if ( word.length() == length ) { + matchingStrings.add(word); + } + } + return matchingStrings; + } + + @Override public char GetGuess(List clue) { - return 'a'; + + StringBuilder sb = new StringBuilder(clue.size()); + for (Character c : clue) + sb.append(c); + String clueAsString = sb.toString(); + + if (clueAsString.equals(lastClue) || lastClue == null) { + lastAttemptResult = WRONG_GUESS; + } + else { + lastAttemptResult = RIGHT_GUESS; + hasOneRightGuess = true; + } + + List wordList = YourPlayer.getWordMatchingLength(words,clue.size()); + words = new String[wordList.size()]; + words = wordList.toArray(words); + + + + wordList = YourPlayer.getWordMatchingPattern(words,clue); + words = new String[wordList.size()]; + words = wordList.toArray(words); + + + if(getLastAttemptResult() == WRONG_GUESS) { + wordList = YourPlayer.getWordsWithoutChars(words, getLastCharGuessed()); + words = new String[wordList.size()]; + words = wordList.toArray(words); + + } + + + + + if(words.length > 0 ) { + lastCharGuessed = getMostFrequentChar(words, attemptedCharacters); + } + else{ + while(attemptedCharacters.contains(frequentUsedChars[index])){ + index++; + } + lastCharGuessed = frequentUsedChars[index++]; + } + attemptedCharacters.add(lastCharGuessed); + lastClue = clueAsString; + return lastCharGuessed; } + + + public static List getWordMatchingPattern(String[] words, List pattern) { + List matchingStrings = new ArrayList(Arrays.asList(words)); + for(int index=0; index < pattern.size(); index++) { + if(pattern.get(index) == '_') { + continue; + } + for(String word : words) { + if(word.charAt(index) != pattern.get(index)) { + matchingStrings.remove(word); + continue; + } + } + } + return matchingStrings; + } + + public static List getWordsWithoutChars(String[] words, char chars) { + List matchingStrings = new ArrayList(Arrays.asList(words)); + + for(String word: words) { + if ( word.indexOf(chars) != -1) { + matchingStrings.remove(word); + continue; + } + } + + return matchingStrings; + } + + public char getLastCharGuessed() { + return lastCharGuessed; + } + + public boolean getLastAttemptResult() { + return lastAttemptResult; + } + + public boolean hasOneRightGuess() { + return hasOneRightGuess; + } + + public static char getMostFrequentChar(String[] words, List attemptedCharacters) { + Map counter = new HashMap(); + + for(String word : words) { + for(char character: word.toCharArray()) { + try { + counter.get(character); + if ( counter.get(character) == null ) { + counter.put(character,0); + } + } + catch (Exception e){ + counter.put(character, 0); + } + + counter.put(character, counter.get(character) + 1); + } + } + + char highest = 'a'; + int highest_count = 0; + for(Character character: counter.keySet()) { + if(counter.get(character) > highest_count ) { + if(attemptedCharacters.indexOf(character) == -1 ) { + highest = character; + highest_count = counter.get(character); + } + } + } + return highest; + } } diff --git a/src/test/java/com/hangman/players/YourPlayerTest.java b/src/test/java/com/hangman/players/YourPlayerTest.java index bc92a3b..1b00a03 100644 --- a/src/test/java/com/hangman/players/YourPlayerTest.java +++ b/src/test/java/com/hangman/players/YourPlayerTest.java @@ -2,15 +2,73 @@ import org.junit.Test; import java.util.Arrays; +import java.util.List; + +import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; public class YourPlayerTest { + + @Test + public void testCanGetWordsThatMatchLengthSpecified() throws Exception { + String[] words = {"aboard", "accident"}; + List matches = YourPlayer.getWordMatchingLength(words, 6); + assertTrue(matches.contains("aboard")); + assertFalse(matches.contains("accident")); + } + + @Test + public void testCanExcludeWordsThatContainMissedChar() throws Exception { + String[] words = {"aboard", "actual", "active"}; + List matches = YourPlayer.getWordsWithoutChars(words, 'b'); + assertTrue(matches.contains("actual")); + assertFalse(matches.contains("aboard")); + } + + @Test + public void testGivenAPartialMatchedStringFilterOutWordsThatDoNotQualify() throws Exception { + String[] words = {"aboard", "actual", "active"}; + List matches = YourPlayer.getWordMatchingPattern(words, Arrays.asList('_', 'c', '_', '_', '_', '_')); + + assertTrue(matches.contains("actual")); + assertFalse(matches.contains("aboard")); + } + @Test - public void AlwaysGuessA() { + public void testLastGuessedCharIsReturned() throws Exception { YourPlayer player = new YourPlayer(); + char first = player.GetGuess(Arrays.asList('e', 'b', 'c')); + assertEquals(first, player.getLastCharGuessed()); + } + + @Test + public void testCanGetCorrectLastGuessResult() throws Exception { + YourPlayer player = new YourPlayer(); + char first = player.GetGuess(Arrays.asList('_', '_', '_')); + char second = player.GetGuess(Arrays.asList('_', 'e', '_')); + assertEquals(YourPlayer.RIGHT_GUESS, player.getLastAttemptResult()); + char third = player.GetGuess(Arrays.asList('_', 'e', '_')); + assertEquals(YourPlayer.WRONG_GUESS, player.getLastAttemptResult()); + } + + @Test + public void testCanCheckIfWeHaveMadeAtLeastOneRightGuess() throws Exception { + YourPlayer player = new YourPlayer(); + char first = player.GetGuess(Arrays.asList('_', '_', '_')); + assertFalse(player.hasOneRightGuess()); + char second = player.GetGuess(Arrays.asList('_', '_', '_')); + assertFalse(player.hasOneRightGuess()); + char third = player.GetGuess(Arrays.asList('_', 'e', '_')); + assertTrue(player.hasOneRightGuess()); + } + + @Test + public void testCanGetTheMostFrequentAppearingCharInWordList() throws Exception { - char guess = player.GetGuess(Arrays.asList('a', 'b', 'c')); + String[] words = {"aboard", "actual", "active"}; - assertEquals('a', guess); + char mostFrequent = YourPlayer.getMostFrequentChar(words, Arrays.asList('f', 'u', 't')); + assertEquals('a', mostFrequent); } }