148 lines
6.1 KiB
Python
148 lines
6.1 KiB
Python
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")
|