Éléments de corrigé
Fichier de test test_hang.py
import unittest
from hangman import print_check
from hangman import check_guess
from hangman import get_guessed_word
from hangman import check_guessed_word
from hangman import calc_score
class TestHangman (unittest.TestCase) :
def test_check_word(self):
self.assertTrue(print_check('python', 'yponth'))
self.assertTrue(print_check('', ''))
self.assertTrue(print_check('', 'c'))
self.assertFalse(print_check('c', ''))
self.assertTrue(print_check('python', 'yponths'))
self.assertFalse(print_check('pythons', 'yponth'))
def test_update_turns(self):
self.assertEqual(check_guess('p', 'python', 9), (True, 9))
self.assertEqual(check_guess('a', 'python', 9), (False, 8))
self.assertEqual(check_guess('', '', 9), (True, 9))
self.assertEqual(check_guess('', 'c', 9), (True, 9))
self.assertEqual(check_guess('a', '', 9), (False, 8))
def test_get_guessed_word(self):
self.assertEqual(get_guessed_word('', ''),'')
self.assertEqual(get_guessed_word('', 'c'),'')
self.assertEqual(get_guessed_word('centralesupelec', ''),'***************')
self.assertEqual(get_guessed_word('centralesupelec', 'c'),'c*************c')
self.assertEqual(get_guessed_word('centralesupelec', 'cs'),'c*******s*****c')
self.assertEqual(get_guessed_word('centralesupelec', 'centralsup'),'centralesupelec')
self.assertEqual(get_guessed_word('centralesupelec', 'supcentral'),'centralesupelec')
def test_check_guessed_word(self):
self.assertTrue(check_guessed_word('', ''))
self.assertTrue(check_guessed_word('', 'c'))
self.assertFalse(check_guessed_word('centralesupelec', ''))
self.assertFalse(check_guessed_word('centralesupelec', 'cs'))
self.assertTrue(check_guessed_word('centralesupelec', 'centralsup'))
self.assertTrue(check_guessed_word('centralesupelec', 'supcentral'))
def test_calc_score(self):
self.assertEqual(calc_score('', 0), 0)
self.assertEqual(calc_score('guess', 4), 9)
self.assertEqual(calc_score('guess', 8), 5)
if __name__ == '__main__':
unittest.main()
Fichier hangman.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)
if len(probs) == 0 :
# No more choices (word is not in dictionnary)
break
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.")