import time def loadBoard(fileName): with open(fileName) as board: boardContents = board.read() boardContents = boardContents.splitlines() for boardIter in range(len(boardContents)): boardContents[boardIter] = list(boardContents[boardIter].split()) return boardContents def printBoard(boardInput): for boardIter in range(len(boardInput)): for boardIterTwo in range(len(boardInput[boardIter])): print(boardInput[boardIter][boardIterTwo], end=" ") print() def possibleMoves(inputCoords, boardInput): maxLen = len(boardInput) - 1 moveList = [] # possible moves: (x+1, y), (x-1, y), (x, y+1), (x, y-1), (x+1, y+1), (x-1, y-1), (x+1, y-1), (x-1, y+1) possibleMoves = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)] for move in possibleMoves: newX = inputCoords[0] + move[0] newY = inputCoords[1] + move[1] if (0 <= newX <= maxLen) and (0 <= newY <= maxLen): moveList.append((newX, newY)) # print(moveList) return moveList def legalMoves(possMoves, pathTaken): legalMoveSet = set(possMoves) pathTakenSet = set(pathTaken) return legalMoveSet.difference(pathTakenSet) def readDictionary(fileName): wordList = [] with open(fileName) as words: wordList = words.read().splitlines() return wordList def examineState(boardInput, inputCoords, pathTaken, wordList): # add the inputCoords to the pathTaken pathTaken = pathTaken + (inputCoords,) # find the word that is associated with that path createdWord = "" for x, y in pathTaken: createdWord = createdWord + boardInput[x][y] createdWord = createdWord.lower() # check the wordList to see if that word is valid validWord = createdWord in wordList # create a tuple that includes the word, and 'Yes' if the word was valid. validState = "No" if validWord: validState = "Yes" state = (createdWord, validState) # return the created tuple return state def runBoard(boardFileName, wordListFileName): # load the board completeBoard = loadBoard(boardFileName) # load the dictionary completeDictionary = set(readDictionary(wordListFileName)) # print out the board printBoard(completeBoard) # print out the starting print("\nAnd we're off!") # count the number of paths that are searched searchedPaths = 0 # define a set of the found words foundWords = set() # since the board is square, take the length of the board from one side. boardSize = len(completeBoard) # start the time counter startTime = time.time() # use a double for loop structure to traverse the board for x in range(boardSize): for y in range(boardSize): # define the current traced path, using a tuple, inside a set, inside a set, inside a list... # this was a very frustrating structure to work with... trace = [((x, y),)] # now, using a while loop, go through the trace structure. while trace: # this is the current path taken, remove it from the list currentPath = trace.pop() # add the number of paths searchedPaths = searchedPaths + 1 # save the previous coordinate used from the current path previousCoord = currentPath[-1] # add a possible path using the possible moves function. possiblePath = possibleMoves(previousCoord, completeBoard) # check which are the legal moves/paths legalPath = legalMoves(possiblePath, currentPath) # now, check each path within the legalPath structure for path in legalPath: # add the path to a temporary variable newPath = currentPath + (path,) # check to see if the word is valid, deconstructing the tuple # into the word and if the word exists using the examineState # function checkWord, validWord = examineState(completeBoard, path, currentPath, completeDictionary) # check to see if the word is valid, and if it is, # then add that word to the foundWords set. if validWord == "Yes": foundWords.add(checkWord.upper()) # append the path to the trace tracker. trace.append(newPath) # save the current time as the endTime endTime = time.time() # subtract the endTime and startTime to get the total amount of time totalTime = endTime - startTime # tell the user that the search is complete. print("All done") # print out how many paths were searching and how long it took print(f"\nSearched total of {searchedPaths} moves in {totalTime:.3f} seconds") # print out how many word were found of each length, comma separated, # using a empty dictionary. wordLens = {} # loop through the foundWords list for word in foundWords: # set the current word length length = len(word) # check to see if the length is within the dictionary if length not in wordLens: wordLens[length] = [] # append the word to dictionary associating it with a length wordLens[length].append(word) # show the words that are found print("\nWords found:") # loop through the total length, and the words that are now sorted in the # wordLens dictionary. for length, words in sorted(wordLens.items()): # print out each word list, creating the string kinda on the fly. print(f"{length}-letter words: {', '.join(sorted(words))}") # print out the number of words found total print("\nFound " + str(len(foundWords)) + " words in total.") # print out an alphabetical sorted list of the words (comma separated) print("Alpha-sorted list words:") print(", ".join(sorted(foundWords))) # (DONE) define runBoard and other functions. runBoard("board2.txt", "twl06.txt") runBoard("board3.txt", "twl06.txt") runBoard("board4.txt", "twl06.txt")