#ifndef ORDLE_H #define ORDLE_H #include #include #include #include #include #include // TODO: Evaluate need for helpers // Helper types and aliases using size_type = std::string::size_type; /** * @brief A mapping of indices to letters or strings. * * This type alias represents a map where each key is a position (index), and * the value is a string (typically a single letter). It is used to track the * correct or misplaced letter positions in word-guessing games, like Wordle, or * similar puzzles. * * @note The `std::map` ensures that the indices are stored in sorted order, * which is useful for efficiently checking conditions related to the positions * of letters within words. * * @see correct_fn, misplaced_fn, build_list */ using IndexMap = std::map; /** * Reads a list of words from an input stream where each word is separated by a * newline. * * @param input The input stream containing newline-separated words. * @return A vector containing all the words from the input stream. */ std::vector read_candidates(std::istream &input); /** * Checks if a string contains any character from a given set of characters. * * @param s The string to search within. * @param cs A string containing the set of characters to look for. * @return true if any character in 'cs' is found in 's'; otherwise, false. */ inline bool contains_any_of(const std::string &s, const std::string &cs) { return std::any_of(cs.begin(), cs.end(), [&s](char c) { return s.find(c) != std::string::npos; }); } /** * Checks if a string contains a specific character at a given position. * * @param s The string to search within. * @param c The character to check for. * @param pos The position to check within the string. * @return true if the character 'c' is found at position 'pos' in the string * 's'; otherwise, false. */ inline bool contains_at(const std::string &s, char c, size_type pos) { return pos < s.size() && s[pos] == c; } /** * Checks if a string contains a specific character, but not at a given * position. * * @param s The string to search within. * @param c The character to check for. * @param pos The position where the character must not be located. * @return true if the character 'c' is found in the string 's' and not at * position 'pos'; otherwise, false. */ inline bool contains_but_not_at(const std::string &s, char c, size_type pos) { for (size_type i = 0; i < s.size(); ++i) { if (s[i] == c && i != pos) { return true; // Found letter but not at the correct position } } return false; // Letter not found or in the correct index } /** * A functor to filter words containing any of the specified letters. */ struct wrong_fn { /** * Constructs a functor with the specified letters to filter against. * * @param letters A string containing the letters that words should not * contain. */ wrong_fn(const std::string &letters) : letter_set{letters} {} /** * Checks if a word contains any of the specified "wrong" letters. * * @param word The word to be checked. * @return True if the word contains any "wrong" letters; false otherwise. */ bool operator()(const std::string &word) const; private: std::string letter_set; ///< The letters considered "wrong". }; /** * A functor to filter words based on exact character positions. */ struct correct_fn { /** * Constructs a functor with the specified indices and characters. * * @param idxs A map of indices to characters representing the exact * matches. */ correct_fn(const IndexMap &idxs) : map{idxs} {} /** * Checks if a word contains the correct characters at the specified * indices. * * @param word The word to be checked. * @return True if the word matches the correct indices; false otherwise. */ bool operator()(const std::string &word) const; private: IndexMap map; ///< Map of indices to expected characters. }; /** * A functor to filter words based on misplaced characters. */ struct misplaced_fn { /** * Constructs a functor with the specified indices and characters. * * @param idxs A map of indices to characters representing misplaced * matches. */ misplaced_fn(const IndexMap &idxs) : map{idxs} {} /** * Checks if a word contains the specified characters but at incorrect * positions. * * @param word The word to be checked. * @return True if the word contains ALL of the characters but at incorrect * positions; false otherwise. */ bool operator()(const std::string &word) const; private: IndexMap map; ///< Map of indices to misplaced characters. }; /** * Filters the `candidates` list by removing words that do not meet certain * conditions based on the given `wrong`, `green`, and `yellow` parameters. * * The conditions are as follows: * - A word is removed if it contains any of the incorrect letters specified in * `wrong`. * - A word is removed if it does not match the positions of the letters * specified in `green` (green letters must be in the exact same positions). * - A word is removed if it does not correctly place the yellow letters * specified in `yellow` (yellow letters must be in the word but at different * positions). * * @param candidates A reference to the vector of candidate words to filter. * @param wrong A string of incorrect letters that should not appear in the * word. * @param green An `IndexMap` representing the correct letters and their exact * positions in the word. * @param yellow An `IndexMap` representing the letters that should appear in * the word but in incorrect positions. */ void do_filter(std::vector &candidates, const std::string &wrong, const IndexMap &green, const IndexMap &yellow); /** * Constructs an `IndexMap` from the provided string. * The function parses the string and maps the indices of letters to their * respective positions in a way that is suitable for the filtering logic in the * Wordle solver. * * @param line A string representing the word or feedback line to process (e.g., * "G__Y_"). * * @return An `IndexMap` where the key is the index of the letter, and the value * represents the status of that letter. This could be an enumeration or an * integer representing the state of the letter (e.g., green, yellow, or gray). */ IndexMap build_list(const std::string &line); /** * Prompts the user (or simulation) for input, typically to get a guess and * feedback from the user. This function returns the guessed word along with its * green and yellow feedback in the form of `IndexMap`s. * * @return A tuple containing three elements: * - A string representing the guessed word. * - An `IndexMap` for the positions and letters that are correct (green * letters). * - An `IndexMap` for the positions and letters that are in the word * but misplaced (yellow letters). */ std::tuple prompt(); #endif // ORDLE_H