Exemplo n.º 1
0
 def subtract_rack(self, rack):
     """ Subtract all tiles in the rack from the bag """
     self._tiles = Alphabet.string_subtract(self._tiles, rack)
Exemplo n.º 2
0
 def subtract_board(self, board):
     """ Subtract all tiles on the board from the bag """
     board_tiles = u''.join(tile for row, col, tile, letter in board.enum_tiles())
     self._tiles = Alphabet.string_subtract(self._tiles, board_tiles)
Exemplo n.º 3
0
 def process(self, rack):
     """ Generate the data that will be shown to the user on the result page.
         This includes a list of permutations of the rack, as well as combinations
         of the rack with a single additional letter. High scoring words are also
         tabulated. """
     # Start with basic hygiene
     if not rack:
         return False
     rack = rack.strip()
     if not rack:
         return False
     # Make sure we reset all state in case we're called multiple times
     self._counter = 0
     self._allwords = [] # List of tuples: (word, score)
     self._highscore = 0
     self._highwords = []
     self._combinations = { }
     self._rack = ""
     self._pattern = False
     # Do a sanity check on the input by calculating its raw score, thereby
     # checking whether all the letters are valid
     score = 0
     rack_lower = "" # Rack converted to lowercase
     wildcards = 0 # Number of wildcard characters
     # If the rack starts with an equals sign ('=') we do a pattern match
     # instead of a permutation search
     if rack[0] == '=':
         self._pattern = True
         rack = rack[1:]
     # Sanitize the rack, converting upper case to lower case and
     # catching invalid characters
     try:
         for c in rack:
             ch = c
             if ch in Alphabet.upper:
                 # Uppercase: find corresponding lowercase letter
                 ch = Alphabet.lowercase(ch)
             if ch in '?_*':
                 # This is one of the allowed wildcard characters
                 wildcards += 1
                 ch = '?'
             else:
                 score += Alphabet.scores[ch]
             rack_lower += ch
     except KeyError:
         # A letter in the rack is not valid, even after conversion to lower case
         return False
     if not self._pattern and (wildcards > 2):
         # Too many wildcards in a permutation search - need to constrain result set size
         return False
     # The rack contains only valid letters
     self._rack = rack_lower
     # Generate combinations
     if not self._pattern and not wildcards:
         # If no wildcards given, check combinations with one additional letter
         query = self._rack + '?'
         # Permute the rack with one additional letter
         p = self._word_db.find_permutations(query)
         # Check the permutations to find valid words and their scores
         if p is not None:
             for word in p:
                 # Only interested in full-length permutations, i.e. with the additional letter
                 if len(word) == len(query):
                     # Find out which letter was added
                     addedletter = Alphabet.string_subtract(word, self._rack)
                     self._add_combination(addedletter, word)
     # Check permutations
     # The shortest possible rack to check for permutations is 2 letters
     if len(self._rack) < 2:
         return True
     if self._pattern:
         # Use pattern matching
         p = self._word_db.find_matches(self._rack, True) # We'd like a sorted result
     else:
         # Find permutations
         p = self._word_db.find_permutations(self._rack)
     if p is None:
         return True
     for word in p:
         if len(word) < 2:
             # Don't show single letter words
             continue
         # Calculate the basic score of the word
         score = self.score(word)
         if wildcards and not self._pattern:
             # Complication: Make sure we don't count the score of the wildcard tile(s)
             wildchars = Alphabet.string_subtract(word, self._rack)
             # What we have left are the wildcard substitutes: subtract'em
             score -= self.score(wildchars)
         self._add_permutation(word, score)
     # Successful
     return True
Exemplo n.º 4
0
 def process(self, rack):
     """ Generate the data that will be shown to the user on the result page.
         This includes a list of permutations of the rack, as well as combinations
         of the rack with a single additional letter. High scoring words are also
         tabulated. """
     # Start with basic hygiene
     if not rack:
         return False
     rack = rack.strip()
     if not rack:
         return False
     # Make sure we reset all state in case we're called multiple times
     self._counter = 0
     self._allwords = [] # List of tuples: (word, score)
     self._highscore = 0
     self._highwords = []
     self._combinations = { }
     self._rack = u''
     self._pattern = False
     # Do a sanity check on the input by calculating its raw score, thereby
     # checking whether all the letters are valid
     score = 0
     rack_lower = u'' # Rack converted to lowercase
     wildcards = 0 # Number of wildcard characters
     # If the rack starts with an equals sign ('=') we do a pattern match
     # instead of a permutation search
     if rack[0] == u'=':
         self._pattern = True
         rack = rack[1:]
     # Sanitize the rack, converting upper case to lower case and
     # catching invalid characters
     try:
         for c in rack:
             ch = c
             if ch in Alphabet.upper:
                 # Uppercase: find corresponding lowercase letter
                 ch = Alphabet.lowercase(ch)
             if ch in u'?_*':
                 # This is one of the allowed wildcard characters
                 wildcards += 1
                 ch = u'?'
             else:
                 score += Alphabet.scores[ch]
             rack_lower += ch
     except KeyError:
         # A letter in the rack is not valid, even after conversion to lower case
         return False
     if not self._pattern and (wildcards > 2):
         # Too many wildcards in a permutation search - need to constrain result set size
         return False
     # The rack contains only valid letters
     self._rack = rack_lower
     # Generate combinations
     if not self._pattern and not wildcards:
         # If no wildcards given, check combinations with one additional letter
         query = self._rack + u'?'
         # Permute the rack with one additional letter
         p = self._word_db.find_permutations(query)
         # Check the permutations to find valid words and their scores
         if p is not None:
             for word in p:
                 # Only interested in full-length permutations, i.e. with the additional letter
                 if len(word) == len(query):
                     # Find out which letter was added
                     addedletter = Alphabet.string_subtract(word, self._rack)
                     self._add_combination(addedletter, word)
     # Check permutations
     # The shortest possible rack to check for permutations is 2 letters
     if len(self._rack) < 2:
         return True
     if self._pattern:
         # Use pattern matching
         p = self._word_db.find_matches(self._rack, True) # We'd like a sorted result
     else:
         # Find permutations
         p = self._word_db.find_permutations(self._rack)
     if p is None:
         return True
     for word in p:
         if len(word) < 2:
             # Don't show single letter words
             continue
         # Calculate the basic score of the word
         score = self.score(word)
         if wildcards and not self._pattern:
             # Complication: Make sure we don't count the score of the wildcard tile(s)
             wildchars = Alphabet.string_subtract(word, self._rack)
             # What we have left are the wildcard substitutes: subtract'em
             score -= self.score(wildchars)
         self._add_permutation(word, score)
     # Successful
     return True
Exemplo n.º 5
0
 def subtract_rack(self, rack):
     """ Subtract all tiles in the rack from the bag """
     self._tiles = Alphabet.string_subtract(self._tiles, rack)
Exemplo n.º 6
0
 def subtract_board(self, board):
     """ Subtract all tiles on the board from the bag """
     board_tiles = u''.join(
         tile for row, col, tile, letter in board.enum_tiles())
     self._tiles = Alphabet.string_subtract(self._tiles, board_tiles)