Package: elzzur
elzzursolves a Ruzzle board, listing all the valid words with their
scores.Version: 0.0.1Date: 2016-05-11Developer:Alberto PettarinLicense: the MIT License (MIT)Contact:click hereUsage$ python -m elzzur --help
$ python -m elzzur solve -l language -b board [-d dictionary] [OPTIONS]
$ python -m elzzur demo -l language
$ python -m elzzur languages
$ python -m elzzur cat -d dictionary [-o output]
$ python -m elzzur compile -d dictionary -o output
$ python -m elzzur generate -l language [-r rows] [-c columns] [-o board]In demo mode elzzur will solve a built-in real board for the given
language.If you do not specify a dictionary file, the built-in dictionary for the
given language will be used.Examples$python-melzzurdemo-len$python-melzzursolve-len-b/path/to/en.board$python-melzzursolve-len-b/path/to/en.board-d/path/to/your.dict.txt$python-melzzursolve-lit-b/path/to/it.board-d/path/to/your.dict.marisaOutput (board, list of words, statistics):$python-melzzurdemo-lenTtlRSNdlOdwHtwEICdwINVEtlADECOHESIVE224(2,0)(1,0)(1,1)(1,2)(0,2)(1,3)(2,3)(3,3)HEROIC154(1,1)(1,2)(0,1)(1,0)(2,1)(2,0)CHORES154(2,0)(1,1)(1,0)(0,1)(1,2)(0,2)COHEN149(2,0)(1,0)(1,1)(1,2)(0,3)ECHO144(3,0)(2,0)(1,1)(1,0)...IA2(2,1)(3,1)ES2(1,2)(0,2)ER2(1,2)(0,1)AN2(3,1)(2,2)AI2(3,1)(2,1)Numberofwords:281Lengthofthelongestword:8Maximumtotalscore:7376See theOUTPUT filefor the full output.Installation$pipinstallelzzuror$gitclonehttps://github.com/pettarin/elzzur$cdelzzur$pythonsetup.pyinstallYou need themarisa-triePython package to run elzzur
(pip installmarisa-trie).Scoring RulesOnly words in the given dictionary are valid.Only words at least two letters long are valid.A snake (i.e., a sequence of adjacent letters) cannot intersect
itself, that is, each board cell can be used at most once per snake.Only one snake per word counts, that is, only the first snake forming
a word will get points.The score of a snake is the sum of the scores of its letters (each
multiplied by its letter multiplier, if any), times the product of
the word multipliers (if any), plus the word length points.The word length points are: 25 for 9-letter words, 20 for 8, 15 for
7, 10 for 6, 5 for 5, 0 for all the other cases.Available LanguagesThe following languages are supported, which means that the code
includes a sample board, letter score, and letter frequency for each of
them:deenesfr(letter score TBC)itnlpt(letter score TBC)Adding A New LanguageYou need to modify theelzzur/languages.py. Specifically, you need
to edit the following constants:LANGUAGES: add your language code, sayzz;LETTER_SCORE: add the score of each letter for languagezz;LETTER_FREQUENCY: add the frequency of each letter in languagezz, normalizing Unicode and case.You should also provide a real board filezz.board, and thezz.marisadictionary derived fromaspell-zz.If you add a new language, please open a pull request, so that everyone
can get it!Dictionary File FormatThe dictionary file must be a plain text, UTF-8 encoded file, with one
word per line:a
A
AA
AAA
Aachen
aah
Aaliyah
...The words will undergoUnicode
NFKDandcase
normalization,
resulting in a dictionary of (uppercased) ASCII words. For example, the
Italian wordcaffè(coffee) will becomeCAFFE.Alternatively, dictionary files can be compiled MARISA files, which are
binary serializations of MARISA tries (see SectionSolver
Strategyfor details). Providing the dictionary in
this format will make the loading time shorter. To compile a plain text
dictionary into a MARISA binary dictionary, you can invoke:$ python -m elzzur compile -d /path/to/plain/dictionary -o /path/to/output.marisaPlease note that you need to specify the.marisaextension for
elzzur to load the file as a MARISA trie. Otherwise, it will try to read
it as a plain text file, failing.Board File FormatThe board file must be an ASCII file, containing one line per board row,
with letters separated by one space (or more, as multiple spaces are
counted as one), for example:Ttl R   S Ndl
Odw Htw E I
Cdw I   N V
Etl A   D EThe board can have dimensionsNxM, withN >= 1, M >= 1, not just4x4, under the constraint that all the rows must have the same
number of columns (letters), that is, the board cannot contain holes.The multipliers, if present, must be appended to the corresponding
letter, using the following codes:tw: triples the value of the worddw: doubles the value of the wordtl: triples the value of the letterdl: doubles the value of the letterYou can generate a random board with:$ python -m elzzur generate -l language [-r rows] [-c cols] [-o outputfile]Solver StrategyThe current implementation solves a given board in three steps:it finds all the valid snakes, that is, all the adjacent sequences of
letters corresponding to a valid word in the dictionary;for each word, it keeps only the snake with the highest score; andit sorts the words (and the corresponding highest scoring snake),
according to the method requested by the user: score, word length,
word start cell, word end cell.To find all the valid snakes, a BFS exploration of the board is
performed (simulated with a queue), avoiding extending the current snake
if either:the snake will self-intersect or,the word corresponding to the current snake is not a prefix of any
word in the dictionary.Clearly, the crucial point consists in speeding the prefix testing up.
Hence, the dictionary is stored in memory as a MARISA trie (either
loaded from a serialized trie version, or converted from a plain text
file).AMARISA
trieis a
very efficient trie (prefix tree), in terms of both storage space and
preprocessing/running time. In particular, it guarantees that the
following operations are extremely fast:has_keys_with_prefix(prefix)keys_with_prefix(prefix)has_key(key)ThePython modulemarisa-trieis based on theoriginal
C++MARISA code.Currently, elzzur can solve a 4x4 board in less than 100ms, and a 10x10
board in about 5s.TODO ListLet the user run with a new language without editing the source codeLet the user alter the letter scores without editing the source codeLet the user specify the letter scores directly in the board fileSome languages have letters other thanA-ZGeneralize the game to be case-sensitiveGeneralize the game to allow self-intersecting snakesGeneralize the game to allow holes in the boardBetter random board generation, e.g. based on N-grams and/or
vocabularyGiven a board (hence, the letters and their number of repetitions),
one can prune the dictionary trie, excluding words that cannot be
formed with the given available lettersConfirm letter scores forfrandptConfirm length points for words longer than 9 lettersDefine rules and scores outside the code, using some format/lib TBDNicer command line interface, e.g. better argparse and examplesLicenseelzzuris released under the MIT License.The included MARISA dictionariesres/*.marisawere compiled from the
correspondingGNU aspelldictionaries, and they
are released under the same license, that is, the GNU GPL v2 License,
see thelicensesdirectory.Ruzzleis a product of MAG
Interactive(TM).AcknowledgmentsMy sister and nephews for introducing me to Ruzzle