Le sujet SIP-TD11.pdf
Éléments de corrigé
Fichier de test test_td11.py
import pytest import td11 def test_check_word() : assert td11.print_check('python', 'yponth') assert td11.print_check('', '') assert td11.print_check('', 'c') assert not td11.print_check('c', '') assert td11.print_check('python', 'yponths') assert not td11.print_check('pythons', 'yponth') def test_update_turns(): assert td11.check_guess('p', 'python', 9) == (True, 9) assert td11.check_guess('a', 'python', 9) == (False, 8) assert td11.check_guess('', '', 9) == (True, 9) assert td11.check_guess('', 'c', 9) == (True, 9) assert td11.check_guess('a', '', 9) == (False, 8) def test_get_guessed_word(): assert td11.get_guessed_word('', '') == '' assert td11.get_guessed_word('', 'c') == '' assert td11.get_guessed_word('centralesupelec', '') == '***************' assert td11.get_guessed_word('centralesupelec', 'c') == 'c*************c' assert td11.get_guessed_word('centralesupelec', 'cs') == 'c*******s*****c' assert td11.get_guessed_word('centralesupelec', 'centralsup') == 'centralesupelec' assert td11.get_guessed_word('centralesupelec', 'supcentral') == 'centralesupelec' def test_check_guessed_word(): assert td11.check_guessed_word('', '') assert td11.check_guessed_word('', 'c') assert not td11.check_guessed_word('centralesupelec', '') assert not td11.check_guessed_word('centralesupelec', 'cs') assert td11.check_guessed_word('centralesupelec', 'centralsup') assert td11.check_guessed_word('centralesupelec', 'supcentral') def test_calc_score(): assert td11.calc_score('', 0) == 0 assert td11.calc_score('guess', 4) == 9 assert td11.calc_score('guess', 8) == 5
Fichier td11.py
import random def raw_version() : AA = ("python", "information", "systems", "programming", "centralesupelec") a = random.choice(AA) b = '' c = 10 while c > 0: d = 0 for e in a: if e in b: print(e) else: print("*") d += 1 if d == 0: print("You won") break f = input("guess a character:") b += f if f not in a: c -= 1 print("Wrong, you have ", + c, "more guesses") if c == 0: print("You Lost, the word was: " + a) def clean_version() : words = ("python", "information", "systems", "programming", "centralesupelec") word = random.choice(words) guessed = '' rem_turns = 10 while rem_turns > 0: nb_missing = 0 for letter in word: if letter in guessed: print(letter) else: print("*") nb_missing += 1 if nb_missing == 0: print("You won") break guess = input("guess a character:") if guess not in word: rem_turns -= 1 if rem_turns == 0: print("Wrong guess, you lose, the word was: " + word) else: print("Wrong, you have ", + rem_turns, "more guesses") else : guessed += guess # Structured version def print_check(word, guessed) : wins = True for letter in word: if letter in guessed: print(letter) else: print("*") wins = False return wins def check_guess(guess, word, turns) : good_guess = True if guess not in word : turns -= 1 good_guess = False if turns == 0: print("Wrong guess, you lose, the word was: " + word) else: print("Wrong, you have ", + turns, "more guesses") return (good_guess, turns) def simple_game(word, turns) : guessed = '' rem_turns = turns while rem_turns > 0: if print_check(word, guessed) : print("You win!") break guess = input("guess a character:") (good_guess, rem_turns) = check_guess(guess, word, rem_turns) if good_guess: guessed += guess # simple_game(random.choice(("python", "information", "systems", "programming", "centralesupelec")), 9) # Full version # Ex 5 def get_guessed_word(secret_word, letters_guessed): masked_word = "" for l in secret_word : if l in letters_guessed : masked_word += l else: masked_word += '*' return masked_word # Ex 6 def check_guessed_word(secret_word, letters_guessed) : return "*" not in get_guessed_word(secret_word, letters_guessed) # Ex 7 def word_game(secret_word, max_guesses) : letters_guessed = '' available_letters = [chr(i) for i in range(ord('a'), ord('z') + 1)] num_guesses = 0 while not check_guessed_word(secret_word, letters_guessed) \ and num_guesses < max_guesses : print(max_guesses - num_guesses, " guesses left") print("available letters: ", available_letters) # guess = input("Your guess: ") guess = validate_input(input("Your guess: ")) num_guesses += 1 if guess in available_letters : available_letters.remove(guess) if guess in secret_word : letters_guessed += guess print("Good: ", get_guessed_word(secret_word, letters_guessed)) else: print("Sorry: ", get_guessed_word(secret_word, letters_guessed)) else: print("Be careful, just just wasted a guess on an already tested letter!") if check_guessed_word(secret_word, letters_guessed) : return num_guesses else: return -1 # Ex 8 def calc_max_guesses(secret_word) : # Allow two guesses for each distinct letter return len(set(secret_word)) * 2 scrabble_values = { '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 calc_score(secret_word, num_guesses, letter_values = scrabble_values) : score = 0 for l in set(secret_word): score += letter_values[l] score += calc_max_guesses(secret_word) - num_guesses return score def real_word_game(secret_word) : n = word_game(secret_word, calc_max_guesses(secret_word)) if n < 0 : print("You lose.") else: print("You win with score: ", calc_score(secret_word, n)) def validate_input(l) : if l.isalpha() : return l else: return validate_input(input("# Invalid input, please type only letters: ")) # Ex 10 def guess_whole_word(secret_word): guess = validate_input(input("guess a word: ")) if guess == secret_word : return 0 # As if guessed in no turn else: return -1 def word_game_w(secret_word, max_guesses) : letters_guessed = '' available_letters = [chr(i) for i in range(ord('a'), ord('z') + 1)] num_guesses = 0 while not check_guessed_word(secret_word, letters_guessed) \ and num_guesses < max_guesses : print(max_guesses - num_guesses, " guesses left") print("available letters: ", available_letters) guess = input("Your guess, or * for guessing the whole word: ") if guess == "*": return guess_whole_word(secret_word) guess = validate_input(guess) num_guesses += 1 if guess in available_letters : available_letters.remove(guess) if guess in secret_word : letters_guessed += guess print("Good: ", get_guessed_word(secret_word, letters_guessed)) else: print("Sorry: ", get_guessed_word(secret_word, letters_guessed)) else: print("Be careful, just just wasted a guess on an already tested letter!") if check_guessed_word(secret_word, letters_guessed) : return num_guesses else: return -1 def real_word_game_w(secret_word) : n = word_game_w(secret_word, calc_max_guesses(secret_word)) if n < 0 : print("You lose.") else: print("You win with score: ", calc_score(secret_word, n)) # Ex 11 def random_word_game(secret_word, max_guesses) : letters_guessed = '' available_letters = [chr(i) for i in range(ord('a'), ord('z') + 1)] num_guesses = 0 while not check_guessed_word(secret_word, letters_guessed) \ and num_guesses < max_guesses : print(max_guesses - num_guesses, " guesses left") print("available letters: ", available_letters) guess = random.choice(available_letters) num_guesses += 1 available_letters.remove(guess) if guess in secret_word : letters_guessed += guess print(guess, " is good: ", get_guessed_word(secret_word, letters_guessed)) else: print(guess, " is not in the word: ", get_guessed_word(secret_word, letters_guessed)) if check_guessed_word(secret_word, letters_guessed) : return num_guesses else: return -1 # Ex 12 def match(word, guess_pattern, letters_tried): """ Check if a word is a possible solution according to the guess pattern and the letters that have already been tried. :param word: the word to test :param guess_pattern: the guess pattern, which is the secret word with '*' in place of not yet guessed letters :param letters_tried: the letters that have already been tried to guess the secret word :return: True if the word can be the secret word, else False """ if len(word) != len(guess_pattern) : # If the word does not have the right length, we can reject it return False for i in range(len(guess_pattern)) : # Check if the word matches the current guess (with '*' in place of not yet guessed characters) if guess_pattern[i] != "*" and guess_pattern[i] != word[i] : return False # Ignore words that contains already tried letters which are not in the pattern if not word[i] in guess_pattern and word[i] in letters_tried : return False return True def probabilities(guess_pattern, letters_tried, dic): # Filter out words that cannot be the secret one possible_words = [word for word in dic if match(word, guess_pattern, letters_tried)] print("# possibilities for ", guess_pattern, ": ", possible_words) # Count the number of occurrences of a character frequencies = {} for word in possible_words : for c in word : if c in letters_tried : # Ignore already characters that have already been tried continue if c in frequencies : frequencies[c] += 1 else: frequencies[c] = 1 print("# freq for ", guess_pattern, ": ", frequencies) # Get the total number of distinct characters total_chars = sum(frequencies.values()) # Fill the table of probabilities prob = {} for c in frequencies.keys() : prob[c] = frequencies[c] / total_chars return prob def ai_word_game(secret_word): with open("../dic.txt", "r") as dict_file : words = dict_file.read().lower().splitlines() dic = [word.replace("-", "").replace("-", "") for word in words] letters_tried = '' num_guesses = 0 max_guesses = calc_max_guesses(secret_word) while num_guesses < max_guesses \ and not check_guessed_word(secret_word, letters_tried) : probs = probabilities(get_guessed_word(secret_word, letters_tried), letters_tried, dic) guess = max(probs, key=probs.get) num_guesses += 1 letters_tried += guess if guess in secret_word : print(guess, " is good: ", get_guessed_word(secret_word, letters_tried)) else: print(guess, " is not in the word: ", get_guessed_word(secret_word, letters_tried)) if check_guessed_word(secret_word, letters_tried) : print("AI wins with score: ", calc_score(secret_word, num_guesses)) else: print("AI loses.")