def extendDownBeta(board, colIdx, rack, partialWord, currentNode, square, legalWords): #Case 1: At the board's edge. Play currentNode and check validity of partialWord. if(square == 14): if '{' in currentNode.children: rowIdx = square - len(partialWord) + 1 legalWords.append((partialWord, (colIdx, rowIdx), False )) #Case 2: Still looking to place more tiles on the board after this move if we can else: #Case 2.1: If square next to where we want to place letter on currentNode on is empty. if(board[square+1][colIdx].getChar() == '_'): #Play and check if partial word is legal. if '{' in currentNode.children: rowIdx = square - len(partialWord) + 1 legalWords.append((partialWord, (colIdx, rowIdx), False )) #Find a candidate tile to play at the next square and call extendRight on it for child in currentNode.children: if child in rack: if board[square+1][colIdx].downCrossCheck[ord(child)-ord('a')] == True: #and it can be legally placed on the next square. rack.remove(child) extendDownBeta(board, colIdx, rack,partialWord + child, currentNode.children[child], square + 1, legalWords) rack.append(child) elif "*" in rack: if board[square+1][colIdx].downCrossCheck[ord(child)-ord('a')] == True: #and it can be legally placed on the next square. rack.remove("*") extendDownBeta(board, colIdx, rack,partialWord + child, currentNode.children[child], square + 1, legalWords) rack.append("*") #Case 2.2: If square next to where we want to place letter from currentNode on is full. Hey, no worries! #Just check if playing the occupying letter after currentNode will give us some valid prefix else: if board[square+1][colIdx].getChar() in currentNode.children: extendDownBeta(board, colIdx, rack, partialWord + board[square+1][colIdx].getChar(), currentNode.children[board[square+1][colIdx].getChar()], square + 1, legalWords)
def upperPart(board, colIdx, rack, partialWord, currentNode, anchorSquare, limit, legalWords): if anchorSquare > 0: #Case 1: Above of anchor square occupied if(board[anchorSquare-1][colIdx].getChar() != '_'): upSquare = anchorSquare-1 upBit = board[upSquare][colIdx].getChar() #Construct the existing upPart while(upSquare > 0): if(board[upSquare-1][colIdx].getChar() == '_'): break upSquare = upSquare - 1 upBit = board[upSquare][colIdx].getChar() + upBit #Walk down the trie to node with upBit path. If it exists. for element in upBit: if element in currentNode.children: currentNode = currentNode.children[element] else: return #For each tile playable on anchorSquare for child in currentNode.children: if child in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendDownBeta(board, colIdx, rack, upBit + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendDownBeta(board, colIdx, rack, upBit + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*") #Case 2: Above of anchor square vacant else: #Check if partialWord formed so far can be placed above pStart = anchorSquare - len(partialWord) for i, letter in enumerate(partialWord): if board[pStart+i][colIdx].downCrossCheck[ord(letter)-ord('a')] == False: return #print partialWord, limit, "survived!" #For each tile playable on anchorSquare for child in currentNode.children: if child in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendDownBeta(board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendDownBeta(board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*") if limit > 0: for child in currentNode.children: if child in rack: rack.remove(child) upperPart( board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, limit-1, legalWords) rack.append(child) elif "*" in rack: rack.remove("*") upperPart( board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, limit-1, legalWords) rack.append("*") else: for child in currentNode.children: if child in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendDownBeta(board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[anchorSquare][colIdx].downCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendDownBeta(board, colIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*")
def leftPart(board, rowIdx, rack, partialWord, currentNode, anchorSquare, limit, legalWords): if anchorSquare > 0: #Case 1: Left of anchor square occupied if(board[rowIdx][anchorSquare-1].getChar() != '_'): leftSquare = anchorSquare-1 leftBit = board[rowIdx][leftSquare].getChar() #Construct the existing leftPart while(leftSquare > 0): if(board[rowIdx][leftSquare-1].getChar() == '_'): break leftSquare = leftSquare - 1 leftBit = board[rowIdx][leftSquare].getChar() + leftBit #Walk down the trie to node with leftBit path for element in leftBit: if element in currentNode.children: currentNode = currentNode.children[element] else: return #if it is not in trie then quit. #For each tile playable on anchorSquare for child in currentNode.children: if child in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendRightBeta(board, rowIdx, rack, leftBit + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendRightBeta(board, rowIdx, rack, leftBit + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*") #Case 2: Left of anchor square vacant else: #Check if partial word formed so far can be placed to the left. pStart = anchorSquare - len(partialWord) for i, letter in enumerate(partialWord): if board[rowIdx][pStart+i].acrossCrossCheck[ord(letter)-ord('a')] == False: return #print partialWord, limit, "survived!" #For each tile playable on anchorSquare for child in currentNode.children: if child in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendRightBeta(board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendRightBeta(board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*") #If we can create even more leftParts if limit > 0: for child in currentNode.children: if child in rack: rack.remove(child) leftPart( board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, limit-1, legalWords) rack.append(child) elif "*" in rack: rack.remove("*") leftPart( board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, limit-1, legalWords) rack.append("*") #Case 3: Nothing to the left of anchor square. else: for child in currentNode.children: if child in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove(child) extendRightBeta(board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append(child) elif "*" in rack: if board[rowIdx][anchorSquare].acrossCrossCheck[ord(child)-ord('a')] == True: rack.remove("*") extendRightBeta(board, rowIdx, rack, partialWord + child, currentNode.children[child], anchorSquare, legalWords) rack.append("*")