NAME
Games::Literati - For word games like Literati (or Scrabble, or Words With Friends), find the best-scoring solution(s) for a board and hand of tiles.
SYNOPSIS
use Games::Literati qw/:allGames/;
literati();
wordswithfriends();
scrabble();
superscrabble();
Example Windows-based one-liner:
perl -MGames::Literati=literati -e "$Games::Literati::WordList = './mydict.txt'; literati();"
Example linux-based one-liner:
perl -MGames::Literati=literati -e "$Games::Literati::WordList = '/usr/dict/words'; literati();"
Export Tags
- :allGames =>
literati()
,wordswithfriends()
,scrabble()
,superscrabble()
- :configGame =>
$WordFile
,$MinimumWordLength
- :infoFunctions =>
n_rows()
,n_cols()
,numTilesPerHand()
,get_solutions()
- :miscFunctions =>
reduce_hand()
DESCRIPTION
Games::Literati helps you find out all solutions for a given board and tiles. It can be used to play Scrabble (the original 15x15 grid), Super Scrabble (the official 21x21 extended grid), Literati (an old Yahoo! Games 15x15 grid, from which Games::Literati derives its name), and Words With Friends (a newer 15x15 grid). By overriding or extending the package, one could implement other similar letter-tile grids, with customizable bonus placements.
To use this module to play the games, a one-liner such as the following can be used:
perl -MGames::Literati=literati -e "literati();"
(This will only work if `./wordlist' is in the current directory. Otherwise, see "PUBLIC VARIABLES", below.)
Enter the data prompted then the best 10 solutions will be displayed.
Board Input
The game will prompt you for each row of the board, one row at a time
row 0:
row 1:
...
row 14:
And will expect you to enter the requested row's data. It expects one character for each column on the board. Thus, on a standard 15x15 board, it will expect each row to contain 15 characters. The `.
' character represents an empty square. Individual letters (in lower case) represent tiles that have already been laid on the board. (Don't worry about indicating wild tiles just yet; that will come momentarily.) An example input row could be:
.......s.header
After requesting the last row, the Games::Literati will display the board as it received it, and ask you
Is the above correct?
At this point, it is expecting you to type either `yes
' or `no
'. If you answer `yes
', the game will progress. If you answer `no
', it will start over asking for row 0:
. If you answer with anything else, it will ask you again if everything is correct.
Once you have entered `yes
', Games::Literati will ask you for the coordinates of the any wild tiles already on the board
wild tiles are at:[Row1,Col1 Row2,Col2 ...]
Row#
and Col#
are 0-referenced, so the upper left of the board is 0,0
, and the lowe right of the standard board is 14,14
. Multiple wild tiles are space-separated. If there have not been any wild tiled played yet, just hit ENTER
, giving it an empty input. If you have wilds, with one at one-tile diagonally from the upper right and the second two tiles diagonally from the lower-left, you would enter
1,13 12,2
If your coordinates resolve to an empty tile (.
) or a tile that's not on the board, you will be notified:
Invalid wild tile positions, please re-enter.
wild tiles are at:[Row1,Col1 Row2,Col2 ...]
Finally, after receiving a valid input for the wilds, Games::Literati will ask you for what tiles are in your hand.
Enter tiles:
You should enter anywhere from 1 to 7 tiles (for a standard game). Letter tiles should be in lower case; wild tiles are indicated by a question mark `?
'.
?omment
It is recommended to pre-write everything into a file. and run the program via command-line. See the "SAMPLE TURNS", below.
SAMPLE TURNS
These samples will use input file t, to help ensure the correct input format.
As described above, the first 15 lines represent board situation, followed with "yes", followed by wild tile positions, if none, place a empty line here, then followed by tiles (can be less than 7), use ? to represent wild tiles. Please make sure the last line in your file ends with a full NEWLINE character on your system (it's safest to add a blank line after the list of tiles).
Make sure to put `./wordlist' in the working directory when running the program, or to set $WordFile
as described in "PUBLIC VARIABLES", below.
First Turn
Create game file named t, like this:
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
yes
?omment
<file end with a CR>
Run the game from the command line:
perl -MGames::Literati=literati -e'literati()' < t
The output will be (depending on word list)
[...]
using 7 tiles:
(47) row 7 become: 'comment' starting at column 1 (BINGO!!!!)
(47) row 7 become: 'memento' starting at column 1 (BINGO!!!!)
(47) row 7 become: 'metonym' starting at column 1 (BINGO!!!!)
(47) row 7 become: 'momenta' starting at column 1 (BINGO!!!!)
(47) row 7 become: 'momento' starting at column 1 (BINGO!!!!)
[...]
Possible Ten Best Solution 1: row 7 become: 'metonym' starting at column 5 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 2: row 7 become: 'moments' starting at column 6 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 3: row 7 become: 'momenta' starting at column 6 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 4: column 7 become: 'omentum' starting at row 7 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 5: column 7 become: 'memento' starting at row 7 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 6: column 7 become: 'memento' starting at row 1 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 7: row 7 become: 'comment' starting at column 3 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 8: row 7 become: 'omentum' starting at column 7 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 9: row 7 become: 'omentum' starting at column 1 (BINGO!!!!) using 7 tile(s), score 47
Possible Ten Best Solution 10: column 7 become: 'memento' starting at row 5 (BINGO!!!!) using 7 tile(s), score 47
If you run the same board with the Scrabble engine:
$ perl -MGames::Literati=scrabble -e'scrabble()' < t
You will get
[...]
(76) row 7 become: 'comment' starting at column 1 (BINGO!!!!)
(76) row 7 become: 'memento' starting at column 1 (BINGO!!!!)
(72) row 7 become: 'metonym' starting at column 1 (BINGO!!!!)
[...]
Possible Ten Best Solution 1: column 7 become: 'memento' starting at row 1 (BINGO!!!!) using 7 tile(s), score 76
Possible Ten Best Solution 2: column 7 become: 'momento' starting at row 1 (BINGO!!!!) using 7 tile(s), score 76
Possible Ten Best Solution 3: row 7 become: 'metonym' starting at column 5 (BINGO!!!!) using 7 tile(s), score 76
Possible Ten Best Solution 4: row 7 become: 'momenta' starting at column 1 (BINGO!!!!) using 7 tile(s), score 76
[...]
Intermediate Turn
For most turns, you input file the t containing a partially populated game, such as:
...............
...............
...............
.......c.......
......ai.......
.......s.header
.......t....r..
...jurors..soup
.......o....p.h
.upsilon.f..pea
.......speering
.........s..n.e
.........t..g..
.........e.....
........broils.
yes
7,8 10,14 7,14
eurmsss
<file end with a CR>
Run the game from the command line:
perl -MGames::Literati=literati -e'literati()' < t
The output will be (depending on word list)
[....]
using 7 tiles:
using 6 tiles:
(9) row 3 become: 'cussers' starting at column 8
(9) row 12 become: 'russets' starting at column 4
using 5 tiles:
(8) row 3 become: 'cruses' starting at column 8
(8) row 3 become: 'curses' starting at column 8
[...]
Possible Ten Best Solution 1: column 3 become: 'susses' starting at row 10 using 5 tile(s), score 24
Possible Ten Best Solution 2: column 3 become: 'serums' starting at row 10 using 5 tile(s), score 24
[...]
If you run the same board with the Scrabble engine:
perl -MGames::Literati=scrabble -e'scrabble()' < t
You will get
[...]
Possible Ten Best Solution 1: row 14 become: 'embroils' starting at column 6 using 2 tile(s), score 36
Possible Ten Best Solution 2: row 6 become: 'stems' starting at column 6 using 4 tile(s), score 23
Possible Ten Best Solution 3: column 2 become: 'spumes' starting at row 8 using 5 tile(s), score 22
[...]
Good luck!:)
PUBLIC FUNCTIONS
- literati([min[, max]])
- wordswithfriends([min[, max]])
- scrabble([min[, max]])
- superscrabble([min[, max]])
-
These functions execute each of the games. As shown in the "SYNOPSIS" and "SAMPLE TURNS", each turn generally requires just one call to the specific game function. Each function implements the appropriate 15x15 (or 20x20 for superscrabble) grid of bonus scores.
There are two optional arguments to the game functions:
- min
-
The minimum number of tiles to play, which defaults to
1
. If you want to only allow your computer player (ie, the Games::Literati module) to play 3 or more tiles, you would set min=3
.If you specify
0
or negative, the magic of perl will occur, and it will internally use the default of min=1
. - max
-
The maximum number of tiles to play, which defaults to all the tiles in the given hand. If you want to restrict your computer player to play 5 or fewer tiles, you would set max=
5
. It will check to ensure that max is bounded by thenumTilesPerHand()
..If you want to specify max, you must also specify a min.
If you specify max less than min, Games::Literati will not play any tiles.
Thus, specifying
literati(3,5)
will restrict the computer Literati player to using 3, 4, or 5 tiles on this turn. - n_rows()
- n_cols()
-
Returns number of rows or columns for the most recent game type
- numTilesPerHand()
-
Returns number of tiles in a full hand for the most recent game type
- get_solutions()
-
Returns a hash, whose elements are described in the example below
%solutions = get_solutions(); # equivalent to %solutions = ( $key => { # [string]: the string that is printed; # it's a really bad idea for the key, but it keeps things # consistent with the old %Games::Literati::solutions keys word => $word, # [string]: the word being played tiles_used => $ntiles, # [number]: the _number_ of tiles used score => $score, # [number]: the score (equivalent to $Games::Literati::solutions{$key}) direction => $dir, # [string]: either 'column' or 'row' row => $row, # [number]: the row number for the start of the word (0-based) col => $col, # [number]: the column number for start of the word (0-based) bingo => $flag, # [boolean]: whether this word was a BINGO or not tiles_this_word => $tiles_this_word, # [string]: Shows the tiles for this word, both those from the board and # those from your hand. Useful for determining placement of wild # tiles tiles_consumed => $consumed, # [string]: Shows the tiles from your hand that were used for this play # (a subset of the tiles from tiles_this_word), which can be used # to remove the tiles from your hand that were played this turn }, ... # repeat for other solutions );
- reduce_hand( $hand_tiles, $played_tiles )
-
Returns the new hand tiles, with the played tiles removed.
print reduce_hand( "rstlnec", "lest"); # prints "rnc"
- DEPRECATED: find(\%args) or find($args)
-
Finds possible valid words, based on the hashref provided. When playing the automated game using the above functions, this is not needed, but it is provided to give you access to a function similar to the internal function, but it outputs extra information to the user.
- \%args or $args
-
A reference to a hash containing the keys
letters
,re
, andinternal
.- $args->{letters}
-
This is the list of letters available to play.
- $args->{re}
-
This is a string which will be evaluated into a perl regular expression that is evaluated to determine. Note: this requres the full regex syntax, so use
'/c.t/'
to indicate you are looking for valid letters to put between a `c' and a `t'. - $args->{internal}
-
(Boolean) If set to a true value, find() will be quiet (not print to standard output) and will return an array-reference of possible solutions. If false, find() will print suggested words to STDOUT.
Note: The find() function is not under active development, and changes to the internal function might not be replicated to this public function. (It is documented and left exportable to be backward compatible with the original Games::Literati 0.01 release.)
PUBLIC VARIABLES
These variables are exportable, so can be fully qualified as %Games::Literati::WordFile
, or if included in the export list when you use
the module, you can reference them directly, as
use Games::Literati qw/literati $WordFile/;
$WordFile = '/usr/share/dict/words';
- $WordFile
-
The
$WordFile
points to a text document, which lists one valid word per line.The variable defaults to './wordfile'. (in version 0.01, that was the only value, and there was no variable.)
You may change the default wordfile by setting this variable to the path to find the list.
$Games::Literati::WordFile = '/usr/dict/words';
Sources for
$WordFile
Your OS may include a builtin dictionary (such as /usr/dict/words or /usr/share/dict/words). Beware: these often have numbers or punctuation (periods, hyphens), which may interfere with proper functioning
ENABLE (Enhanced North American Benchmark Lexicon): a public-domain list with more than 173,000 words, available at a variety of locations, including in an old google code repository as "enable1.txt" The ENABLE dictionary is used by a variety of online tools, and is the primary source for the official Words With Friends dictionary.
Anthony Tan has delved into the Words With Friends app, and has compared their internal list to the original ENABLE list at http://www.greenworm.net/notes/2011/05/02/words-friends-wordlist
If you want to use one of the lists from a website, you will need to download the list to a file, and set
$WordFile
to the path to your downloaded list. - %valid
-
For each word that Games::Literati parses from the
$WordList
file, it will set$valid{word}
to1
. - $MinimumWordLength
-
Default = 2. This is used when parsing the dictionary file (during
var_init
) to ignore words that are too short. Most of these games don't allow single-letter words ("I", "a").
BUGS AND FEATURE REQUESTS
Please report any bugs or feature requests thru the web interface at https://github.com/pryrt/Games-Literati/issues.
A simple interface (with examples) for play your own custom grid is in the works. Studying the source code may point you in the right direction if you want a custom grid before the customization features are made public.
AUTHOR
Chicheng Zhang <chichengzhang AT hotmail.com>
wrote the original code.
Peter C. Jones <petercj AT cpan.org>
is the current maintainer, and has added various features and made bug fixes.
LICENSE AND COPYRIGHT
Copyright (c) 2003, Chicheng Zhang. Copyright (C) 2016,2019,2020 by Peter C. Jones
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.