This repository has been archived on 2026-03-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
CSE-122/absurdle/Absurdle.java
2026-03-18 00:39:22 -07:00

233 lines
7.9 KiB
Java

// Nik Johnson
// 2-11-2024
// TA: Andy Ruan
/*
absurd wordle-like game
instead of guessing one word, prolongs game as long as possible by
testing users guess against every word in selected dictionary, and
choosing the largest set of words associated with a possible pattern
for the users guess. the game only ends when the next set to be
considered is narrowed down to one, and the user guesses it.
*/
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);
guessedPatterns.add(pattern);
System.out.println(": " + pattern);
System.out.println();
}
System.out.println("Absurdle " + guessedPatterns.size() + "/∞");
System.out.println();
printPatterns(guessedPatterns);
console.close();
}
// [[ 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;
}
/*
look through list of words from dictionary, removing words that aren't of
the user specified length.
takes list of words from user specified dictionary, and user specified word length
return set of words pruned according to user input
if the user specified length is less than one, throw IllegalArgumentException
*/
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;
}
/*
evaluate users guess, looking for the largest set of words that have the pattern
of the guess. if all possible patterns have the same number of words, pick the
first one in alphabetical order.
takes users guess, set of words determined by pruneDictionary, and length of users guess
return the pattern associated with the largest set of words
if the users guess is the wrong length, or there is no words to be guessed,
throw IllegalArgumentException
*/
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<>();
for (String word : words) {
String nextPattern = patternFor(word, guess);
if (!wordMap.containsKey(nextPattern)) {
wordMap.put(nextPattern, new HashSet<String>());
}
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;
}
/*
helper method for record, removes words from next considered set that arent in
the largest set determined in record
takes next set of words to be considered as determined by record,
which will be used to trim the previous set
no return
*/
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();
}
}
}
/*
produce pattern for users guess against every word in set of
considered words.
takes users guess, and the word to generate a pattern against
return pattern of colored squares for use in record
*/
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;
}
}