189 lines
6.4 KiB
Java
189 lines
6.4 KiB
Java
// Nik Johnson
|
|
// 2-11-2024
|
|
// TA: Andy Ruan
|
|
|
|
// TODO: Write your class comment here!
|
|
|
|
import java.util.*;
|
|
import java.io.*;
|
|
|
|
public class Absurdle {
|
|
public static final String GREEN = "🟩";
|
|
public static final String YELLOW = "🟨";
|
|
public static final String GRAY = "⬜";
|
|
|
|
// [[ ALL OF MAIN PROVIDED ]]
|
|
public static void main(String[] args) throws FileNotFoundException {
|
|
Scanner console = new Scanner(System.in);
|
|
System.out.println("Welcome to the game of Absurdle.");
|
|
|
|
System.out.print("What dictionary would you like to use? ");
|
|
String dictName = console.next();
|
|
|
|
System.out.print("What length word would you like to guess? ");
|
|
int wordLength = console.nextInt();
|
|
|
|
List<String> contents = loadFile(new Scanner(new File(dictName)));
|
|
Set<String> words = pruneDictionary(contents, wordLength);
|
|
|
|
List<String> guessedPatterns = new ArrayList<>();
|
|
while (!isFinished(guessedPatterns)) {
|
|
System.out.print("> ");
|
|
String guess = console.next();
|
|
String pattern = record(guess, words, wordLength);
|
|
System.out.println(words);
|
|
guessedPatterns.add(pattern);
|
|
System.out.println(": " + pattern);
|
|
System.out.println();
|
|
}
|
|
System.out.println("Absurdle " + guessedPatterns.size() + "/∞");
|
|
System.out.println();
|
|
printPatterns(guessedPatterns);
|
|
}
|
|
|
|
// [[ PROVIDED ]]
|
|
// Prints out the given list of patterns.
|
|
// - List<String> patterns: list of patterns from the game
|
|
public static void printPatterns(List<String> patterns) {
|
|
for (String pattern : patterns) {
|
|
System.out.println(pattern);
|
|
}
|
|
}
|
|
|
|
// [[ PROVIDED ]]
|
|
// Returns true if the game is finished, meaning the user guessed the word. Returns
|
|
// false otherwise.
|
|
// - List<String> patterns: list of patterns from the game
|
|
public static boolean isFinished(List<String> patterns) {
|
|
if (patterns.isEmpty()) {
|
|
return false;
|
|
}
|
|
String lastPattern = patterns.get(patterns.size() - 1);
|
|
return !lastPattern.contains("⬜") && !lastPattern.contains("🟨");
|
|
}
|
|
|
|
// [[ PROVIDED ]]
|
|
// Loads the contents of a given file Scanner into a List<String> and returns it.
|
|
// - Scanner dictScan: contains file contents
|
|
public static List<String> loadFile(Scanner dictScan) {
|
|
List<String> contents = new ArrayList<>();
|
|
while (dictScan.hasNext()) {
|
|
contents.add(dictScan.next());
|
|
}
|
|
return contents;
|
|
}
|
|
|
|
public static Set<String> pruneDictionary(List<String> contents, int wordLength) {
|
|
if (wordLength < 1) throw new IllegalArgumentException();
|
|
Set<String> prunedDict = new HashSet<>();
|
|
for (String word : contents) {
|
|
if (word.length() == wordLength) {
|
|
prunedDict.add(word);
|
|
}
|
|
}
|
|
return prunedDict;
|
|
}
|
|
|
|
public static String record(String guess, Set<String> words, int wordLength) {
|
|
if (guess.length() != wordLength || words.isEmpty()) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
Map<String, Set<String>> wordMap = new TreeMap<>();
|
|
Iterator<String> iter = words.iterator();
|
|
while (iter.hasNext()) {
|
|
String word = iter.next();
|
|
String nextPattern = patternFor(word, guess);
|
|
if (!wordMap.containsKey(nextPattern)) {
|
|
wordMap.put(nextPattern, new HashSet<String>());
|
|
// iter.remove();
|
|
}
|
|
wordMap.get(nextPattern).add(word);
|
|
}
|
|
|
|
Boolean allSameSize = true;
|
|
int setSize1 = 0;
|
|
|
|
for (String pattern : wordMap.keySet()) {
|
|
int size = wordMap.get(pattern).size();
|
|
if (setSize1 == 0) setSize1 = size;
|
|
if (setSize1 != size) allSameSize = false;
|
|
}
|
|
|
|
if (allSameSize) {
|
|
for (String pattern : wordMap.keySet()) {
|
|
removeAllNonMatching(words, wordMap.get(pattern));
|
|
return pattern;
|
|
}
|
|
}
|
|
|
|
String pattern = "";
|
|
int setSize = 0;
|
|
for (String word : wordMap.keySet()) {
|
|
int nextSetSize = (wordMap.get(word)).size();
|
|
if (nextSetSize > setSize) {
|
|
setSize = nextSetSize;
|
|
pattern = word;
|
|
}
|
|
}
|
|
removeAllNonMatching(words, wordMap.get(pattern));
|
|
return pattern;
|
|
}
|
|
|
|
public static void removeAllNonMatching(Set<String> words, Set<String> match) {
|
|
Iterator<String> iter = words.iterator();
|
|
while(iter.hasNext()) {
|
|
if(!match.contains(iter.next())) {
|
|
iter.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static String patternFor(String word, String guess) {
|
|
List<String> splitGuess = new ArrayList<>();
|
|
String pattern = new String();
|
|
for (int i = 0;i < guess.length(); i++) {
|
|
String nextChar = Character.toString(guess.charAt(i));
|
|
splitGuess.add(nextChar);
|
|
}
|
|
|
|
Map<Character, Integer> wordMap = new HashMap<>();
|
|
for (int j = 0; j < word.length(); j++) {
|
|
char wordChar = word.charAt(j);
|
|
if (!wordMap.containsKey(wordChar)) {
|
|
wordMap.put(wordChar, 1);
|
|
} else {
|
|
wordMap.put(wordChar, (wordMap.get(wordChar) + 1));
|
|
}
|
|
}
|
|
|
|
for (int n = 0; n < splitGuess.size(); n++) {
|
|
if ((Character.toString(word.charAt(n))).equals(splitGuess.get(n))) {
|
|
int currCount = wordMap.get((splitGuess.get(n)).charAt(0));
|
|
wordMap.put(word.charAt(n), (currCount - 1));
|
|
splitGuess.set(n, GREEN);
|
|
}
|
|
}
|
|
|
|
for (int n = 0; n < splitGuess.size(); n++) {
|
|
char charToCheck = (splitGuess.get(n)).charAt(0);
|
|
if ((wordMap.keySet()).contains(charToCheck)
|
|
&& wordMap.get(charToCheck) != 0) {
|
|
int currCount2 = wordMap.get(charToCheck);
|
|
wordMap.put(charToCheck, (currCount2 - 1));
|
|
splitGuess.set(n, YELLOW);
|
|
}
|
|
}
|
|
|
|
for (int n = 0; n < splitGuess.size(); n++) {
|
|
if ((splitGuess.get(n)).length() == 1) {
|
|
splitGuess.set(n, GRAY);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < splitGuess.size(); i++) {
|
|
pattern += splitGuess.get(i);
|
|
}
|
|
return pattern;
|
|
}
|
|
}
|