Skip to content

Commit ec9e566

Browse files
authored
Merge pull request #784 from LaneHesser/PCC02
PCC02 LaneHesser
2 parents a00dcf3 + 56ac849 commit ec9e566

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

02/LaneHesser/game.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!python3
2+
# Code Challenge 02 - Word Values Part II - a simple game
3+
# http://pybit.es/codechallenge02.html
4+
5+
import random
6+
from itertools import chain, permutations
7+
8+
from data import DICTIONARY, LETTER_SCORES, POUCH
9+
10+
11+
NUM_LETTERS = 7
12+
13+
14+
# re-use from challenge 01
15+
def calc_word_value(word):
16+
"""Calc a given word value based on Scrabble LETTER_SCORES mapping"""
17+
return sum(LETTER_SCORES.get(char.upper(), 0) for char in word)
18+
19+
20+
# re-use from challenge 01
21+
def max_word_value(words):
22+
"""Calc the max value of a collection of words"""
23+
return max(words, key=calc_word_value)
24+
25+
26+
def _permutations(iterable):
27+
"""Returns all possible permutations of the letters in draw."""
28+
return chain.from_iterable(permutations(iterable, n)
29+
for n in range(1, NUM_LETTERS+1))
30+
31+
32+
def calc_optimal_word(draw):
33+
"""Calculates optimal word (highest value) given the letters in draw"""
34+
permutations = _permutations(draw)
35+
36+
valid_words = set(
37+
''.join(word).lower()
38+
for word in permutations
39+
if ''.join(word).lower() in DICTIONARY
40+
)
41+
42+
max_word = max_word_value(valid_words).upper()
43+
max_val = calc_word_value(max_word)
44+
return max_word, max_val
45+
46+
47+
def draw_letters():
48+
"""Returns 7 random letters from POUCH"""
49+
return [
50+
random.choice(POUCH)
51+
for _ in range(NUM_LETTERS)
52+
]
53+
54+
55+
def get_user_input(draw):
56+
"""Asks the player to form a word with one or more letters from draw."""
57+
draw_copy = draw.copy()
58+
print('Letters drawn:', *draw_copy)
59+
60+
while True:
61+
word = input('Form a valid word: ').lower()
62+
63+
try:
64+
if word not in DICTIONARY:
65+
raise ValueError(f'{word} is not in the dictionary. Try again.')
66+
67+
word = word.upper()
68+
for letter in word:
69+
if letter not in draw_copy:
70+
raise ValueError(f'{letter} is not in draw. Try again.')
71+
else:
72+
draw_copy.remove(letter)
73+
74+
return word
75+
except ValueError as e:
76+
print(e)
77+
continue
78+
79+
80+
def main():
81+
draw = draw_letters()
82+
word = get_user_input(draw)
83+
word_value = calc_word_value(word)
84+
print(f'Word chosen: {word} (value: {word_value})')
85+
86+
optimal_word, optimal_val = calc_optimal_word(draw)
87+
print(f'Optimal word possible: {optimal_word} (value: {optimal_val})')
88+
89+
player_score = round((word_value / optimal_val) * 100, 1)
90+
print(f'You scored: {player_score}')
91+
92+
93+
if __name__ == "__main__":
94+
main()

0 commit comments

Comments
 (0)