From dd1c170eb25fa38054ceb80817221192f2eb230e Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Fri, 13 Sep 2024 20:24:52 -0700 Subject: [PATCH 1/3] added solution --- adagrams/game.py | 154 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 4 deletions(-) diff --git a/adagrams/game.py b/adagrams/game.py index 5fb37b11..42d13ac4 100644 --- a/adagrams/game.py +++ b/adagrams/game.py @@ -1,11 +1,157 @@ +import random + +# Dictionary of the letters with their quantities +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 +} + +# Dictionary assigning point values to the letters +LETTERS_VALUE = { + '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 +} + def draw_letters(): - pass + + # Draw 10 letters randomly, considering the quantity limits + letter_list = list(LETTER_POOL.keys()) + tiles = {} # Dictionary with letter and count to avoid nested loops + letter_bank = [] + while len(letter_bank) < 10: + random_number = random.randint(0, 25) + random_letter = letter_list[random_number] + if random_letter not in tiles: + tiles[random_letter] = 1 + letter_bank.append(random_letter) + elif tiles[random_letter] < LETTER_POOL[random_letter]: + tiles[random_letter] += 1 + letter_bank.append(random_letter) + + return letter_bank + +# Count occurrences of a letter in an iterable +def count_items(item, iterable): + count = 0 + for x in iterable: + if x == item: + count += 1 + return count def uses_available_letters(word, letter_bank): - pass + capital_word = word.upper() + + for letter in set(capital_word): + if letter not in letter_bank or count_items(letter, capital_word) > count_items(letter, letter_bank): + return False + return True + def score_word(word): - pass + # Calculate score + score = 0 + for letter in word.upper(): + score += LETTERS_VALUE[letter] + + # Add bonus points for words of length 7-10 + if len(word) >= 7 and len(word) <= 10: + score += 8 + return score + +# Function to find the maximum value in a list of numbers +def calculate_max(iterable): + max = 0 + for value in iterable: + if value > max: + max = value + return max + +# Function to find the minimum length of words in a list +def calculate_min_length(list_of_words): + if not list_of_words: + return None + + min_length = len(list_of_words[0]) + for word in list_of_words: + if len(word) < min_length: + min_length = len(word) + return min_length + def get_highest_word_score(word_list): - pass \ No newline at end of file + # Calculate scores of each word + word_score = {} + for word in word_list: + score = score_word(word) + word_score[word] = score + + # Calculate max score + max_score = calculate_max(word_score.values()) + + # Find all candidate words with max scores + candidates = [] + for word, score in word_score.items(): + if score == max_score: + candidates.append(word) + + # Find minimum length in candidates + min_length = calculate_min_length(candidates) + + # Determine a winner considering rules + current_winner = '' + for word in candidates: + if len(word) == 10: + current_winner = word + break + if len(word) == min_length and not current_winner: + current_winner = word + + return current_winner, word_score[current_winner] \ No newline at end of file From 389221a84bbb1a8f5546d63c670270e503b88179 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Tue, 17 Sep 2024 15:15:31 -0700 Subject: [PATCH 2/3] refactored draw_letters function --- adagrams/game.py | 147 +++++++++++++++++++++++------------------- main.py | 41 +++++++----- tests/test_wave_04.py | 10 +++ 3 files changed, 115 insertions(+), 83 deletions(-) diff --git a/adagrams/game.py b/adagrams/game.py index 42d13ac4..19c000be 100644 --- a/adagrams/game.py +++ b/adagrams/game.py @@ -2,82 +2,88 @@ # Dictionary of the letters with their quantities 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 + "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, } # Dictionary assigning point values to the letters LETTERS_VALUE = { - '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 + "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, } + def draw_letters(): # Draw 10 letters randomly, considering the quantity limits letter_list = list(LETTER_POOL.keys()) - tiles = {} # Dictionary with letter and count to avoid nested loops - letter_bank = [] + tiles = {} # Dictionary with letter and count to avoid nested loops + letter_bank = [] + while len(letter_bank) < 10: - random_number = random.randint(0, 25) + random_number = random.randint(0, len(letter_list) - 1) random_letter = letter_list[random_number] - if random_letter not in tiles: - tiles[random_letter] = 1 - letter_bank.append(random_letter) - elif tiles[random_letter] < LETTER_POOL[random_letter]: + + if random_letter in tiles: + if tiles[random_letter] >= LETTER_POOL[random_letter]: + continue tiles[random_letter] += 1 - letter_bank.append(random_letter) + else: + tiles[random_letter] = 1 + + letter_bank.append(random_letter) return letter_bank + # Count occurrences of a letter in an iterable def count_items(item, iterable): count = 0 @@ -86,11 +92,14 @@ def count_items(item, iterable): count += 1 return count + def uses_available_letters(word, letter_bank): capital_word = word.upper() for letter in set(capital_word): - if letter not in letter_bank or count_items(letter, capital_word) > count_items(letter, letter_bank): + if letter not in letter_bank or count_items(letter, capital_word) > count_items( + letter, letter_bank + ): return False return True @@ -106,6 +115,7 @@ def score_word(word): score += 8 return score + # Function to find the maximum value in a list of numbers def calculate_max(iterable): max = 0 @@ -114,11 +124,12 @@ def calculate_max(iterable): max = value return max + # Function to find the minimum length of words in a list def calculate_min_length(list_of_words): if not list_of_words: - return None - + return None + min_length = len(list_of_words[0]) for word in list_of_words: if len(word) < min_length: @@ -132,10 +143,10 @@ def get_highest_word_score(word_list): for word in word_list: score = score_word(word) word_score[word] = score - + # Calculate max score max_score = calculate_max(word_score.values()) - + # Find all candidate words with max scores candidates = [] for word, score in word_score.items(): @@ -146,12 +157,12 @@ def get_highest_word_score(word_list): min_length = calculate_min_length(candidates) # Determine a winner considering rules - current_winner = '' + current_winner = "" for word in candidates: - if len(word) == 10: + if len(word) == 10: current_winner = word break if len(word) == min_length and not current_winner: current_winner = word - return current_winner, word_score[current_winner] \ No newline at end of file + return current_winner, word_score[current_winner] diff --git a/main.py b/main.py index bcd6ab0b..aa1e2448 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,12 @@ import sys from adagrams.ui_helper import * -from adagrams.game import draw_letters, uses_available_letters, score_word, get_highest_word_score +from adagrams.game import ( + draw_letters, + uses_available_letters, + score_word, + get_highest_word_score, +) + def wave_1_run_game(): display_welcome_message() @@ -9,13 +15,14 @@ def wave_1_run_game(): print("Let's draw 10 letters from the letter pool...") letter_bank = draw_letters() display_drawn_letters(letter_bank) - + display_retry_instructions() continue_input = input() game_continue = continue_input == "y" - + display_goodbye_message() + def wave_2_run_game(): display_welcome_message() game_continue = True @@ -26,16 +33,17 @@ def wave_2_run_game(): display_game_instructions() user_input_word = input() - while( not uses_available_letters(user_input_word, letter_bank)): + while not uses_available_letters(user_input_word, letter_bank): display_needs_valid_input_message() user_input_word = input() display_retry_instructions() continue_input = input() game_continue = continue_input == "y" - + display_goodbye_message() + def wave_3_run_game(): display_welcome_message() game_continue = True @@ -46,10 +54,10 @@ def wave_3_run_game(): display_game_instructions() user_input_word = input() - while( not uses_available_letters(user_input_word, letter_bank)): + while not uses_available_letters(user_input_word, letter_bank): display_needs_valid_input_message() user_input_word = input() - + score = score_word(user_input_word) display_score(score) @@ -58,6 +66,7 @@ def wave_3_run_game(): game_continue = continue_input == "y" display_goodbye_message() + def wave_4_run_game(): display_welcome_message() game_continue = True @@ -69,10 +78,10 @@ def wave_4_run_game(): display_game_instructions() user_input_word = input() - while( not uses_available_letters(user_input_word, letter_bank)): + while not uses_available_letters(user_input_word, letter_bank): display_needs_valid_input_message() user_input_word = input() - + score = score_word(user_input_word) display_score(score) played_words.append(user_input_word) @@ -83,22 +92,24 @@ def wave_4_run_game(): display_highest_score(get_highest_word_score(played_words)) display_goodbye_message() + def main(wave): - if(wave == 1): + if wave == 1: wave_1_run_game() - elif(wave == 2): + elif wave == 2: wave_2_run_game() - elif(wave == 3): + elif wave == 3: wave_3_run_game() - elif(wave == 4): + elif wave == 4: wave_4_run_game() else: print("Please input a wave number. Valid wave numbers are 1, 2, 3, 4.") + if __name__ == "__main__": args = sys.argv - if(len(args) >= 2 and args[1].isnumeric()): + if len(args) >= 2 and args[1].isnumeric(): wave = int(args[1]) else: wave = "ERROR" - main(wave) \ No newline at end of file + main(wave) diff --git a/tests/test_wave_04.py b/tests/test_wave_04.py index e586621c..7c7e4cef 100644 --- a/tests/test_wave_04.py +++ b/tests/test_wave_04.py @@ -2,6 +2,7 @@ from adagrams.game import score_word, get_highest_word_score + def test_get_highest_word_score_accurate(): # Arrange words = ["X", "XX", "XXX", "XXXX"] @@ -14,6 +15,7 @@ def test_get_highest_word_score_accurate(): assert best_word[0] == "XXXX" assert best_word[1] == 32 + def test_get_highest_word_score_accurate_unsorted_list(): # Arrange words = ["XXX", "XXXX", "XX", "X"] @@ -25,6 +27,7 @@ def test_get_highest_word_score_accurate_unsorted_list(): assert best_word[0] == "XXXX" assert best_word[1] == 32 + def test_get_highest_word_tie_prefers_shorter_word(): # Arrange words = ["MMMM", "WWW"] @@ -38,6 +41,7 @@ def test_get_highest_word_tie_prefers_shorter_word(): assert best_word[0] == "WWW" assert best_word[1] == 12 + def test_get_highest_word_tie_prefers_shorter_word_unsorted_list(): # Arrange words = ["WWW", "MMMM"] @@ -51,6 +55,7 @@ def test_get_highest_word_tie_prefers_shorter_word_unsorted_list(): assert best_word[0] == "WWW" assert best_word[1] == 12 + def test_get_highest_word_tie_prefers_ten_letters(): # Arrange words = ["AAAAAAAAAA", "BBBBBB"] @@ -62,6 +67,7 @@ def test_get_highest_word_tie_prefers_ten_letters(): assert best_word[0] == "AAAAAAAAAA" assert best_word[1] == 18 + def test_get_highest_word_tie_prefers_ten_letters_unsorted_list(): # Arrange words = ["BBBBBB", "AAAAAAAAAA"] @@ -73,6 +79,7 @@ def test_get_highest_word_tie_prefers_ten_letters_unsorted_list(): assert best_word[0] == "AAAAAAAAAA" assert best_word[1] == 18 + def test_get_highest_word_tie_same_length_prefers_first(): # Arrange words = ["AAAAAAAAAA", "EEEEEEEEEE"] @@ -86,6 +93,7 @@ def test_get_highest_word_tie_same_length_prefers_first(): assert best_word[0] == words[0] assert best_word[1] == 18 + def test_get_highest_word_many_ties_pick_first_ten_letters(): # Arrange words = ["JQ", "FHQ", "AAAAAAAAAA", "BBBBBB", "TTTTTTTTTT"] @@ -97,6 +105,7 @@ def test_get_highest_word_many_ties_pick_first_ten_letters(): assert best_word[0] == "AAAAAAAAAA" assert best_word[1] == 18 + def test_get_highest_word_many_ties_pick_shortest(): # Arrange words = ["BBBBBB", "AAAAAAAAD", "JQ", "KFHK"] @@ -108,6 +117,7 @@ def test_get_highest_word_many_ties_pick_shortest(): assert best_word[0] == "JQ" assert best_word[1] == 18 + def test_get_highest_word_does_not_return_early_after_first_tiebreaker(): # Arrange words = ["WWW", "MMMM", "BBBBBB", "AAAAAAAAD", "JQ", "KFHK"] From d8a06380f35e19d43b41c8e62fac4a59491dc2cd Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Fri, 20 Sep 2024 10:05:06 -0700 Subject: [PATCH 3/3] made a small change in final func --- adagrams/game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adagrams/game.py b/adagrams/game.py index 19c000be..1cb31bb4 100644 --- a/adagrams/game.py +++ b/adagrams/game.py @@ -165,4 +165,4 @@ def get_highest_word_score(word_list): if len(word) == min_length and not current_winner: current_winner = word - return current_winner, word_score[current_winner] + return current_winner, max_score