open StdLabels open Note open Motus_lib open Brr type t = { length : int ; html_response : (int * Jstr.t, Jv.Error.t) result ; sender : (int * Jstr.t * Validity.t) E.send ; proposition : State.proposition } (** Pick the next word from the dictionnary, and return it as a proposition. If the word is empty (no word) return [None], else return a proposition which can be edited by the user. The rule list is used to identify the letter already fixed by the previous results. *) let get_proposition : int -> catalog:Wordlist.t -> Wordlist.t -> Criteria.t list -> State.proposition option = fun length ~catalog wordlist rules -> let word = let elements = Wordlist.list_size wordlist in if elements > 2000 then Freq_analysis.analyse wordlist |> Freq_analysis.pick_next_word wordlist else let _, word = Entropy.analyse length ~catalog wordlist in word in match String.equal String.empty word with | true -> None | false -> let i = ref 0 in let proposition = word |> String.to_seq |> Seq.map (fun c -> let contain = Criteria.Contain (c, Some !i) in let wellplaced = List.mem contain ~set:rules in incr i; let validity = match wellplaced with | true -> Validity.Wellplaced | _ -> Validity.Missing in Some (Jstr.of_char c, validity) ) |> List.of_seq in Some proposition let process { sender; length; html_response; proposition } state = match html_response with | Ok (200, value) -> let rules = Criteria.Lenght length :: State.get_current_rules proposition in let words = Jstr.cuts ~sep:(Jstr.v "\n") value in let analysis = List.to_seq words |> Seq.map (fun w -> Jstr.(to_string (uppercased w))) |> Wordlist.add_words rules in Printf.printf "Number of elements after filter : %d\n" (Motus_lib.Wordlist.list_size analysis); let current_prop = get_proposition ~catalog:analysis length analysis rules and fields = FieldList.make length sender in ( match current_prop with | None -> state | Some prop -> FieldList.set_with_props prop fields rules; State. { analysis ; catalog = analysis ; rules ; length ; current_prop = prop ; propositions = [] ; fields } ) | _ -> Console.(log [ Jstr.v "No words found" ]); state