Skip to content

Instantly share code, notes, and snippets.

@tompretty
Created May 21, 2020 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompretty/744198635b1318275e76a4fa63e819f1 to your computer and use it in GitHub Desktop.
Save tompretty/744198635b1318275e76a4fa63e819f1 to your computer and use it in GitHub Desktop.
import random
from collections import Counter
# - 1 point: E, A, I, O, N, R, T, L, S, U
# - 2 points: D, G
# - 3 points: B, C, M, P
# - 4 points: F, H, V, W, Y
# - 5 points: K
# - 8 points: J, X
# - 10 points: Q, Z
class Word:
LETTER_SCORES = {
"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 __init__(self, word):
if not isinstance(word, str):
raise ValueError
self.word = word.upper()
self.letter_counts = Counter(self.word)
def score(self):
return sum(Word.LETTER_SCORES[letter] for letter in self.word)
def score_with_a_triple_letter(self):
pass
def can_be_made_from(self, player_tiles_counts):
for letter, count in self.letter_counts.items():
if player_tiles_counts[letter] < count:
return False
return True
class Bag:
def draw_tiles(self, num_tiles):
pass
# - 12 tiles: E
# - 9 tiles: A,I
# - 8 tiles: O
# - 6 tiles: N,R,T
# - 4 tiles: L,S,U,D
# - 3 tiles: G
# - 2 tiles: B,C,M,P,F,H,V,W,Y
# - 1 tiles: K,J,X,Q,Z
class EnglishDistributionBag(Bag):
LETTER_DISTIBUTION = {
"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,
}
def __init__(self):
self.tiles = []
for letter, count in EnglishDistributionBag.LETTER_DISTIBUTION.items():
self.tiles += [letter] * count
random.shuffle(self.tiles)
def __len__(self):
return len(self.tiles)
def draw_tiles(self, num_tiles):
return [self.tiles.pop() for _ in range(num_tiles)]
def load_words():
with open("words.txt") as f:
raw_words = f.read().split("\n")
return [Word(raw_word) for raw_word in raw_words]
if __name__ == "__main__":
word = Word("GUARDIAN")
print(word.score())
words = load_words()
bag = EnglishDistributionBag()
player_tiles = bag.draw_tiles(7)
player_tiles_counts = Counter(player_tiles)
playable_words = [
word for word in words if word.can_be_made_from(player_tiles_counts)
]
highest_scoring_word = max(playable_words, key=lambda word: word.score())
print(player_tiles)
print(highest_scoring_word.word)
import unittest
from pairing_exercise import EnglishDistributionBag, Word
class TestPairingExercise(unittest.TestCase):
def test_unit_tests(self):
self.assertTrue(True, "Failed!")
class TestWord(unittest.TestCase):
def test_score_ignores_casing(self):
word = Word("GuaRdIAn")
self.assertEqual(word.score(), 10)
def test_raises_value_error_on_number_input(self):
with self.assertRaises(ValueError):
Word(123)
def test_raises_value_error_one_invalid_characters(self):
pass
class TestEnglishDistributionBag(unittest.TestCase):
def test_correct_number_of_tiles_are_in_the_bag(self):
bag = EnglishDistributionBag()
self.assertEqual(len(bag), 98)
def test_draw_tiles_reduces_bag_size_by_number_of_tiles_drawn(self):
bag = EnglishDistributionBag()
bag.draw_tiles(7)
self.assertEqual(len(bag), 91)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment