!752 static new Highest highest; sclass Infos { Map chars; bool debug; } static interface Algorithm { S recognizeWord(BWImage img, Infos infos); } static Infos infos; static Map words; p { load("highest"); } please include function charRangeToChar. // returns true when happy with the sucking package static bool suck(S desc, Algorithm algorithm) { print("Best score: " + highest.score); if (highest.update(desc, scoreAlgorithm(algorithm))) { save("highest"); true; } false; } static synchronized double scoreAlgorithm(Algorithm algorithm) { if (infos == null) { infos = new Infos; infos.chars = mapValues("charRangeToChar", loadGlyphSheet("#1004645")); } if (words == null) words = loadGlyphSheet("#1004649"); printStructure(values(words)); double score = 0, total = 0; for (BWImage img : keys(words)) { infos.debug = false; S w; try { w = algorithm.recognizeWord(img, infos); } catch e { w = exceptionToStringShort(e); silentException(e); } S real = words.get(img); print(real + " => " + w); ++total; if (eq(real, w)) { ++score; print(" ok!"); } else { print(" oops..."); if (l(real) != 0) { int lev = leven(real, w); double s = max(0, 1-lev/(double) l(real)); print("score: " + s + " (lev: " + lev + ")"); score += s; } // Do it again for debug output (could be skipped if needed) infos.debug = true; try { algorithm.recognizeWord(img, infos); } catch {} } } print(); print("SCORE: " + formatDouble(score, 1) + "/" + formatDouble(total, 1)); if (lastSilentException() != null) printStackTrace(lastSilentException()); ret score*100/total; }