From efbb3fc739cdcbffb50b5efe9899482565fcda1d Mon Sep 17 00:00:00 2001 From: Conor Walker <2089327w@student.gla.ac.uk> Date: Tue, 1 Feb 2022 21:53:19 +0000 Subject: [PATCH 1/3] Moves code to functions, and refactors to follow standard Python style --- src/pydle.py | 97 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/src/pydle.py b/src/pydle.py index 10c7baf..c6c6753 100644 --- a/src/pydle.py +++ b/src/pydle.py @@ -3,7 +3,7 @@ import random import sys -def getGuess(number): +def get_guess(number): validGuess = False guess = "" while not validGuess: @@ -21,23 +21,21 @@ def resource_path(relative_path): return os.path.join(base_path, relative_path) -def getWord(): +# Gets a random word from a words.txt file present in the same directory as this script +def get_random_word(): lines = open(resource_path('words.txt')).read().splitlines() return random.choice(lines) -def checkRight(wordToGuess, guessSoFar): - if str(wordToGuess).upper() == str(guessSoFar).upper(): +# Compares the users input with the word to be guessed. Returns true if the guess is correct, false otherwise +def check_word_is_right(word_guessed, word_to_guess): + if str(word_guessed).upper() == str(word_to_guess).upper(): return True else: return False - -def quit(): - input("Thanks for playing! Press ENTER to exit :)") - sys.exit(0) - +# Makes a cool header. def header(): return r" ______ ______ _ _____" + "\n" + \ r"| _ \ \ / / _ \| | | ____|" + "\n" + \ @@ -46,35 +44,54 @@ def header(): r"|_| |_| |____/|_____|_____|" -print("Welcome to...") -print(header()) -print("A totally original guessing game!") -emptyWordGuess = ["_"] * 5 -wrongLetters, rightLettersWrongPlace = set() -wordToGuess = list(getWord().upper()) -# print(wordToGuess) - -counter = 1 -while counter < 6: - userGuess = getGuess(counter) - emptyWordGuess = ["_"] * 5 - for i in range(len(userGuess)): - if wordToGuess[i] == userGuess[i]: - emptyWordGuess[i] = userGuess[i] - elif userGuess[i] in wordToGuess: - if userGuess[i] in emptyWordGuess and userGuess[i] not in wordToGuess[i:]: - break +# Prints welcome messages +def intro(): + print("Welcome to...") + print(header()) + print("A totally original guessing game!") + + +# Prints the results, a thank-you message and gracefully exits +def game_over(user_was_right, correct_word): + if user_was_right: + print("Congratulations! The word was", ''.join(correct_word).capitalize()) + else: + print("Ran out of guesses! The word was: ", "".join(correct_word)) + input("Thanks for playing! Press ENTER to exit :)") + sys.exit(0) + + +# Main game flow. +def game_logic(): + not_in_word, present_in_word = set(), set() + word_to_be_guessed = list(get_random_word().upper()) + counter = 1 + while counter < 7: + users_guess_input = get_guess(counter) + users_guess_results = ["_"] * 5 + for i in range(len(users_guess_input)): + if word_to_be_guessed[i] == users_guess_input[i]: + users_guess_results[i] = users_guess_input[i] + elif users_guess_input[i] in word_to_be_guessed: + if users_guess_input[i] in users_guess_results and users_guess_input[i] not in word_to_be_guessed[i:]: + break + else: + present_in_word.add(users_guess_input[i]) else: - rightLettersWrongPlace.add(userGuess[i]) - else: - wrongLetters.add(userGuess[i]) - if checkRight(wordToGuess, emptyWordGuess): - print("Congratulations! The word was", ''.join(wordToGuess).capitalize()) - quit() - print("Incorrect letters: " + ', '.join(wrongLetters)) - print("Correct letters in the wrong place: " + ', '.join(rightLettersWrongPlace)) - print("Result: " + " ".join(emptyWordGuess)) - counter += 1 - -print("Ran out of guesses! The word was: ", "".join(wordToGuess)) -quit() + not_in_word.add(users_guess_input[i]) + if check_word_is_right(word_to_be_guessed, users_guess_results): + game_over(True, word_to_be_guessed) + print("Incorrect letters: " + ', '.join(not_in_word)) + print("Correct letters in the wrong place: " + ', '.join(present_in_word)) + print("Result: " + " ".join(users_guess_results)) + counter += 1 + game_over(False, word_to_be_guessed) + + +def main(): + intro() + game_logic() + + +if __name__ == '__main__': + main() From 30e52e5bde40648fd5f7cdb71e4d2fe16f87b6be Mon Sep 17 00:00:00 2001 From: Conor Walker <2089327w@student.gla.ac.uk> Date: Tue, 1 Feb 2022 22:27:10 +0000 Subject: [PATCH 2/3] Extracts letter checking to its own (ugly) method --- src/pydle.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/pydle.py b/src/pydle.py index c6c6753..ba8eb26 100644 --- a/src/pydle.py +++ b/src/pydle.py @@ -3,6 +3,7 @@ import random import sys +# Gets the input from a user - number param is used to display the guess number the user is on def get_guess(number): validGuess = False guess = "" @@ -61,6 +62,22 @@ def game_over(user_was_right, correct_word): sys.exit(0) +# Takes in the users guess and the myriad lists involved in the game logic, and compares the letters in the guess +# with the word to be guessed. +# Inserts the letter into the appropriate list, based on its presence & position (or lack thereof) +def check_letter_in_word(users_guess_input, word_to_be_guessed, users_guess_results, present_in_word, not_in_word): + for i in range(len(users_guess_input)): + if word_to_be_guessed[i] == users_guess_input[i]: + users_guess_results[i] = users_guess_input[i] + elif users_guess_input[i] in word_to_be_guessed: + if users_guess_input[i] in users_guess_results and users_guess_input[i] not in word_to_be_guessed[i:]: + break + else: + present_in_word.add(users_guess_input[i]) + else: + not_in_word.add(users_guess_input[i]) + + # Main game flow. def game_logic(): not_in_word, present_in_word = set(), set() @@ -69,16 +86,7 @@ def game_logic(): while counter < 7: users_guess_input = get_guess(counter) users_guess_results = ["_"] * 5 - for i in range(len(users_guess_input)): - if word_to_be_guessed[i] == users_guess_input[i]: - users_guess_results[i] = users_guess_input[i] - elif users_guess_input[i] in word_to_be_guessed: - if users_guess_input[i] in users_guess_results and users_guess_input[i] not in word_to_be_guessed[i:]: - break - else: - present_in_word.add(users_guess_input[i]) - else: - not_in_word.add(users_guess_input[i]) + check_letter_in_word(users_guess_input, word_to_be_guessed, users_guess_results, present_in_word, not_in_word) if check_word_is_right(word_to_be_guessed, users_guess_results): game_over(True, word_to_be_guessed) print("Incorrect letters: " + ', '.join(not_in_word)) From b1172e5850151c1a1d95002c152bdf17f4b43996 Mon Sep 17 00:00:00 2001 From: Conor Walker <2089327w@student.gla.ac.uk> Date: Tue, 1 Feb 2022 22:37:41 +0000 Subject: [PATCH 3/3] Chooses word based on seed for consistency in a day --- src/pydle.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pydle.py b/src/pydle.py index ba8eb26..3f62320 100644 --- a/src/pydle.py +++ b/src/pydle.py @@ -1,6 +1,7 @@ import os import random import sys +from datetime import date # Gets the input from a user - number param is used to display the guess number the user is on @@ -22,10 +23,19 @@ def resource_path(relative_path): return os.path.join(base_path, relative_path) -# Gets a random word from a words.txt file present in the same directory as this script +# Gets a random word from a words.txt file present in the same directory as this script. +# If file is not present, uses a small fallback list of words. +# Shuffles based on a seed and selects a consistent member of the list to allow consistency between runs on same day. def get_random_word(): - lines = open(resource_path('words.txt')).read().splitlines() - return random.choice(lines) + lines = [] + try: + lines = open(resource_path('words.txt')).read().splitlines() + except IOError: + lines = ["Arrow", "Pride", "Whole", "React", "Chose", "Quote", "Adieu", "Story", "Whale", "Musty", "Korea", + "Snide", "Zebra", "Shite", "Plans", "Bride", "Blare", "Child", "Towns", "Treat", "Lusty", "Ocean"] + random.seed(int(date.today().day)) + random.shuffle(lines) + return lines[1] # Compares the users input with the word to be guessed. Returns true if the guess is correct, false otherwise