Reputation: 43
I am trying to write a scrabble application with two functions (the main word-matching one, and the second for scoring). Implemented this as two .py files, but can't seem to get the query working. We use the sowpods file as the reference for valid scrabble words.
As a secondary objective, I would also like to make this work for 2 (and max 2) wildcards (out of 7) letters in total.
This is the scoring function that takes in a word and returns the score (as total)
def score_word(word_low):
scores = {"a": 1, "c": 3, "b": 3, "e": 1, "d": 2, "g": 2,
"f": 4, "i": 1, "h": 4, "k": 5, "j": 8, "m": 3,
"l": 1, "o": 1, "n": 1, "q": 10, "p": 3, "s": 1,
"r": 1, "u": 1, "t": 1, "w": 4, "v": 4, "y": 4,
"x": 8, "z": 10}
total = 0
for letter in word_low:
total = total + scores[letter]
return total
#valid_words.append([total, word_low])
This is the main function that takes in a rack of letters as input and returns the descending list of valid word combinations (ordered by score). Also the total combinations
from wordscore import *
def run_scrabble(rack):
rack_low = rack.lower()
rack_letters = list(rack_low)
valid_words = []
with open("sowpods.txt","r") as infile:
raw_input = infile.readlines()#[0:1000]
data = [datum.strip('\n') for datum in raw_input]
for word in data:
word_low = word.lower()
for letter in word_low:
if letter in rack_letters:
rack_letters.remove(letter)
elif '*' in rack_letters:
rack_letters.remove('*')
elif '?' in rack_letters:
rack_letters.remove('?')
else:
pass
else:
valid_words.append([score_word(word_low), word_low])
valid_words.sort(reverse = True)
for entry in valid_words:
score = entry[0]
word_low = entry[1]
print((score, word_low))
print("Total number of words:", len(valid_words))
I am stuck in the word matching section which is where I believe the problem is.
Test Sample Rack: 'hare'
Expected Output
(7, 'rhea')
(7, 'hear')
(7, 'hare')
(6, 'reh')
(6, 'rah')
(6, 'her')
(6, 'hae')
(5, 'he')
(5, 'ha')
(5, 'eh')
(5, 'ah')
(3, 'era')
(3, 'ear')
(3, 'are')
(2, 're')
(2, 'er')
(2, 'ea')
(2, 'ar')
(2, 'ae')
Total number of words: 19
Actual Output: looks like the ordered list of max scores from the full dictionary
(51, 'razzamatazzes')
(50, 'razzmatazzes')
(49, 'razzamatazz')
(49, 'pizzazzy')
(48, 'razzmatazz')
(47, 'quizzifications')
(47, 'pizzazzes')
(47, 'pazzazzes')
(47, 'bezzazzes')
...
...
Before tackling the problem with wildcards, I need to resolve the issue with the word-matching query. Any help would be awesome
Upvotes: 0
Views: 411
Reputation: 64
I think the problem can be that you are using for ... else wrong way.
The code after else get executed always, because you always leave the for loop normal way. I think you wanted to type break
instead of pass
. And also you are removing letter permanently. So do something like this.
...
for word in data:
word_low = word.lower()
temp_rack_letters = rack_letters.copy() # keep the original
for letter in word_low:
if letter in temp_rack_letters :
temp_rack_letters .remove(letter)
elif '*' in temp_rack_letters :
temp_rack_letters .remove('*')
elif '?' in temp_rack_letters :
temp_rack_letters .remove('?')
else:
break # You want to exit the loop if letter dont match
else:
valid_words.append([score_word(word_low), word_low])
...
Also this for ... else syntax is not very readable, and as you can see I is easy to make mistakes and bugs, so be careful using it.
HTH
Upvotes: 1