def subtract_rack(self, rack): """ Subtract all tiles in the rack from the bag """ self._tiles = Alphabet.string_subtract(self._tiles, rack)
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)
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
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
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)