Here's a poor man's introduction to the concept of a "language model." Scrabble uses a langauge model. Let's take a look. First, a few utility functions (which I keep in text.py) and some examples of how they work: >>> from text import ngrams, freq ngrams(astring, n) will give you all the substrings of length 'n'. (It also works with objects besides strings, by the way.) >>> bigrams = ngrams('abczzz',2) >>> bigrams ['ab', 'bc', 'cz', 'zz', 'zz'] >>> fq = freq(bigrams) freq(sequence) will return an dictionary with frequency counts of all the elements of sequence. >>> fq == { 'ab': 1, 'bc': 1, 'cz': 1, 'zz': 2} True Note that the ngrams function doesn't remove duplicates -- that's important. In Scrabble, every letter has a value. Here's the ngrams(open('en').read(),2) from text import freq # ngrams(open('en').read(),2) freq( ngrams(open('en').read(),2)) [(v,k) for k,v in freq( ngrams(open('en').read(),2))] [(v,k) for k,v in freq( ngrams(open('en').read(),2)).items()] sorted([(v,k) for k,v in freq( ngrams(open('en').read(),2)).items()]) sorted([(v,k) for k,v in freq( ngrams(open('en').read(),2)).items()])[-20:] for i in sorted([(v,k) for k,v in freq( ngrams(open('en').read(),2)).items()])[-20:]: print i