add the next Boggle part.

This commit is contained in:
Charles Descamps 2025-02-02 15:11:51 -07:00
parent 7cf4d90336
commit 9214cdea09
2 changed files with 140 additions and 3 deletions

View file

@ -1,3 +1,5 @@
import time
def loadBoard(fileName): def loadBoard(fileName):
with open(fileName) as board: with open(fileName) as board:
boardContents = board.read() boardContents = board.read()
@ -25,10 +27,122 @@ def possibleMoves(inputCoords, boardInput):
if (0 <= newX <= maxLen) and (0 <= newY <= maxLen): if (0 <= newX <= maxLen) and (0 <= newY <= maxLen):
moveList.append((newX, newY)) moveList.append((newX, newY))
print(moveList) # print(moveList)
# return 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.
# TODO define runBoard and other functions.
runBoard("board2.txt", "twl06.txt") runBoard("board2.txt", "twl06.txt")
runBoard("board3.txt", "twl06.txt") runBoard("board3.txt", "twl06.txt")
runBoard("board4.txt", "twl06.txt") runBoard("board4.txt", "twl06.txt")

23
Boggle/interpreter.py Normal file
View file

@ -0,0 +1,23 @@
import code
import re
class FileConsole(code.InteractiveConsole):
"""Emulate python console but use file instead of stdin"""
def raw_input(self, prompt):
line = self.f.readline()
if line=="":
raise EOFError()
no_newline = line.replace("\n", "")
no_indent = re.match(r"^\s", line) is None
print(prompt, no_newline, sep="")
return no_newline
def run_file(filename):
fc = FileConsole()
fc.f = open(filename)
fc.interact(banner="", exitmsg="")
if __name__ == "__main__":
import sys
sys.ps1 = "\n>>> "
run_file(sys.argv[1])