A player guesses letters that are part of a word!
If he has not guessed the complete word before making six (6) mistakes, he has lost!
_______
|/ |
| (_)
| \|/ It is a game over!
| |
| / \
|
___|___
⚫ Your Challenge
In a language of your choice, write a program that takes as its input (in some way) the target word (with blanks) and the letters that have been guessed already. It should then output the next letter to be guessed.
For example:
$ echo -n "p...s\npds" | ./guesser
e
You may assume the word to be guessed is an English word and contains only lowercaseASCIIletters.
Provide code and instructions if usage is not obvious. Consider using a tripcode to ease conversation about your entry.
Entries will be judged on GOODITUDE (defined as its win/loss ratio over twenty random games), on SPEED, and on CLEVERNESS.
Your deadline is 23:59:59 on Sunday, May 20th. Results will be posted the following day.
(define (char-range a b)
(map integer->char (range (char->integer a) (char->integer b))))
;; evaluates functions on a fixed input.
(define (evaluator x)
(lambda (f)
(f x)))
;; checks if a guess will match a fixed word.
(define (checker word)
(lambda (guess)
(equal? guess word)))
;; collects all indeces in which the letter matches a fixed word.
(define (matching-index-collector word)
(lambda (letter)
(letrec ((loop (lambda (i matches)
(cond ((>= i (string-length word))
matches)
((equal? (string-ref word i) letter)
(loop (+ i 1) (cons i matches)))
(else
(loop (+ i 1) matches))))))
(loop 0 '()))))
;; Sees how many times a letter will match a fixed word.
(define (scorer word)
(lambda (letter)
(letrec ((loop (lambda (i score)
(cond ((>= i (string-length word))
score)
((equal? (string-ref word i) letter)
(loop (+ i 1) (+ score 1)))
(else
(loop (+ i 1) score))))))
(loop 0 0))))
;; Sums the scores for a letter, recieved from a fixed list of scorers.
(define (sum-scorer scorers-list)
(lambda (letter)
(apply + (map (evaluator letter) scorers-list))))
;; evaluates to the element in domain-list that maximizes f.
(define (arg-max domain-list f)
(letrec ((loop (lambda (current-arg-max current-max domain-list)
(if (null? domain-list)
current-arg-max
(let* ((next-arg (car domain-list))
(next-value (f next-arg)))
(if (> next-value current-max)
(loop next-arg next-value (cdr domain-list))
(loop current-arg-max current-max (cdr domain-list))))))))
(loop (car domain-list) (f (car domain-list)) (cdr domain-list))))
(define result (hang-man words-list (matching-index-collector goal-word) (string-length goal-word) alphabet lives-count))
(display result) (newline)
give it:
"goal word"
("dictionary" "list" ...)
lives-count
as input, and it'll:
1. pick an unchosen letter that would yield the largest sum of discoveries in all considerable words left in the dictionary.
2. find all positions where the letter matches the goal word.
3. filter the dictionary with words that match the chosen letter, in the same positions.