14 WORDS
= [w
.strip() for w
in open('/usr/share/dict/british-english').readlines()
15 if re
.match(r
'^[a-z]*$', w
.strip())]
20 LETTER_COUNTS
= collections
.Counter(l
.lower() for l
in open('../sherlock-holmes.txt').read() if l
in string
.ascii_letters
)
21 LETTERS_IN_ORDER
= [p
[0] for p
in LETTER_COUNTS
.most_common()]
32 def __init__(self
, target
, player
=None, lives
=STARTING_LIVES
):
36 self
.discovered
= list('_' * len(target
))
37 self
.wrong_letters
= []
38 self
.game_finished
= False
40 self
.game_lost
= False
42 def find_all(self
, letter
):
43 return [p
for p
, l
in enumerate(self
.target
) if l
== letter
]
45 def update_discovered_word(self
, guessed_letter
):
46 locations
= self
.find_all(guessed_letter
)
47 for location
in locations
:
48 self
.discovered
[location
] = guessed_letter
49 return self
.discovered
53 guess
= self
.player
.guess(self
.discovered
, self
.wrong_letters
, self
.lives
)
55 guess
= self
.ask_for_guess()
56 if guess
in self
.target
:
57 self
.update_discovered_word(guess
)
60 if guess
not in self
.wrong_letters
:
61 self
.wrong_letters
+= [guess
]
63 self
.game_finished
= True
65 if '_' not in self
.discovered
:
66 self
.game_finished
= True
69 def ask_for_guess(self
):
70 print('Word:', ' '.join(self
.discovered
),
71 ' : Lives =', self
.lives
,
72 ', wrong guesses:', ' '.join(sorted(self
.wrong_letters
)))
73 guess
= input('Enter letter: ').strip().lower()[0]
77 while not self
.game_finished
:
83 def report_on_game(self
):
85 print('You won! The word was', self
.target
)
87 print('You lost. The word was', self
.target
)
93 DICT_COUNTS
= collections
.Counter(l
.lower() for l
in open('/usr/share/dict/british-english').read() if l
in string
.ascii_letters
)
94 DICT_LETTERS_IN_ORDER
= [p
[0] for p
in DICT_COUNTS
.most_common()]
99 class PlayerAdaptiveNoRegex
:
100 def __init__(self
, words
):
101 self
.candidate_words
= words
103 def guess(self
, discovered
, missed
, lives
):
104 self
.filter_candidate_words(discovered
, missed
)
105 self
.set_ordered_letters()
106 guessed_letters
= [l
.lower() for l
in discovered
+ missed
if l
in string
.ascii_letters
]
107 return [l
for l
in self
.ordered_letters
if l
not in guessed_letters
][0]
109 def filter_candidate_words(self
, discovered
, missed
):
112 def set_ordered_letters(self
):
113 counts
= collections
.Counter(l
.lower()
114 for l
in ''.join(self
.candidate_words
) + string
.ascii_lowercase
115 if l
in string
.ascii_letters
)
116 self
.ordered_letters
= [p
[0] for p
in counts
.most_common()]
118 def match(self
, pattern
, target
, excluded
=None):
121 if len(pattern
) != len(target
):
123 for m
, c
in zip(pattern
, target
):
124 if m
== '_' and c
not in excluded
:
127 elif m
!= '_' and m
== c
:
137 class PlayerAdaptiveLengthNoRegex(PlayerAdaptiveNoRegex
):
138 def __init__(self
, words
):
139 super().__init
__(words
)
141 self
.ordered_letters
= None
143 def filter_candidate_words(self
, discovered
, missed
):
144 if not self
.word_len
:
145 self
.word_len
= len(discovered
)
146 self
.candidate_words
= [w
for w
in self
.candidate_words
if len(w
) == self
.word_len
]
148 def set_ordered_letters(self
):
149 if not self
.ordered_letters
:
150 super().set_ordered_letters()
155 class PlayerAdaptiveIncludedLettersNoRegex(PlayerAdaptiveNoRegex
):
156 def filter_candidate_words(self
, discovered
, missed
):
157 self
.candidate_words
= [w
for w
in self
.candidate_words
if self
.match(discovered
, w
)]
162 class PlayerAdaptiveExcludedLettersNoRegex(PlayerAdaptiveNoRegex
):
163 def filter_candidate_words(self
, discovered
, missed
):
165 empty_target
= '_' * len(discovered
)
166 self
.candidate_words
= [w
for w
in self
.candidate_words
if self
.match(empty_target
, w
, missed
)]
171 class PlayerAdaptivePatternNoRegex(PlayerAdaptiveNoRegex
):
172 def filter_candidate_words(self
, discovered
, missed
):
173 attempted_letters
= [l
for l
in discovered
if l
!= '_'] + missed
174 self
.candidate_words
= [w
for w
in self
.candidate_words
if self
.match(discovered
, w
, attempted_letters
)]
179 get_ipython().run_cell_magic('timeit', '', '\nwins = 0\nfor _ in range(1000):\n g = Game(random.choice(WORDS), player=PlayerAdaptivePatternNoRegex(WORDS))\n g.play_game()\n if g.game_won:\n wins += 1\nprint(wins)')
184 len([w
for w
in WORDS
if 'r' in w
])
189 len([w
for w
in WORDS
if 'r' not in w
])
195 for l
in string
.ascii_lowercase
:
202 letter_diffs
+= [(l
, abs(n
))]
203 sorted(letter_diffs
, key
=lambda p
: p
[1])
209 return abs(sum(1 if l
in w
else -1 for w
in WORDS
))
211 letter_diffs
= [(l
, letter_diff(l
))
212 for l
in string
.ascii_lowercase
]
213 sorted(letter_diffs
, key
=lambda p
: p
[1])
218 class PlayerAdaptiveSplit(PlayerAdaptivePatternNoRegex
):
219 def set_ordered_letters(self
):
221 return abs(sum(1 if l
in w
else -1 for w
in self
.candidate_words
))
222 possible_letters
= set(''.join(self
.candidate_words
))
223 # if len(self.candidate_words) > 1:
224 letter_diffs
= [(l
, letter_diff(l
)) for l
in possible_letters
]
225 self
.ordered_letters
= [p
[0] for p
in sorted(letter_diffs
, key
=lambda p
: p
[1])]
227 # self.ordered_letters = list(self.candidate_words[0])
232 g
= Game(random
.choice(WORDS
), player
=PlayerAdaptiveSplit(WORDS
))
253 get_ipython().run_cell_magic('timeit', '', '\nwins = 0\nfor _ in range(1000):\n g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS))\n g.play_game()\n if g.game_won:\n wins += 1\nprint(wins)')
258 p
=PlayerAdaptiveSplit(WORDS
)
263 dsc
= ['_'] * len('recognition')
274 len(p
.candidate_words
)
279 p
.guess(['_', '_', '_', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10)
289 p
.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10)
299 p
.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a'], 9)
309 p
.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a', 'd'], 8)
319 g
= Game('recognition', player
=PlayerAdaptiveSplit(WORDS
))
335 get_ipython().run_cell_magic('timeit', '', '\nwins = 0\nfor _ in range(10000):\n g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS))\n g.play_game()\n if g.game_won:\n wins += 1\nprint(wins)')
340 get_ipython().run_cell_magic('timeit', '', '\nwins = 0\nfor _ in range(10000):\n g = Game(random.choice(WORDS), player=PlayerAdaptivePatternNoRegex(WORDS))\n g.play_game()\n if g.game_won:\n wins += 1\nprint(wins)')
345 for w
in random
.sample(WORDS
, 5000):
346 gp
= Game(w
, player
=PlayerAdaptivePatternNoRegex(WORDS
))
348 gs
= Game(w
, player
=PlayerAdaptiveSplit(WORDS
))
350 if not gp
.game_won
and not gs
.game_won
:
351 print('Both:::::', gp
.target
, 'Pattern:', '[' + ' '.join(gp
.discovered
) + ']', ''.join(gp
.wrong_letters
),
352 ':: Split:', '[' + ' '.join(gs
.discovered
) + ']', ''.join(gs
.wrong_letters
))
353 if not gp
.game_won
and gs
.game_won
:
354 print('Pattern::', gp
.target
, '[' + ' '.join(gp
.discovered
) + ']', ''.join(gp
.wrong_letters
))
355 if gp
.game_won
and not gs
.game_won
:
356 print('Split::::', gs
.target
, '[' + ' '.join(gs
.discovered
) + ']', ''.join(gs
.wrong_letters
))
361 gs
= Game('businesses', player
=PlayerAdaptiveSplit(WORDS
))
366 g
= Game('feminism', player
=PlayerAdaptiveSplit(WORDS
))
367 while not g
.game_finished
:
368 guess
= g
.player
.guess(g
.discovered
, g
.wrong_letters
, g
.lives
)
369 print(g
.target
, '(' + str(g
.lives
) + ')',
370 '[' + ' '.join(g
.discovered
) + ']', ''.join(g
.wrong_letters
),
371 ';', len(g
.player
.candidate_words
), 'candidate words')
372 print('Guess = ', guess
)
378 g
= Game('feminism', player
=PlayerAdaptivePatternNoRegex(WORDS
))
379 while not g
.game_finished
:
380 guess
= g
.player
.guess(g
.discovered
, g
.wrong_letters
, g
.lives
)
381 print(g
.target
, '(' + str(g
.lives
) + ')',
382 '[' + ' '.join(g
.discovered
) + ']', ''.join(g
.wrong_letters
),
383 ';', len(g
.player
.candidate_words
), 'candidate words')
384 print('Guess = ', guess
)
390 g
.player
.candidate_words