import httpclient, sequtils, sets, strutils, sugar from unicode import capitalize const DictFname = "unixdict.txt" DictUrl1 = "http://wiki.puzzlers.org/pub/wordlists/unixdict.txt" # ~25K words DictUrl2 = "https://raw.githubusercontent.com/dwyl/english-words/master/words.txt" # ~470K words type Dictionary = HashSet[string] proc loadDictionary(fname = DictFname): Dictionary = ## Return appropriate words from a dictionary file. for word in fname.lines(): if word.len >= 3 and word.allCharsInSet(Letters): result.incl word.toLowerAscii proc loadWebDictionary(url: string): Dictionary = ## Return appropriate words from a dictionary web page. let client = newHttpClient() for word in client.getContent(url).splitLines(): if word.len >= 3 and word.allCharsInSet(Letters): result.incl word.toLowerAscii proc getPlayers(): seq[string] = ## Return inputted ordered list of contestant names. try: stdout.write "Space separated list of contestants: " stdout.flushFile() result = stdin.readLine().splitWhitespace().map(capitalize) if result.len == 0: quit "Empty list of names. Quitting.", QuitFailure except EOFError: echo() quit "Encountered end of file. Quitting.", QuitFailure proc isWordiffRemoval(word, prev: string; comment = true): bool = ## Is "word" derived from "prev" by removing one letter? for i in 0..prev.high: if word == prev[0.. wordiffs[^1].len: word.isWordiffInsertion(wordiffs[^1], comment) else: word.isWordiffChange(wordiffs[^1], comment) proc couldHaveGot(wordiffs: seq[string]; dict: Dictionary): seq[string] = for word in dict - wordiffs.toHashSet: if word.isWordiff(wordiffs, dict, comment = false): result.add word when isMainModule: import random randomize() let dict = loadDictionary(DictFname) let dict34 = collect(newSeq): for word in dict: if word.len in [3, 4]: word let start = sample(dict34) var wordiffs = @[start] let players = getPlayers() var iplayer = 0 var word: string while true: let name = players[iplayer] while true: stdout.write "$1, input a wordiff from “$2”: ".format(name, wordiffs[^1]) stdout.flushFile() try: word = stdin.readLine().strip() if word.len > 0: break except EOFError: quit "Encountered end of file. Quitting.", QuitFailure if word.isWordiff(wordiffs, dict): wordiffs.add word else: echo "You have lost, $#.".format(name) let possibleWords = couldHaveGot(wordiffs, dict) if possibleWords.len > 0: echo "You could have used: ", possibleWords[0..min(possibleWords.high, 20)].join(" ") break iplayer = (iplayer + 1) mod players.len