X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=hangman%2Fhangman.py;h=f9a634c658ce7404b0d92d9c0391126ef0940a9d;hb=refs%2Fheads%2Fdevelopment;hp=4725c9dd22005a6d61225be2f5a42dad678c68b8;hpb=b3934d614b144fccdb085ebae9158f91b475b63d;p=cas-master-teacher-training.git diff --git a/hangman/hangman.py b/hangman/hangman.py index 4725c9d..f9a634c 100644 --- a/hangman/hangman.py +++ b/hangman/hangman.py @@ -1,33 +1,19 @@ - -# coding: utf-8 - -# In[4]: - import re import random import string import collections - -# In[5]: - WORDS = [w.strip() for w in open('/usr/share/dict/british-english').readlines() if re.match(r'^[a-z]*$', w.strip())] - -# In[6]: - LETTER_COUNTS = collections.Counter(l.lower() for l in open('../sherlock-holmes.txt').read() if l in string.ascii_letters) LETTERS_IN_ORDER = [p[0] for p in LETTER_COUNTS.most_common()] - -# In[7]: +DICT_COUNTS = collections.Counter(''.join(WORDS)) +DICT_LETTERS_IN_ORDER = [p[0] for p in DICT_COUNTS.most_common()] STARTING_LIVES = 10 - -# In[8]: - class Game: def __init__(self, target, player=None, lives=STARTING_LIVES): self.lives = lives @@ -88,23 +74,38 @@ class Game: return self.game_won -# In[9]: +class PlayerFixedOrder: + def __init__(self, ordered_letters): + self.ordered_letters = ordered_letters + + def guess(self, discovered, missed, lives): + return [l for l in self.ordered_letters if l not in discovered + missed][0] + +class PlayerAlphabetical(PlayerFixedOrder): + def __init__(self): + super().__init__(string.ascii_lowercase) -DICT_COUNTS = collections.Counter(l.lower() for l in open('/usr/share/dict/british-english').read() if l in string.ascii_letters) -DICT_LETTERS_IN_ORDER = [p[0] for p in DICT_COUNTS.most_common()] +class PlayerAlphabeticalReversed(PlayerFixedOrder): + def __init__(self): + super().__init__(list(reversed(string.ascii_lowercase))) + +class PlayerFreqOrdered(PlayerFixedOrder): + def __init__(self): + super().__init__(LETTERS_IN_ORDER) +class PlayerDictFreqOrdered(PlayerFixedOrder): + def __init__(self): + super().__init__(DICT_LETTERS_IN_ORDER) -# In[10]: -class PlayerAdaptiveNoRegex: +class PlayerAdaptive: def __init__(self, words): self.candidate_words = words def guess(self, discovered, missed, lives): self.filter_candidate_words(discovered, missed) self.set_ordered_letters() - guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters] - return [l for l in self.ordered_letters if l not in guessed_letters][0] + return [l for l in self.ordered_letters if l not in discovered + missed][0] def filter_candidate_words(self, discovered, missed): pass @@ -131,10 +132,7 @@ class PlayerAdaptiveNoRegex: return False return True - -# In[11]: - -class PlayerAdaptiveLengthNoRegex(PlayerAdaptiveNoRegex): +class PlayerAdaptiveLength(PlayerAdaptive): def __init__(self, words): super().__init__(words) self.word_len = None @@ -150,247 +148,29 @@ class PlayerAdaptiveLengthNoRegex(PlayerAdaptiveNoRegex): super().set_ordered_letters() -# In[12]: - -class PlayerAdaptiveIncludedLettersNoRegex(PlayerAdaptiveNoRegex): +class PlayerAdaptiveIncludedLetters(PlayerAdaptive): def filter_candidate_words(self, discovered, missed): self.candidate_words = [w for w in self.candidate_words if self.match(discovered, w)] -# In[13]: - -class PlayerAdaptiveExcludedLettersNoRegex(PlayerAdaptiveNoRegex): +class PlayerAdaptiveExcludedLetters(PlayerAdaptive): def filter_candidate_words(self, discovered, missed): if missed: empty_target = '_' * len(discovered) self.candidate_words = [w for w in self.candidate_words if self.match(empty_target, w, missed)] -# In[14]: - -class PlayerAdaptivePatternNoRegex(PlayerAdaptiveNoRegex): +class PlayerAdaptivePattern(PlayerAdaptive): def filter_candidate_words(self, discovered, missed): attempted_letters = [l for l in discovered if l != '_'] + missed self.candidate_words = [w for w in self.candidate_words if self.match(discovered, w, attempted_letters)] -# In[15]: - -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)') - - -# In[21]: - -len([w for w in WORDS if 'r' in w]) - - -# In[22]: - -len([w for w in WORDS if 'r' not in w]) - - -# In[19]: - -letter_diffs = [] -for l in string.ascii_lowercase: - n = 0 - for w in WORDS: - if l in w: - n += 1 - else: - n -=1 - letter_diffs += [(l, abs(n))] -sorted(letter_diffs, key=lambda p: p[1]) - - -# In[23]: - -def letter_diff(l): - return abs(sum(1 if l in w else -1 for w in WORDS)) - -letter_diffs = [(l, letter_diff(l)) - for l in string.ascii_lowercase] -sorted(letter_diffs, key=lambda p: p[1]) - - -# In[71]: - -class PlayerAdaptiveSplit(PlayerAdaptivePatternNoRegex): +class PlayerAdaptiveSplit(PlayerAdaptivePattern): def set_ordered_letters(self): def letter_diff(l): return abs(sum(1 if l in w else -1 for w in self.candidate_words)) possible_letters = set(''.join(self.candidate_words)) - # if len(self.candidate_words) > 1: letter_diffs = [(l, letter_diff(l)) for l in possible_letters] self.ordered_letters = [p[0] for p in sorted(letter_diffs, key=lambda p: p[1])] - # else: - # self.ordered_letters = list(self.candidate_words[0]) - - -# In[72]: - -g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS)) -g.play_game() - - -# In[73]: - -g.target - - -# In[74]: - -g.discovered - - -# In[75]: - -g.wrong_letters - - -# In[78]: - -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)') - - -# In[54]: - -p=PlayerAdaptiveSplit(WORDS) - - -# In[55]: - -dsc = ['_'] * len('recognition') -dsc - - -# In[56]: - -p.guess(dsc, [], 10) - - -# In[57]: - -len(p.candidate_words) - - -# In[58]: - -p.guess(['_', '_', '_', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10) - - -# In[59]: - -p.candidate_words - - -# In[60]: - -p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10) - - -# In[61]: - -p.candidate_words - - -# In[62]: - -p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a'], 9) - - -# In[63]: - -p.candidate_words - - -# In[64]: - -p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a', 'd'], 8) - - -# In[65]: - -p.candidate_words - - -# In[67]: - -g = Game('recognition', player=PlayerAdaptiveSplit(WORDS)) -g.play_game() - - -# In[68]: - -g.discovered - - -# In[69]: - -g.lives - - -# In[79]: - -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)') - - -# In[81]: - -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)') - - -# In[90]: - -for w in random.sample(WORDS, 5000): - gp = Game(w, player=PlayerAdaptivePatternNoRegex(WORDS)) - gp.play_game() - gs = Game(w, player=PlayerAdaptiveSplit(WORDS)) - gs.play_game() - if not gp.game_won and not gs.game_won: - print('Both:::::', gp.target, 'Pattern:', '[' + ' '.join(gp.discovered) + ']', ''.join(gp.wrong_letters), - ':: Split:', '[' + ' '.join(gs.discovered) + ']', ''.join(gs.wrong_letters)) - if not gp.game_won and gs.game_won: - print('Pattern::', gp.target, '[' + ' '.join(gp.discovered) + ']', ''.join(gp.wrong_letters)) - if gp.game_won and not gs.game_won: - print('Split::::', gs.target, '[' + ' '.join(gs.discovered) + ']', ''.join(gs.wrong_letters)) - - -# In[91]: - -gs = Game('businesses', player=PlayerAdaptiveSplit(WORDS)) - - -# In[170]: - -g = Game('feminism', player=PlayerAdaptiveSplit(WORDS)) -while not g.game_finished: - guess = g.player.guess(g.discovered, g.wrong_letters, g.lives) - print(g.target, '(' + str(g.lives) + ')', - '[' + ' '.join(g.discovered) + ']', ''.join(g.wrong_letters), - ';', len(g.player.candidate_words), 'candidate words') - print('Guess = ', guess) - g.do_turn() - - -# In[172]: - -g = Game('feminism', player=PlayerAdaptivePatternNoRegex(WORDS)) -while not g.game_finished: - guess = g.player.guess(g.discovered, g.wrong_letters, g.lives) - print(g.target, '(' + str(g.lives) + ')', - '[' + ' '.join(g.discovered) + ']', ''.join(g.wrong_letters), - ';', len(g.player.candidate_words), 'candidate words') - print('Guess = ', guess) - g.do_turn() - - -# In[171]: - -g.player.candidate_words - - -# In[ ]: - -