-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spruce - Cecily M. and Angela F. #28
base: master
Are you sure you want to change the base?
Changes from all commits
663254a
773282a
6f3b604
b28f745
b500d90
ace0c1a
3c59070
b58b0ad
14d3289
01a02dc
3be533f
e2f2c9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,120 @@ | ||
import random | ||
|
||
def draw_letters(): | ||
pass | ||
letter_pool = { | ||
'A': 9, | ||
'B': 2, | ||
'C': 2, | ||
'D': 4, | ||
'E': 12, | ||
'F': 2, | ||
'G': 3, | ||
'H': 2, | ||
'I': 9, | ||
'J': 1, | ||
'K': 1, | ||
'L': 4, | ||
'M': 2, | ||
'N': 6, | ||
'O': 8, | ||
'P': 2, | ||
'Q': 1, | ||
'R': 6, | ||
'S': 4, | ||
'T': 6, | ||
'U': 4, | ||
'V': 2, | ||
'W': 2, | ||
'X': 1, | ||
'Y': 2, | ||
'Z': 1 | ||
} | ||
|
||
letters_drawn = [] | ||
letter_pool_list = [] | ||
|
||
for key in letter_pool: | ||
for idx in range(letter_pool[key]): | ||
letter_pool_list.append(key) | ||
Comment on lines
+36
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is building a list of expanded letters to be used for random picking later. From a purely syntax perspective, keep in mind that if we know that we'll need both the key and the value ( for letter, count in letter_pool.items():
letter_pool_list += [letter] * count The alternative approach would be to make a copy of the letter count data, and pick random letters, decrementing their available counts. The initial copy (required so that the next draw has all the letters available again) is roughly equivalent in time to building the extra letter list here. The upside would be that each letter pick would be roughly O(1) rather than O(n) for operations like the choice and remove operations. |
||
|
||
while len(letters_drawn) != 10: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the logic here guarantees that a random letter will be successfully drawn each time through the loop, we could use a for loop with a range expression to run this 10 times. Other approaches (such as the decrement approach I mentioned above) might have loops where a valid letter isn't chosen (if the count is 0), in which case while loop based on the accumulated length of the selected tile list is also a great approach. But here, we could do: for _ in range(10): The use of |
||
random_entry = random.choice(letter_pool_list) | ||
letters_drawn.append(random_entry) | ||
letter_pool_list.remove(random_entry) | ||
return letters_drawn | ||
|
||
def uses_available_letters(word, letter_bank): | ||
pass | ||
|
||
letters_copy = letter_bank.copy() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Since the approach used to check whether the word can be made from the letter bank is destructive to the hand, this copy is necessary (otherwise we'd be destroying the player's hand anytime we check for word validity!). Another approach would be to build a frequency map out of the letter bank, and then check whether each letter in word can be accounted for in the map. This would have the upside that each letter check would be O(1), while checking for |
||
word_length = len(word) | ||
|
||
try: | ||
while word_length > 0: | ||
for letter in word: | ||
if letter in letters_copy: | ||
letters_copy.remove(letter) | ||
word_length -= 1 | ||
else: | ||
raise ValueError | ||
return True | ||
Comment on lines
+52
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of errors! Notice, however, that for letter in word:
letters_copy.remove(letter)
return True |
||
except ValueError: | ||
return False | ||
|
||
def score_word(word): | ||
pass | ||
|
||
score_chart = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice lookup table for the tile scores. As with |
||
'A': 1, | ||
'B': 3, | ||
'C': 3, | ||
'D': 2, | ||
'E': 1, | ||
'F': 4, | ||
'G': 2, | ||
'H': 4, | ||
'I': 1, | ||
'J': 8, | ||
'K': 5, | ||
'L': 1, | ||
'M': 3, | ||
'N': 1, | ||
'O': 1, | ||
'P': 3, | ||
'Q': 10, | ||
'R': 1, | ||
'S': 1, | ||
'T': 1, | ||
'U': 1, | ||
'V': 4, | ||
'W': 4, | ||
'X': 8, | ||
'Y': 4, | ||
'Z': 10 | ||
} | ||
|
||
word = word.upper() | ||
total_points = 0 | ||
|
||
for letter in word: | ||
total_points += score_chart[letter] | ||
if len(word) >= 7 and len(word) <= 10: | ||
total_points += 8 | ||
Comment on lines
+99
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider creating constants to represent these literal values, for example: MIN_BONUS_LENGTH = 7
MAX_BONUS_LENGTH = 10
LENGTH_BONUS = 8 Something else to consider, is it even necessary to check whether the length of the word is less than or equal to 10? |
||
|
||
return total_points | ||
|
||
def get_highest_word_score(word_list): | ||
pass | ||
|
||
highest_scoring_word = ("",0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider keeping these as 2 distinct variables during the calculation, and wait to return them together until the end of the method. By working with a tuple directly here, we need to keep track of which position in the tuple holds the score, and which holds the word. Instead, we could make 2 variables: |
||
|
||
for word in word_list: | ||
score = score_word(word) | ||
if score > highest_scoring_word[1]: | ||
highest_scoring_word = (word, score) | ||
elif score == highest_scoring_word[1]: | ||
if len(word) == len(highest_scoring_word[0]) \ | ||
or len(highest_scoring_word[0]) >= 10: | ||
Comment on lines
+113
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP8 recommends that we avoid explicit line breaks ( if (len(word) == len(highest_scoring_word[0])
or len(highest_scoring_word[0]) >= 10): |
||
continue | ||
if len(word) >= 10 \ | ||
or len(word)< len(highest_scoring_word[0]): | ||
highest_scoring_word = (word, score) | ||
|
||
return highest_scoring_word |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider declaring this as a "constant" (maybe POOL_OF_LETTERS) outside this function. Doing so wouldn't really save on runtime (since we need to modify the counts, we'd need to make a copy at the start of each call to the method), but it does declutter the method a bit by allow us to move the large data structure to some innocuous corner of our file.