--- /dev/null
+{
+ "metadata": {
+ "name": "",
+ "signature": "sha256:5a2b414ce60f525ddfcbb85f2b57ef6ecf5d08662151337bdc833cd40f541f71"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "import re\n",
+ "import random\n",
+ "import string\n",
+ "import collections"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 4
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "WORDS = [w.strip() for w in open('/usr/share/dict/british-english').readlines() \n",
+ " if re.match(r'^[a-z]*$', w.strip())]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 5
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "LETTER_COUNTS = collections.Counter(l.lower() for l in open('../sherlock-holmes.txt').read() if l in string.ascii_letters)\n",
+ "LETTERS_IN_ORDER = [p[0] for p in LETTER_COUNTS.most_common()]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 6
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "STARTING_LIVES = 10"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 7
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class Game:\n",
+ " def __init__(self, target, player=None, lives=STARTING_LIVES):\n",
+ " self.lives = lives\n",
+ " self.player = player\n",
+ " self.target = target\n",
+ " self.discovered = list('_' * len(target))\n",
+ " self.wrong_letters = []\n",
+ " self.game_finished = False\n",
+ " self.game_won = False\n",
+ " self.game_lost = False\n",
+ " \n",
+ " def find_all(self, letter):\n",
+ " return [p for p, l in enumerate(self.target) if l == letter]\n",
+ " \n",
+ " def update_discovered_word(self, guessed_letter):\n",
+ " locations = self.find_all(guessed_letter)\n",
+ " for location in locations:\n",
+ " self.discovered[location] = guessed_letter\n",
+ " return self.discovered\n",
+ " \n",
+ " def do_turn(self):\n",
+ " if self.player:\n",
+ " guess = self.player.guess(self.discovered, self.wrong_letters, self.lives)\n",
+ " else:\n",
+ " guess = self.ask_for_guess()\n",
+ " if guess in self.target:\n",
+ " self.update_discovered_word(guess)\n",
+ " else:\n",
+ " self.lives -= 1\n",
+ " if guess not in self.wrong_letters:\n",
+ " self.wrong_letters += [guess]\n",
+ " if self.lives == 0:\n",
+ " self.game_finished = True\n",
+ " self.game_lost = True\n",
+ " if '_' not in self.discovered:\n",
+ " self.game_finished = True\n",
+ " self.game_won = True\n",
+ " \n",
+ " def ask_for_guess(self):\n",
+ " print('Word:', ' '.join(self.discovered), \n",
+ " ' : Lives =', self.lives, \n",
+ " ', wrong guesses:', ' '.join(sorted(self.wrong_letters)))\n",
+ " guess = input('Enter letter: ').strip().lower()[0]\n",
+ " return guess\n",
+ " \n",
+ " def play_game(self):\n",
+ " while not self.game_finished:\n",
+ " self.do_turn()\n",
+ " if not self.player:\n",
+ " self.report_on_game()\n",
+ " return self.game_won\n",
+ " \n",
+ " def report_on_game(self):\n",
+ " if self.game_won:\n",
+ " print('You won! The word was', self.target)\n",
+ " else:\n",
+ " print('You lost. The word was', self.target)\n",
+ " return self.game_won"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 8
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "DICT_COUNTS = collections.Counter(l.lower() for l in open('/usr/share/dict/british-english').read() if l in string.ascii_letters)\n",
+ "DICT_LETTERS_IN_ORDER = [p[0] for p in DICT_COUNTS.most_common()]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 9
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptiveNoRegex:\n",
+ " def __init__(self, words):\n",
+ " self.candidate_words = words\n",
+ " \n",
+ " def guess(self, discovered, missed, lives):\n",
+ " self.filter_candidate_words(discovered, missed)\n",
+ " self.set_ordered_letters()\n",
+ " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
+ " return [l for l in self.ordered_letters if l not in guessed_letters][0]\n",
+ " \n",
+ " def filter_candidate_words(self, discovered, missed):\n",
+ " pass\n",
+ " \n",
+ " def set_ordered_letters(self):\n",
+ " counts = collections.Counter(l.lower() \n",
+ " for l in ''.join(self.candidate_words) + string.ascii_lowercase \n",
+ " if l in string.ascii_letters)\n",
+ " self.ordered_letters = [p[0] for p in counts.most_common()]\n",
+ "\n",
+ " def match(self, pattern, target, excluded=None):\n",
+ " if not excluded:\n",
+ " excluded = ''\n",
+ " if len(pattern) != len(target):\n",
+ " return False\n",
+ " for m, c in zip(pattern, target):\n",
+ " if m == '_' and c not in excluded:\n",
+ " # true\n",
+ " pass\n",
+ " elif m != '_' and m == c:\n",
+ " # true\n",
+ " pass\n",
+ " else:\n",
+ " return False\n",
+ " return True "
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 10
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptiveLengthNoRegex(PlayerAdaptiveNoRegex):\n",
+ " def __init__(self, words):\n",
+ " super().__init__(words)\n",
+ " self.word_len = None\n",
+ " self.ordered_letters = None\n",
+ " \n",
+ " def filter_candidate_words(self, discovered, missed):\n",
+ " if not self.word_len:\n",
+ " self.word_len = len(discovered)\n",
+ " self.candidate_words = [w for w in self.candidate_words if len(w) == self.word_len]\n",
+ " \n",
+ " def set_ordered_letters(self):\n",
+ " if not self.ordered_letters:\n",
+ " super().set_ordered_letters()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 11
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptiveIncludedLettersNoRegex(PlayerAdaptiveNoRegex):\n",
+ " def filter_candidate_words(self, discovered, missed):\n",
+ " self.candidate_words = [w for w in self.candidate_words if self.match(discovered, w)]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 12
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptiveExcludedLettersNoRegex(PlayerAdaptiveNoRegex):\n",
+ " def filter_candidate_words(self, discovered, missed):\n",
+ " if missed:\n",
+ " empty_target = '_' * len(discovered)\n",
+ " self.candidate_words = [w for w in self.candidate_words if self.match(empty_target, w, missed)] "
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 13
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptivePatternNoRegex(PlayerAdaptiveNoRegex):\n",
+ " def filter_candidate_words(self, discovered, missed):\n",
+ " attempted_letters = [l for l in discovered if l != '_'] + missed\n",
+ " self.candidate_words = [w for w in self.candidate_words if self.match(discovered, w, attempted_letters)]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 14
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "%%timeit\n",
+ "\n",
+ "wins = 0\n",
+ "for _ in range(1000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerAdaptivePatternNoRegex(WORDS))\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "993\n",
+ "992"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "994"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "991"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "1 loops, best of 3: 48.2 s per loop\n"
+ ]
+ }
+ ],
+ "prompt_number": 15
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "len([w for w in WORDS if 'r' in w])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 21,
+ "text": [
+ "31398"
+ ]
+ }
+ ],
+ "prompt_number": 21
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "len([w for w in WORDS if 'r' not in w])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 22,
+ "text": [
+ "31458"
+ ]
+ }
+ ],
+ "prompt_number": 22
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "letter_diffs = []\n",
+ "for l in string.ascii_lowercase:\n",
+ " n = 0\n",
+ " for w in WORDS:\n",
+ " if l in w:\n",
+ " n += 1\n",
+ " else:\n",
+ " n -=1\n",
+ " letter_diffs += [(l, abs(n))]\n",
+ "sorted(letter_diffs, key=lambda p: p[1])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 19,
+ "text": [
+ "[('r', 60),\n",
+ " ('a', 98),\n",
+ " ('n', 3720),\n",
+ " ('t', 4728),\n",
+ " ('i', 6136),\n",
+ " ('s', 8662),\n",
+ " ('o', 12788),\n",
+ " ('l', 17878),\n",
+ " ('e', 22936),\n",
+ " ('c', 26102),\n",
+ " ('d', 26368),\n",
+ " ('u', 30282),\n",
+ " ('g', 33260),\n",
+ " ('p', 35960),\n",
+ " ('m', 37904),\n",
+ " ('h', 41134),\n",
+ " ('b', 44784),\n",
+ " ('y', 47462),\n",
+ " ('f', 49626),\n",
+ " ('v', 52502),\n",
+ " ('k', 53616),\n",
+ " ('w', 53688),\n",
+ " ('x', 60010),\n",
+ " ('q', 60816),\n",
+ " ('j', 60938),\n",
+ " ('z', 61244)]"
+ ]
+ }
+ ],
+ "prompt_number": 19
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def letter_diff(l):\n",
+ " return abs(sum(1 if l in w else -1 for w in WORDS))\n",
+ "\n",
+ "letter_diffs = [(l, letter_diff(l)) \n",
+ " for l in string.ascii_lowercase]\n",
+ "sorted(letter_diffs, key=lambda p: p[1])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 23,
+ "text": [
+ "[('r', 60),\n",
+ " ('a', 98),\n",
+ " ('n', 3720),\n",
+ " ('t', 4728),\n",
+ " ('i', 6136),\n",
+ " ('s', 8662),\n",
+ " ('o', 12788),\n",
+ " ('l', 17878),\n",
+ " ('e', 22936),\n",
+ " ('c', 26102),\n",
+ " ('d', 26368),\n",
+ " ('u', 30282),\n",
+ " ('g', 33260),\n",
+ " ('p', 35960),\n",
+ " ('m', 37904),\n",
+ " ('h', 41134),\n",
+ " ('b', 44784),\n",
+ " ('y', 47462),\n",
+ " ('f', 49626),\n",
+ " ('v', 52502),\n",
+ " ('k', 53616),\n",
+ " ('w', 53688),\n",
+ " ('x', 60010),\n",
+ " ('q', 60816),\n",
+ " ('j', 60938),\n",
+ " ('z', 61244)]"
+ ]
+ }
+ ],
+ "prompt_number": 23
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "class PlayerAdaptiveSplit(PlayerAdaptivePatternNoRegex):\n",
+ " def set_ordered_letters(self):\n",
+ " def letter_diff(l):\n",
+ " return abs(sum(1 if l in w else -1 for w in self.candidate_words))\n",
+ " possible_letters = set(''.join(self.candidate_words))\n",
+ " # if len(self.candidate_words) > 1:\n",
+ " letter_diffs = [(l, letter_diff(l)) for l in possible_letters]\n",
+ " self.ordered_letters = [p[0] for p in sorted(letter_diffs, key=lambda p: p[1])]\n",
+ " # else:\n",
+ " # self.ordered_letters = list(self.candidate_words[0])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 71
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS))\n",
+ "g.play_game()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 72,
+ "text": [
+ "True"
+ ]
+ }
+ ],
+ "prompt_number": 72
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.target"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 73,
+ "text": [
+ "'baste'"
+ ]
+ }
+ ],
+ "prompt_number": 73
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.discovered"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 74,
+ "text": [
+ "['b', 'a', 's', 't', 'e']"
+ ]
+ }
+ ],
+ "prompt_number": 74
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.wrong_letters"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 75,
+ "text": [
+ "['c', 'h']"
+ ]
+ }
+ ],
+ "prompt_number": 75
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "%%timeit\n",
+ "\n",
+ "wins = 0\n",
+ "for _ in range(1000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS))\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "983\n",
+ "982"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "981"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "987"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "1 loops, best of 3: 55.6 s per loop\n"
+ ]
+ }
+ ],
+ "prompt_number": 78
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p=PlayerAdaptiveSplit(WORDS)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 54
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "dsc = ['_'] * len('recognition')\n",
+ "dsc"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 55,
+ "text": [
+ "['_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_']"
+ ]
+ }
+ ],
+ "prompt_number": 55
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.guess(dsc, [], 10)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 56,
+ "text": [
+ "'o'"
+ ]
+ }
+ ],
+ "prompt_number": 56
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "len(p.candidate_words)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 57,
+ "text": [
+ "5027"
+ ]
+ }
+ ],
+ "prompt_number": 57
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.guess(['_', '_', '_', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 58,
+ "text": [
+ "'c'"
+ ]
+ }
+ ],
+ "prompt_number": 58
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.candidate_words"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 59,
+ "text": [
+ "['association',\n",
+ " 'defoliation',\n",
+ " 'deformation',\n",
+ " 'denominator',\n",
+ " 'deportation',\n",
+ " 'excoriation',\n",
+ " 'exhortation',\n",
+ " 'exportation',\n",
+ " 'importation',\n",
+ " 'information',\n",
+ " 'liposuction',\n",
+ " 'negotiation',\n",
+ " 'recognition',\n",
+ " 'recondition',\n",
+ " 'reformation',\n",
+ " 'subornation']"
+ ]
+ }
+ ],
+ "prompt_number": 59
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], [], 10)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 60,
+ "text": [
+ "'a'"
+ ]
+ }
+ ],
+ "prompt_number": 60
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.candidate_words"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 61,
+ "text": [
+ "['excoriation', 'recognition', 'recondition']"
+ ]
+ }
+ ],
+ "prompt_number": 61
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a'], 9)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 62,
+ "text": [
+ "'d'"
+ ]
+ }
+ ],
+ "prompt_number": 62
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.candidate_words"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 63,
+ "text": [
+ "['recognition', 'recondition']"
+ ]
+ }
+ ],
+ "prompt_number": 63
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.guess(['_', '_', 'c', 'o', '_', '_', '_', '_', '_', 'o', '_'], ['a', 'd'], 8)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 64,
+ "text": [
+ "'r'"
+ ]
+ }
+ ],
+ "prompt_number": 64
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "p.candidate_words"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 65,
+ "text": [
+ "['recognition']"
+ ]
+ }
+ ],
+ "prompt_number": 65
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g = Game('recognition', player=PlayerAdaptiveSplit(WORDS))\n",
+ "g.play_game()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 67,
+ "text": [
+ "True"
+ ]
+ }
+ ],
+ "prompt_number": 67
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.discovered"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 68,
+ "text": [
+ "['r', 'e', 'c', 'o', 'g', 'n', 'i', 't', 'i', 'o', 'n']"
+ ]
+ }
+ ],
+ "prompt_number": 68
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.lives"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 69,
+ "text": [
+ "8"
+ ]
+ }
+ ],
+ "prompt_number": 69
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "%%timeit\n",
+ "\n",
+ "wins = 0\n",
+ "for _ in range(10000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerAdaptiveSplit(WORDS))\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "9857\n",
+ "9862"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "9844"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "9860"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "1 loops, best of 3: 9min 15s per loop\n"
+ ]
+ }
+ ],
+ "prompt_number": 79
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "%%timeit\n",
+ "\n",
+ "wins = 0\n",
+ "for _ in range(10000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerAdaptivePatternNoRegex(WORDS))\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "9934\n",
+ "9916"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "9921"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "9932"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "\n",
+ "1 loops, best of 3: 8min 12s per loop\n"
+ ]
+ }
+ ],
+ "prompt_number": 81
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "for w in random.sample(WORDS, 5000):\n",
+ " gp = Game(w, player=PlayerAdaptivePatternNoRegex(WORDS))\n",
+ " gp.play_game()\n",
+ " gs = Game(w, player=PlayerAdaptiveSplit(WORDS))\n",
+ " gs.play_game()\n",
+ " if not gp.game_won and not gs.game_won:\n",
+ " print('Both:::::', gp.target, 'Pattern:', '[' + ' '.join(gp.discovered) + ']', ''.join(gp.wrong_letters), \n",
+ " ':: Split:', '[' + ' '.join(gs.discovered) + ']', ''.join(gs.wrong_letters))\n",
+ " if not gp.game_won and gs.game_won:\n",
+ " print('Pattern::', gp.target, '[' + ' '.join(gp.discovered) + ']', ''.join(gp.wrong_letters))\n",
+ " if gp.game_won and not gs.game_won:\n",
+ " print('Split::::', gs.target, '[' + ' '.join(gs.discovered) + ']', ''.join(gs.wrong_letters))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "Split:::: cut [_ _ t] aoeiybgnpj\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " reviewers [_ _ _ _ _ _ _ _ _] taoldgnupc\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " piped [_ i _ e d] saolrnkvbm\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " joying Pattern: [_ o _ i n g] esapwdtrkm :: Split: [_ o _ _ n _] srdatpwhvk\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " duck Pattern: [_ u _ _] esoailfrnm :: Split: [_ u _ _] esaorlnfmt\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " bum [b _ _] aoeiyrtgns\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " jibing [_ i _ i n g] esrldmpkvt\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " begged [_ _ _ _ _ d] srlnoauipt\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " bucked [b u _ _ e d] aoilstfgpr\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " bunk [_ u n k] esoailfrgp\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " dumping [_ u _ p _ _ g] srlaoecjhb\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " meekest [_ _ _ _ _ s _] iaournlpdw\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " wove [_ o v e] arnldptkmc\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " finking [_ _ _ _ _ _ g] srlaoeutpd\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fan Pattern: [_ a _] tpgwdmrbys :: Split: [_ a n] tpgwmbyrdv\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " hug [_ u g] aoeibpdmtj\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " feminism [_ _ _ _ _ _ _ _] ratlogdcuh\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " effect [_ _ _ _ c t] srdnaioulp\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " puff [_ u f f] esaorlnmgc\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " skivvies [_ _ _ _ _ _ _ _] ratlogdcuh\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " miffing [_ _ _ _ _ _ g] srlaoeutpd\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " dung Pattern: [_ u n _] esoailfrkt :: Split: [_ u n g] esaorlkthb\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " gibed [_ i _ e d] saomlprkvn\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " rubs [_ u b s] eaoicpdtnh\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " bat [_ a t] ecpsofmvhr\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " boobs [_ o o _ s] eatdklmpfn\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " yon Pattern: [_ o n] atbdwpiecs :: Split: [_ o n] atbdwpiesc\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " firs Pattern: [f i _ s] eaoptgbdmn :: Split: [_ i _ s] eaotpgbdmn\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " quipping [_ _ _ _ _ _ _ g] ratloscedh\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " ragging [r a _ _ _ n _] seotzclpdm\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fuddled [_ u _ _ l _ _] sraoibzmgc\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " yack Pattern: [_ a c k] esolrntmpj :: Split: [_ a c k] esrlntmjhb\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " vanning [_ a _ _ _ _ g] srltpbwmck\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fizziest [_ _ _ _ _ _ _ t] rauonlphdk\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " rug [_ u g] aoeibpdmtj\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fixed Pattern: [_ i _ e d] saomlprkvn :: Split: [_ i _ e d] saolrnkvbm\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " mop [_ o p] atbdwchlsf\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " separatists [_ _ p _ _ _ _ _ _ _ _] oldcgnymbx\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " miff [_ _ _ _] esaoutnlrc\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " putty [p u _ _ y] seaoimlnrf\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " mice [_ i _ e] aorlnvtdkw\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fixing Pattern: [_ i _ i n g] esrldmpkvt :: Split: [_ _ _ _ n _] srdaoeulbp\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " gaged [_ a _ e d] srwctpmzbh\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fag [_ a g] tpjnhrlbsw\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " woeful [_ o _ _ _ _] srdnaictyb\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " pauper [_ a _ _ _ r] sntlmidkvj\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " faxing Pattern: [f a _ i n g] esrwtlcdkz :: Split: [_ a _ _ n _] srdtwmpczh\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " yoking Pattern: [_ o k i n g] esapwdtrcj :: Split: [_ o k _ n _] srdatpwhvj\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " cox Pattern: [_ o _] atbdwpnsge :: Split: [_ o _] atbdwpngse\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " doff [_ o _ _] esalrnctyb\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " puck Pattern: [_ u _ _] esoailfrnm :: Split: [_ u _ _] esaorlnfmt\n",
+ "Pattern::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " tuck [_ u _ _] esoailfrnm\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " kerchiefs [_ _ _ c _ _ _ _ _] taoldgnupv\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " members [_ _ _ _ _ r s] aoiutdpcgv\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " foxing Pattern: [_ o _ i n g] esapwdtrkm :: Split: [_ o _ _ n _] srdatpwhvk\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " anaesthetises [_ _ _ _ _ _ _ _ _ _ _ _ _] clgmpdvuro\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " versifies [_ _ _ _ _ _ _ _ _] taoldgnupc\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " babes Pattern: [_ a _ e s] rltngcdkzv :: Split: [_ a _ e s] rltngcdkzv\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " huffing [_ u f f _ _ g] srlaoecpbm\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " weeper [_ _ _ p _ r] saioutdhbk\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " buffering [_ u _ _ _ _ _ _ g] taoldsphmv\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " dills [_ _ l l s] eaountghrb\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " wigging [_ _ g g _ _ g] srlaouejpd\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " indenting [_ _ d _ _ t _ _ _] aoscrlbvhf\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " morn [_ o r n] esaltchbpw\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " buff Pattern: [_ u f f] esoailgcpd :: Split: [_ u f f] esaorlnmgc\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " zero [_ e r _] satlbnhpyg\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " jazz Pattern: [_ a _ _] esolrntmky :: Split: [_ a _ _] esrlntmkdw\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " k [_] geopdtuyiz\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " find [_ _ n d] esaoutkhrb\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " happy [_ a _ _ y] sentdrglcz\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fibbing [_ _ _ _ _ _ g] srlaoeutpd\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " wifeliest [_ _ _ _ _ _ _ _ t] nroacmhpgu\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " r Pattern: [_] giecposdwk :: Split: [_] geopdtuyiz\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " businesses [_ _ _ _ n _ _ _ _ _] olatdgcphr\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fife Pattern: [_ i _ e] aorlndvtpm :: Split: [_ i _ e] aorlnvtdkw\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " fix Pattern: [_ i _] aoeptdngsb :: Split: [_ i _] aoetndpgbs\n",
+ "Both:::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " mil Pattern: [_ i _] aoeptdngsb :: Split: [_ i _] aoetndpgbs\n",
+ "Split::::"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " wetted [_ _ t t _ d] srlnoauipj\n"
+ ]
+ }
+ ],
+ "prompt_number": 90
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "gs = Game('businesses', player=PlayerAdaptiveSplit(WORDS))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 91
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g = Game('feminism', player=PlayerAdaptiveSplit(WORDS))\n",
+ "while not g.game_finished:\n",
+ " guess = g.player.guess(g.discovered, g.wrong_letters, g.lives)\n",
+ " print(g.target, '(' + str(g.lives) + ')', \n",
+ " '[' + ' '.join(g.discovered) + ']', ''.join(g.wrong_letters), \n",
+ " ';', len(g.player.candidate_words), 'candidate words')\n",
+ " print('Guess = ', guess)\n",
+ " g.do_turn()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "feminism (10) [_ _ _ _ _ _ _ _] ; 10328 candidate words\n",
+ "Guess = r\n",
+ "feminism"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " (9) [_ _ _ _ _ _ _ _] r ; 5102 candidate words\n",
+ "Guess = a\n",
+ "feminism (8) [_ _ _ _ _ _ _ _] ra ; 2673 candidate words\n",
+ "Guess = t\n",
+ "feminism"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " (7) [_ _ _ _ _ _ _ _] rat ; 1466 candidate words\n",
+ "Guess = l\n",
+ "feminism (6) [_ _ _ _ _ _ _ _] ratl ; 704 candidate words\n",
+ "Guess = o\n",
+ "feminism (5) [_ _ _ _ _ _ _ _] ratlo ; 359 candidate words\n",
+ "Guess = g\n",
+ "feminism (4) [_ _ _ _ _ _ _ _] ratlog ; 189 candidate words\n",
+ "Guess = d\n",
+ "feminism (3) [_ _ _ _ _ _ _ _] ratlogd ; 94 candidate words\n",
+ "Guess = c\n",
+ "feminism (2) [_ _ _ _ _ _ _ _] ratlogdc ; 50 candidate words\n",
+ "Guess = u\n",
+ "feminism (1) [_ _ _ _ _ _ _ _] ratlogdcu ; 31 candidate words\n",
+ "Guess = h\n"
+ ]
+ }
+ ],
+ "prompt_number": 170
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g = Game('feminism', player=PlayerAdaptivePatternNoRegex(WORDS))\n",
+ "while not g.game_finished:\n",
+ " guess = g.player.guess(g.discovered, g.wrong_letters, g.lives)\n",
+ " print(g.target, '(' + str(g.lives) + ')', \n",
+ " '[' + ' '.join(g.discovered) + ']', ''.join(g.wrong_letters), \n",
+ " ';', len(g.player.candidate_words), 'candidate words')\n",
+ " print('Guess = ', guess)\n",
+ " g.do_turn()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "feminism (10) [_ _ _ _ _ _ _ _] ; 10328 candidate words\n",
+ "Guess = e\n",
+ "feminism"
+ ]
+ },
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ " (10) [_ e _ _ _ _ _ _] ; 540 candidate words\n",
+ "Guess = i\n",
+ "feminism (10) [_ e _ i _ i _ _] ; 42 candidate words\n",
+ "Guess = n\n",
+ "feminism (10) [_ e _ i n i _ _] ; 3 candidate words\n",
+ "Guess = s\n",
+ "feminism (10) [_ e _ i n i s _] ; 3 candidate words\n",
+ "Guess = f\n",
+ "feminism (10) [f e _ i n i s _] ; 2 candidate words\n",
+ "Guess = m\n"
+ ]
+ }
+ ],
+ "prompt_number": 172
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "g.player.candidate_words"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 171,
+ "text": [
+ "['beehives',\n",
+ " 'enmeshes',\n",
+ " 'evenness',\n",
+ " 'expenses',\n",
+ " 'feminine',\n",
+ " 'feminism',\n",
+ " 'fineness',\n",
+ " 'finesses',\n",
+ " 'finishes',\n",
+ " 'fishwife',\n",
+ " 'inkiness',\n",
+ " 'keenness',\n",
+ " 'meekness',\n",
+ " 'minibike',\n",
+ " 'minimise',\n",
+ " 'missives',\n",
+ " 'ninepins',\n",
+ " 'penknife',\n",
+ " 'sexiness',\n",
+ " 'sheepish',\n",
+ " 'shimmies',\n",
+ " 'shinnies',\n",
+ " 'skivvies',\n",
+ " 'sphinxes',\n",
+ " 'vivifies',\n",
+ " 'vixenish',\n",
+ " 'whimseys',\n",
+ " 'whimsies',\n",
+ " 'whinnies',\n",
+ " 'whiskeys',\n",
+ " 'whiskies']"
+ ]
+ }
+ ],
+ "prompt_number": 171
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": []
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+
+# 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]:
+
+STARTING_LIVES = 10
+
+
+# In[8]:
+
+class Game:
+ def __init__(self, target, player=None, lives=STARTING_LIVES):
+ self.lives = lives
+ self.player = player
+ self.target = target
+ self.discovered = list('_' * len(target))
+ self.wrong_letters = []
+ self.game_finished = False
+ self.game_won = False
+ self.game_lost = False
+
+ def find_all(self, letter):
+ return [p for p, l in enumerate(self.target) if l == letter]
+
+ def update_discovered_word(self, guessed_letter):
+ locations = self.find_all(guessed_letter)
+ for location in locations:
+ self.discovered[location] = guessed_letter
+ return self.discovered
+
+ def do_turn(self):
+ if self.player:
+ guess = self.player.guess(self.discovered, self.wrong_letters, self.lives)
+ else:
+ guess = self.ask_for_guess()
+ if guess in self.target:
+ self.update_discovered_word(guess)
+ else:
+ self.lives -= 1
+ if guess not in self.wrong_letters:
+ self.wrong_letters += [guess]
+ if self.lives == 0:
+ self.game_finished = True
+ self.game_lost = True
+ if '_' not in self.discovered:
+ self.game_finished = True
+ self.game_won = True
+
+ def ask_for_guess(self):
+ print('Word:', ' '.join(self.discovered),
+ ' : Lives =', self.lives,
+ ', wrong guesses:', ' '.join(sorted(self.wrong_letters)))
+ guess = input('Enter letter: ').strip().lower()[0]
+ return guess
+
+ def play_game(self):
+ while not self.game_finished:
+ self.do_turn()
+ if not self.player:
+ self.report_on_game()
+ return self.game_won
+
+ def report_on_game(self):
+ if self.game_won:
+ print('You won! The word was', self.target)
+ else:
+ print('You lost. The word was', self.target)
+ return self.game_won
+
+
+# In[9]:
+
+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()]
+
+
+# In[10]:
+
+class PlayerAdaptiveNoRegex:
+ 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]
+
+ def filter_candidate_words(self, discovered, missed):
+ pass
+
+ def set_ordered_letters(self):
+ counts = collections.Counter(l.lower()
+ for l in ''.join(self.candidate_words) + string.ascii_lowercase
+ if l in string.ascii_letters)
+ self.ordered_letters = [p[0] for p in counts.most_common()]
+
+ def match(self, pattern, target, excluded=None):
+ if not excluded:
+ excluded = ''
+ if len(pattern) != len(target):
+ return False
+ for m, c in zip(pattern, target):
+ if m == '_' and c not in excluded:
+ # true
+ pass
+ elif m != '_' and m == c:
+ # true
+ pass
+ else:
+ return False
+ return True
+
+
+# In[11]:
+
+class PlayerAdaptiveLengthNoRegex(PlayerAdaptiveNoRegex):
+ def __init__(self, words):
+ super().__init__(words)
+ self.word_len = None
+ self.ordered_letters = None
+
+ def filter_candidate_words(self, discovered, missed):
+ if not self.word_len:
+ self.word_len = len(discovered)
+ self.candidate_words = [w for w in self.candidate_words if len(w) == self.word_len]
+
+ def set_ordered_letters(self):
+ if not self.ordered_letters:
+ super().set_ordered_letters()
+
+
+# In[12]:
+
+class PlayerAdaptiveIncludedLettersNoRegex(PlayerAdaptiveNoRegex):
+ 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):
+ 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):
+ 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):
+ 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[ ]:
+
+
+