96c61fe786d71be1d42661beb4e49de12ccf2f16
[cas-master-teacher-training.git] / hangman-better.ipynb
1 {
2 "metadata": {
3 "name": "",
4 "signature": "sha256:b93ed7f85302bd806b23e539f31a6d8afd7554cafe052439a06de6aa5a19b08d"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
10 "cells": [
11 {
12 "cell_type": "code",
13 "collapsed": false,
14 "input": [
15 "import re\n",
16 "import random\n",
17 "import string\n",
18 "import collections"
19 ],
20 "language": "python",
21 "metadata": {},
22 "outputs": [],
23 "prompt_number": 1
24 },
25 {
26 "cell_type": "code",
27 "collapsed": false,
28 "input": [
29 "WORDS = [w.strip() for w in open('/usr/share/dict/british-english').readlines() \n",
30 " if re.match(r'^[a-z]*$', w.strip())]"
31 ],
32 "language": "python",
33 "metadata": {},
34 "outputs": [],
35 "prompt_number": 2
36 },
37 {
38 "cell_type": "code",
39 "collapsed": false,
40 "input": [
41 "LETTER_COUNTS = collections.Counter(l.lower() for l in open('sherlock-holmes.txt').read() if l in string.ascii_letters)\n",
42 "LETTERS_IN_ORDER = [p[0] for p in LETTER_COUNTS.most_common()]"
43 ],
44 "language": "python",
45 "metadata": {},
46 "outputs": [],
47 "prompt_number": 12
48 },
49 {
50 "cell_type": "code",
51 "collapsed": false,
52 "input": [
53 "STARTING_LIVES = 10"
54 ],
55 "language": "python",
56 "metadata": {},
57 "outputs": [],
58 "prompt_number": 4
59 },
60 {
61 "cell_type": "code",
62 "collapsed": false,
63 "input": [
64 "class Game:\n",
65 " def __init__(self, target, player=None, lives=STARTING_LIVES):\n",
66 " self.lives = lives\n",
67 " self.player = player\n",
68 " self.target = target\n",
69 " self.discovered = list('_' * len(target))\n",
70 " self.wrong_letters = []\n",
71 " self.game_finished = False\n",
72 " self.game_won = False\n",
73 " self.game_lost = False\n",
74 " \n",
75 " def find_all(self, letter):\n",
76 " locations = []\n",
77 " starting=0\n",
78 " location = self.target.find(letter)\n",
79 " while location > -1:\n",
80 " locations += [location]\n",
81 " starting = location + 1\n",
82 " location = self.target.find(letter, starting)\n",
83 " return locations\n",
84 " \n",
85 " def update_discovered_word(self, guessed_letter):\n",
86 " locations = self.find_all(guessed_letter)\n",
87 " for location in locations:\n",
88 " self.discovered[location] = guessed_letter\n",
89 " return self.discovered\n",
90 " \n",
91 " def do_turn(self):\n",
92 " if self.player:\n",
93 " guess = self.player.guess(self.discovered, self.wrong_letters, self.lives)\n",
94 " else:\n",
95 " guess = self.ask_for_guess()\n",
96 " if guess in self.target:\n",
97 " self.update_discovered_word(guess)\n",
98 " else:\n",
99 " self.lives -= 1\n",
100 " if guess not in self.wrong_letters:\n",
101 " self.wrong_letters += [guess]\n",
102 " if self.lives == 0:\n",
103 " self.game_finished = True\n",
104 " self.game_lost = True\n",
105 " if '_' not in self.discovered:\n",
106 " self.game_finished = True\n",
107 " self.game_won = True\n",
108 " \n",
109 " def ask_for_guess(self):\n",
110 " print('Word:', ' '.join(self.discovered), \n",
111 " ' : Lives =', self.lives, \n",
112 " ', wrong guesses:', ' '.join(sorted(self.wrong_letters)))\n",
113 " guess = input('Enter letter: ').strip().lower()[0]\n",
114 " return guess\n",
115 " \n",
116 " def play_game(self):\n",
117 " self.do_turn()\n",
118 " while not self.game_finished:\n",
119 " self.do_turn()\n",
120 " if not self.player:\n",
121 " self.report_on_game()\n",
122 " return self.game_won\n",
123 " \n",
124 " def report_on_game(self):\n",
125 " if self.game_won:\n",
126 " print('You won! The word was', self.target)\n",
127 " else:\n",
128 " print('You lost. The word was', self.target)\n",
129 " return self.game_won"
130 ],
131 "language": "python",
132 "metadata": {},
133 "outputs": [],
134 "prompt_number": 5
135 },
136 {
137 "cell_type": "code",
138 "collapsed": false,
139 "input": [
140 "class PlayerFixedOrder:\n",
141 " def __init__(self, ordered_letters):\n",
142 " self.ordered_letters = ordered_letters\n",
143 " \n",
144 " def guess(self, discovered, missed, lives):\n",
145 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
146 " self.ordered_subtract(guessed_letters)\n",
147 " return self.ordered_letters[0]\n",
148 "\n",
149 " def ordered_subtract(self, to_remove):\n",
150 " for r in to_remove:\n",
151 " if r in self.ordered_letters:\n",
152 " ri = self.ordered_letters.index(r)\n",
153 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]"
154 ],
155 "language": "python",
156 "metadata": {},
157 "outputs": [],
158 "prompt_number": 6
159 },
160 {
161 "cell_type": "code",
162 "collapsed": false,
163 "input": [
164 "class PlayerAlphabetical(PlayerFixedOrder):\n",
165 " def __init__(self):\n",
166 " super().__init__(string.ascii_lowercase)\n",
167 "\n",
168 "class PlayerFreqOrdered(PlayerFixedOrder):\n",
169 " def __init__(self):\n",
170 " super().__init__(LETTERS_IN_ORDER)\n"
171 ],
172 "language": "python",
173 "metadata": {},
174 "outputs": [],
175 "prompt_number": 7
176 },
177 {
178 "cell_type": "code",
179 "collapsed": false,
180 "input": [
181 "wins = 0\n",
182 "for _ in range(1000):\n",
183 " g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
184 " g.play_game()\n",
185 " if g.game_won:\n",
186 " wins += 1\n",
187 "print(wins)"
188 ],
189 "language": "python",
190 "metadata": {},
191 "outputs": [
192 {
193 "output_type": "stream",
194 "stream": "stdout",
195 "text": [
196 "55\n"
197 ]
198 }
199 ],
200 "prompt_number": 8
201 },
202 {
203 "cell_type": "code",
204 "collapsed": false,
205 "input": [
206 "wins = 0\n",
207 "for _ in range(1000):\n",
208 " g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
209 " g.play_game()\n",
210 " if g.game_won:\n",
211 " wins += 1\n",
212 "print(wins)"
213 ],
214 "language": "python",
215 "metadata": {},
216 "outputs": [
217 {
218 "output_type": "stream",
219 "stream": "stdout",
220 "text": [
221 "336\n"
222 ]
223 }
224 ],
225 "prompt_number": 9
226 },
227 {
228 "cell_type": "code",
229 "collapsed": false,
230 "input": [
231 "wins = 0\n",
232 "for _ in range(1000):\n",
233 " g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
234 " g.play_game()\n",
235 " if g.game_won:\n",
236 " wins += 1\n",
237 "print(wins)"
238 ],
239 "language": "python",
240 "metadata": {},
241 "outputs": [
242 {
243 "output_type": "stream",
244 "stream": "stdout",
245 "text": [
246 "4\n"
247 ]
248 }
249 ],
250 "prompt_number": 10
251 },
252 {
253 "cell_type": "code",
254 "collapsed": false,
255 "input": [
256 "DICT_COUNTS = collections.Counter(l.lower() for l in open('/usr/share/dict/british-english').read() if l in string.ascii_letters)\n",
257 "DICT_LETTERS_IN_ORDER = [p[0] for p in DICT_COUNTS.most_common()]"
258 ],
259 "language": "python",
260 "metadata": {},
261 "outputs": [],
262 "prompt_number": 17
263 },
264 {
265 "cell_type": "code",
266 "collapsed": false,
267 "input": [
268 "DICT_COUNTS"
269 ],
270 "language": "python",
271 "metadata": {},
272 "outputs": [
273 {
274 "metadata": {},
275 "output_type": "pyout",
276 "prompt_number": 18,
277 "text": [
278 "Counter({'s': 91332, 'e': 88692, 'i': 66900, 'a': 64468, 'r': 57460, 'n': 57128, 't': 52949, 'o': 49121, 'l': 40995, 'c': 31854, 'd': 28505, 'u': 26372, 'g': 22693, 'm': 22549, 'p': 22249, 'h': 19337, 'b': 15540, 'y': 12652, 'f': 10679, 'k': 8386, 'v': 8000, 'w': 7505, 'x': 2125, 'z': 2058, 'j': 1950, 'q': 1536})"
279 ]
280 }
281 ],
282 "prompt_number": 18
283 },
284 {
285 "cell_type": "code",
286 "collapsed": false,
287 "input": [
288 "print(DICT_LETTERS_IN_ORDER)\n",
289 "print(LETTERS_IN_ORDER)"
290 ],
291 "language": "python",
292 "metadata": {},
293 "outputs": [
294 {
295 "output_type": "stream",
296 "stream": "stdout",
297 "text": [
298 "['s', 'e', 'i', 'a', 'r', 'n', 't', 'o', 'l', 'c', 'd', 'u', 'g', 'm', 'p', 'h', 'b', 'y', 'f', 'k', 'v', 'w', 'x', 'z', 'j', 'q']\n",
299 "['e', 't', 'a', 'o', 'i', 'h', 'n', 's', 'r', 'd', 'l', 'u', 'm', 'w', 'c', 'y', 'f', 'g', 'p', 'b', 'v', 'k', 'x', 'j', 'q', 'z']\n"
300 ]
301 }
302 ],
303 "prompt_number": 19
304 },
305 {
306 "cell_type": "code",
307 "collapsed": false,
308 "input": [
309 "wins = 0\n",
310 "for _ in range(1000):\n",
311 " g = Game(random.choice(WORDS), player=PlayerFixedOrder(DICT_LETTERS_IN_ORDER))\n",
312 " g.play_game()\n",
313 " if g.game_won:\n",
314 " wins += 1\n",
315 "print(wins)"
316 ],
317 "language": "python",
318 "metadata": {},
319 "outputs": [
320 {
321 "output_type": "stream",
322 "stream": "stdout",
323 "text": [
324 "451\n"
325 ]
326 }
327 ],
328 "prompt_number": 20
329 },
330 {
331 "cell_type": "code",
332 "collapsed": false,
333 "input": [
334 "class PlayerAdaptiveLength:\n",
335 " def __init__(self, words):\n",
336 " self.all_words = words\n",
337 " self.candidate_words = None\n",
338 " \n",
339 " def guess(self, discovered, missed, lives):\n",
340 " if not self.candidate_words:\n",
341 " self.set_ordered_letters(len(discovered))\n",
342 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
343 " self.ordered_subtract(guessed_letters)\n",
344 " return self.ordered_letters[0]\n",
345 "\n",
346 " def ordered_subtract(self, to_remove):\n",
347 " for r in to_remove:\n",
348 " if r in self.ordered_letters:\n",
349 " ri = self.ordered_letters.index(r)\n",
350 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]\n",
351 " \n",
352 " def set_ordered_letters(self, word_len):\n",
353 " self.candidate_words = [w for w in self.all_words if len(w) == word_len]\n",
354 " counts = collections.Counter(l.lower() for l in ''.join(self.candidate_words) if l in string.ascii_letters)\n",
355 " self.ordered_letters = [p[0] for p in counts.most_common()]"
356 ],
357 "language": "python",
358 "metadata": {},
359 "outputs": [],
360 "prompt_number": 33
361 },
362 {
363 "cell_type": "code",
364 "collapsed": false,
365 "input": [
366 "wins = 0\n",
367 "for _ in range(1000):\n",
368 " g = Game(random.choice(WORDS), player=PlayerAdaptiveLength(WORDS))\n",
369 " g.play_game()\n",
370 " if g.game_won:\n",
371 " wins += 1\n",
372 "print(wins)"
373 ],
374 "language": "python",
375 "metadata": {},
376 "outputs": [
377 {
378 "output_type": "stream",
379 "stream": "stdout",
380 "text": [
381 "485\n"
382 ]
383 }
384 ],
385 "prompt_number": 34
386 },
387 {
388 "cell_type": "code",
389 "collapsed": false,
390 "input": [
391 "class PlayerAdaptiveIncludedLetters:\n",
392 " def __init__(self, words):\n",
393 " self.candidate_words = words\n",
394 " \n",
395 " def guess(self, discovered, missed, lives):\n",
396 " self.filter_candidate_words(discovered)\n",
397 " self.set_ordered_letters()\n",
398 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
399 " self.ordered_subtract(guessed_letters)\n",
400 " return self.ordered_letters[0]\n",
401 "\n",
402 " def ordered_subtract(self, to_remove):\n",
403 " for r in to_remove:\n",
404 " if r in self.ordered_letters:\n",
405 " ri = self.ordered_letters.index(r)\n",
406 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]\n",
407 " \n",
408 " def filter_candidate_words(self, discovered):\n",
409 " exp = re.compile('^' + ''.join(discovered).replace('_', '.') + '$')\n",
410 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]\n",
411 " \n",
412 " def set_ordered_letters(self):\n",
413 " counts = collections.Counter(l.lower() for l in ''.join(self.candidate_words) if l in string.ascii_letters)\n",
414 " self.ordered_letters = [p[0] for p in counts.most_common()]"
415 ],
416 "language": "python",
417 "metadata": {},
418 "outputs": [],
419 "prompt_number": 51
420 },
421 {
422 "cell_type": "code",
423 "collapsed": false,
424 "input": [
425 "wins = 0\n",
426 "for _ in range(1000):\n",
427 " g = Game(random.choice(WORDS), player=PlayerAdaptiveIncludedLetters(WORDS))\n",
428 " g.play_game()\n",
429 " if g.game_won:\n",
430 " wins += 1\n",
431 "print(wins)"
432 ],
433 "language": "python",
434 "metadata": {},
435 "outputs": [
436 {
437 "output_type": "stream",
438 "stream": "stdout",
439 "text": [
440 "985\n"
441 ]
442 }
443 ],
444 "prompt_number": 52
445 },
446 {
447 "cell_type": "code",
448 "collapsed": false,
449 "input": [
450 "re.match('^[^xaz]*$', 'happy')"
451 ],
452 "language": "python",
453 "metadata": {},
454 "outputs": [],
455 "prompt_number": 50
456 },
457 {
458 "cell_type": "code",
459 "collapsed": false,
460 "input": [
461 "class PlayerAdaptiveExcludedLetters:\n",
462 " def __init__(self, words):\n",
463 " self.candidate_words = words\n",
464 " \n",
465 " def guess(self, discovered, missed, lives):\n",
466 " self.filter_candidate_words(missed)\n",
467 " self.set_ordered_letters()\n",
468 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
469 " self.ordered_subtract(guessed_letters)\n",
470 " return self.ordered_letters[0]\n",
471 "\n",
472 " def ordered_subtract(self, to_remove):\n",
473 " for r in to_remove:\n",
474 " if r in self.ordered_letters:\n",
475 " ri = self.ordered_letters.index(r)\n",
476 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]\n",
477 " \n",
478 " def filter_candidate_words(self, missed):\n",
479 " if missed:\n",
480 " exp = re.compile('^[^' + ''.join(missed) + ']*$')\n",
481 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]\n",
482 " \n",
483 " def set_ordered_letters(self):\n",
484 " counts = collections.Counter(l.lower() for l in ''.join(self.candidate_words) if l in string.ascii_letters)\n",
485 " self.ordered_letters = [p[0] for p in counts.most_common()]"
486 ],
487 "language": "python",
488 "metadata": {},
489 "outputs": [],
490 "prompt_number": 62
491 },
492 {
493 "cell_type": "code",
494 "collapsed": false,
495 "input": [
496 "wins = 0\n",
497 "for _ in range(1000):\n",
498 " g = Game(random.choice(WORDS), player=PlayerAdaptiveExcludedLetters(WORDS))\n",
499 " g.play_game()\n",
500 " if g.game_won:\n",
501 " wins += 1\n",
502 "print(wins)"
503 ],
504 "language": "python",
505 "metadata": {},
506 "outputs": [
507 {
508 "output_type": "stream",
509 "stream": "stdout",
510 "text": [
511 "491\n"
512 ]
513 }
514 ],
515 "prompt_number": 63
516 },
517 {
518 "cell_type": "code",
519 "collapsed": false,
520 "input": [
521 "g.player.candidate_words"
522 ],
523 "language": "python",
524 "metadata": {},
525 "outputs": [
526 {
527 "metadata": {},
528 "output_type": "pyout",
529 "prompt_number": 59,
530 "text": [
531 "['a']"
532 ]
533 }
534 ],
535 "prompt_number": 59
536 },
537 {
538 "cell_type": "code",
539 "collapsed": false,
540 "input": [
541 "g.wrong_letters"
542 ],
543 "language": "python",
544 "metadata": {},
545 "outputs": [
546 {
547 "metadata": {},
548 "output_type": "pyout",
549 "prompt_number": 61,
550 "text": [
551 "['a']"
552 ]
553 }
554 ],
555 "prompt_number": 61
556 },
557 {
558 "cell_type": "code",
559 "collapsed": false,
560 "input": [
561 "class PlayerAdaptivePattern:\n",
562 " def __init__(self, words):\n",
563 " self.candidate_words = words\n",
564 " \n",
565 " def guess(self, discovered, missed, lives):\n",
566 " self.filter_candidate_words(discovered, missed)\n",
567 " self.set_ordered_letters()\n",
568 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
569 " self.ordered_subtract(guessed_letters)\n",
570 " return self.ordered_letters[0]\n",
571 "\n",
572 " def ordered_subtract(self, to_remove):\n",
573 " for r in to_remove:\n",
574 " if r in self.ordered_letters:\n",
575 " ri = self.ordered_letters.index(r)\n",
576 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]\n",
577 " \n",
578 " def filter_candidate_words(self, discovered, missed):\n",
579 " if missed:\n",
580 " exclusion_pattern = '(?!.*[' + ''.join(missed) + '])'\n",
581 " else:\n",
582 " exclusion_pattern = ''\n",
583 " exp = re.compile('^' + exclusion_pattern + ''.join(discovered).replace('_', '.') + '$')\n",
584 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]\n",
585 " \n",
586 " def set_ordered_letters(self):\n",
587 " counts = collections.Counter(l.lower() for l in ''.join(self.candidate_words) if l in string.ascii_letters)\n",
588 " self.ordered_letters = [p[0] for p in counts.most_common()]"
589 ],
590 "language": "python",
591 "metadata": {},
592 "outputs": [],
593 "prompt_number": 109
594 },
595 {
596 "cell_type": "code",
597 "collapsed": false,
598 "input": [
599 "def fcw(words, discovered, missed):\n",
600 " if missed:\n",
601 " exclusion_pattern = '(?!.*[' + ''.join(missed) + '])'\n",
602 " else:\n",
603 " exclusion_pattern = ''\n",
604 " exp = re.compile('^' + exclusion_pattern + ''.join(discovered).replace('_', '.') + '$')\n",
605 " return [w for w in words if exp.match(w)]"
606 ],
607 "language": "python",
608 "metadata": {},
609 "outputs": [],
610 "prompt_number": 97
611 },
612 {
613 "cell_type": "code",
614 "collapsed": false,
615 "input": [
616 "def fcwp(discovered, missed):\n",
617 " if missed:\n",
618 " exclusion_pattern = '(?!.*[' + ''.join(missed) + '])'\n",
619 " else:\n",
620 " exclusion_pattern = ''\n",
621 " return '^' + exclusion_pattern + ''.join(discovered).replace('_', '.') + '$'"
622 ],
623 "language": "python",
624 "metadata": {},
625 "outputs": [],
626 "prompt_number": 102
627 },
628 {
629 "cell_type": "code",
630 "collapsed": false,
631 "input": [
632 "fcwp(['h', '_', 'p', '_'], ['x', 'w'])"
633 ],
634 "language": "python",
635 "metadata": {},
636 "outputs": [
637 {
638 "metadata": {},
639 "output_type": "pyout",
640 "prompt_number": 103,
641 "text": [
642 "'^(?!.*[xw])h.p.$'"
643 ]
644 }
645 ],
646 "prompt_number": 103
647 },
648 {
649 "cell_type": "code",
650 "collapsed": false,
651 "input": [
652 "re.match('^(?!.*[xw])h.p.$', 'hwpe')"
653 ],
654 "language": "python",
655 "metadata": {},
656 "outputs": [],
657 "prompt_number": 101
658 },
659 {
660 "cell_type": "code",
661 "collapsed": false,
662 "input": [
663 "re.match('^(?!.*[xw])h.p.$', 'hape')"
664 ],
665 "language": "python",
666 "metadata": {},
667 "outputs": [
668 {
669 "metadata": {},
670 "output_type": "pyout",
671 "prompt_number": 104,
672 "text": [
673 "<_sre.SRE_Match object; span=(0, 4), match='hape'>"
674 ]
675 }
676 ],
677 "prompt_number": 104
678 },
679 {
680 "cell_type": "code",
681 "collapsed": false,
682 "input": [
683 "fcw(WORDS, ['h', '_', 'p', '_'], ['x', 'w', 's'])"
684 ],
685 "language": "python",
686 "metadata": {},
687 "outputs": [
688 {
689 "metadata": {},
690 "output_type": "pyout",
691 "prompt_number": 108,
692 "text": [
693 "['hope', 'hype', 'hypo']"
694 ]
695 }
696 ],
697 "prompt_number": 108
698 },
699 {
700 "cell_type": "code",
701 "collapsed": false,
702 "input": [
703 "wins = 0\n",
704 "for _ in range(1000):\n",
705 " g = Game(random.choice(WORDS), player=PlayerAdaptivePattern(WORDS))\n",
706 " g.play_game()\n",
707 " if g.game_won:\n",
708 " wins += 1\n",
709 "print(wins)"
710 ],
711 "language": "python",
712 "metadata": {},
713 "outputs": [
714 {
715 "output_type": "stream",
716 "stream": "stdout",
717 "text": [
718 "992\n"
719 ]
720 }
721 ],
722 "prompt_number": 110
723 },
724 {
725 "cell_type": "code",
726 "collapsed": false,
727 "input": [
728 "%%timeit\n",
729 "\n",
730 "wins = 0\n",
731 "for _ in range(1000):\n",
732 " g = Game(random.choice(WORDS), player=PlayerAdaptiveIncludedLetters(WORDS))\n",
733 " g.play_game()\n",
734 " if g.game_won:\n",
735 " wins += 1\n",
736 "print(wins)"
737 ],
738 "language": "python",
739 "metadata": {},
740 "outputs": [
741 {
742 "output_type": "stream",
743 "stream": "stdout",
744 "text": [
745 "984\n",
746 "979"
747 ]
748 },
749 {
750 "output_type": "stream",
751 "stream": "stdout",
752 "text": [
753 "\n",
754 "982"
755 ]
756 },
757 {
758 "output_type": "stream",
759 "stream": "stdout",
760 "text": [
761 "\n",
762 "979"
763 ]
764 },
765 {
766 "output_type": "stream",
767 "stream": "stdout",
768 "text": [
769 "\n",
770 "1 loops, best of 3: 52.9 s per loop\n"
771 ]
772 }
773 ],
774 "prompt_number": 111
775 },
776 {
777 "cell_type": "code",
778 "collapsed": false,
779 "input": [
780 "%%timeit\n",
781 "\n",
782 "wins = 0\n",
783 "for _ in range(1000):\n",
784 " g = Game(random.choice(WORDS), player=PlayerAdaptivePattern(WORDS))\n",
785 " g.play_game()\n",
786 " if g.game_won:\n",
787 " wins += 1\n",
788 "print(wins)"
789 ],
790 "language": "python",
791 "metadata": {},
792 "outputs": [
793 {
794 "output_type": "stream",
795 "stream": "stdout",
796 "text": [
797 "986\n",
798 "991"
799 ]
800 },
801 {
802 "output_type": "stream",
803 "stream": "stdout",
804 "text": [
805 "\n",
806 "989"
807 ]
808 },
809 {
810 "output_type": "stream",
811 "stream": "stdout",
812 "text": [
813 "\n",
814 "989"
815 ]
816 },
817 {
818 "output_type": "stream",
819 "stream": "stdout",
820 "text": [
821 "\n",
822 "1 loops, best of 3: 44.7 s per loop\n"
823 ]
824 }
825 ],
826 "prompt_number": 112
827 },
828 {
829 "cell_type": "code",
830 "collapsed": false,
831 "input": [
832 "class PlayerAdaptive:\n",
833 " def __init__(self, words):\n",
834 " self.candidate_words = words\n",
835 " \n",
836 " def guess(self, discovered, missed, lives):\n",
837 " self.filter_candidate_words(discovered, missed)\n",
838 " self.set_ordered_letters()\n",
839 " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
840 " self.ordered_subtract(guessed_letters)\n",
841 " return self.ordered_letters[0]\n",
842 "\n",
843 " def ordered_subtract(self, to_remove):\n",
844 " for r in to_remove:\n",
845 " if r in self.ordered_letters:\n",
846 " ri = self.ordered_letters.index(r)\n",
847 " self.ordered_letters = self.ordered_letters[:ri] + self.ordered_letters[ri+1:]\n",
848 " \n",
849 " def filter_candidate_words(self, discovered, missed):\n",
850 " pass\n",
851 " \n",
852 " def set_ordered_letters(self):\n",
853 " counts = collections.Counter(l.lower() \n",
854 " for l in ''.join(self.candidate_words) + string.ascii_lowercase \n",
855 " if l in string.ascii_letters)\n",
856 " self.ordered_letters = [p[0] for p in counts.most_common()]"
857 ],
858 "language": "python",
859 "metadata": {},
860 "outputs": [],
861 "prompt_number": 174
862 },
863 {
864 "cell_type": "code",
865 "collapsed": false,
866 "input": [
867 "class PlayerAdaptiveLength(PlayerAdaptive):\n",
868 " def __init__(self, words):\n",
869 " super().__init__(words)\n",
870 " self.word_len = None\n",
871 " self.ordered_letters = None\n",
872 " \n",
873 " def filter_candidate_words(self, discovered, missed):\n",
874 " if not self.word_len:\n",
875 " self.word_len = len(discovered)\n",
876 " self.candidate_words = [w for w in self.candidate_words if len(w) == self.word_len]\n",
877 " \n",
878 " def set_ordered_letters(self):\n",
879 " if not self.ordered_letters:\n",
880 " super().set_ordered_letters()"
881 ],
882 "language": "python",
883 "metadata": {},
884 "outputs": [],
885 "prompt_number": 175
886 },
887 {
888 "cell_type": "code",
889 "collapsed": false,
890 "input": [
891 "class PlayerAdaptiveIncludedLetters(PlayerAdaptive):\n",
892 " def filter_candidate_words(self, discovered, missed):\n",
893 " exp = re.compile('^' + ''.join(discovered).replace('_', '.') + '$')\n",
894 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]"
895 ],
896 "language": "python",
897 "metadata": {},
898 "outputs": [],
899 "prompt_number": 176
900 },
901 {
902 "cell_type": "code",
903 "collapsed": false,
904 "input": [
905 "class PlayerAdaptiveExcludedLetters(PlayerAdaptive):\n",
906 " def filter_candidate_words(self, discovered, missed):\n",
907 " if missed:\n",
908 " exp = re.compile('^[^' + ''.join(missed) + ']*$')\n",
909 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)] "
910 ],
911 "language": "python",
912 "metadata": {},
913 "outputs": [],
914 "prompt_number": 177
915 },
916 {
917 "cell_type": "code",
918 "collapsed": false,
919 "input": [
920 "class PlayerAdaptivePatternNegLookahead(PlayerAdaptive):\n",
921 " def filter_candidate_words(self, discovered, missed):\n",
922 " if missed:\n",
923 " exclusion_pattern = '(?!.*[' + ''.join(missed) + '])'\n",
924 " else:\n",
925 " exclusion_pattern = ''\n",
926 " exp = re.compile('^' + exclusion_pattern + ''.join(discovered).replace('_', '.') + '$')\n",
927 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]"
928 ],
929 "language": "python",
930 "metadata": {},
931 "outputs": [],
932 "prompt_number": 195
933 },
934 {
935 "cell_type": "code",
936 "collapsed": false,
937 "input": [
938 "class PlayerAdaptivePattern(PlayerAdaptive):\n",
939 " def filter_candidate_words(self, discovered, missed):\n",
940 " attempted_letters = [l for l in discovered if l != '_'] + missed\n",
941 " if attempted_letters:\n",
942 " exclusion_pattern = '[^' + ''.join(attempted_letters) + ']'\n",
943 " else:\n",
944 " exclusion_pattern = '.'\n",
945 " exp = re.compile('^' + ''.join(discovered).replace('_', exclusion_pattern) + '$')\n",
946 " self.candidate_words = [w for w in self.candidate_words if exp.match(w)]"
947 ],
948 "language": "python",
949 "metadata": {},
950 "outputs": [],
951 "prompt_number": 196
952 },
953 {
954 "cell_type": "code",
955 "collapsed": false,
956 "input": [
957 "%%timeit\n",
958 "\n",
959 "wins = 0\n",
960 "for _ in range(1000):\n",
961 " g = Game(random.choice(WORDS), player=PlayerAdaptiveLength(WORDS))\n",
962 " g.play_game()\n",
963 " if g.game_won:\n",
964 " wins += 1\n",
965 "print(wins)"
966 ],
967 "language": "python",
968 "metadata": {},
969 "outputs": [
970 {
971 "output_type": "stream",
972 "stream": "stdout",
973 "text": [
974 "453\n",
975 "494"
976 ]
977 },
978 {
979 "output_type": "stream",
980 "stream": "stdout",
981 "text": [
982 "\n",
983 "505"
984 ]
985 },
986 {
987 "output_type": "stream",
988 "stream": "stdout",
989 "text": [
990 "\n",
991 "477"
992 ]
993 },
994 {
995 "output_type": "stream",
996 "stream": "stdout",
997 "text": [
998 "\n",
999 "1 loops, best of 3: 24.3 s per loop\n"
1000 ]
1001 }
1002 ],
1003 "prompt_number": 179
1004 },
1005 {
1006 "cell_type": "code",
1007 "collapsed": false,
1008 "input": [
1009 "%%timeit\n",
1010 "\n",
1011 "wins = 0\n",
1012 "for _ in range(1000):\n",
1013 " g = Game(random.choice(WORDS), player=PlayerAdaptiveIncludedLetters(WORDS))\n",
1014 " g.play_game()\n",
1015 " if g.game_won:\n",
1016 " wins += 1\n",
1017 "print(wins)"
1018 ],
1019 "language": "python",
1020 "metadata": {},
1021 "outputs": [
1022 {
1023 "output_type": "stream",
1024 "stream": "stdout",
1025 "text": [
1026 "984\n",
1027 "983"
1028 ]
1029 },
1030 {
1031 "output_type": "stream",
1032 "stream": "stdout",
1033 "text": [
1034 "\n",
1035 "985"
1036 ]
1037 },
1038 {
1039 "output_type": "stream",
1040 "stream": "stdout",
1041 "text": [
1042 "\n",
1043 "982"
1044 ]
1045 },
1046 {
1047 "output_type": "stream",
1048 "stream": "stdout",
1049 "text": [
1050 "\n",
1051 "1 loops, best of 3: 52.9 s per loop\n"
1052 ]
1053 }
1054 ],
1055 "prompt_number": 180
1056 },
1057 {
1058 "cell_type": "code",
1059 "collapsed": false,
1060 "input": [
1061 "%%timeit\n",
1062 "\n",
1063 "wins = 0\n",
1064 "for _ in range(1000):\n",
1065 " g = Game(random.choice(WORDS), player=PlayerAdaptiveExcludedLetters(WORDS))\n",
1066 " g.play_game()\n",
1067 " if g.game_won:\n",
1068 " wins += 1\n",
1069 "print(wins)"
1070 ],
1071 "language": "python",
1072 "metadata": {},
1073 "outputs": [
1074 {
1075 "output_type": "stream",
1076 "stream": "stdout",
1077 "text": [
1078 "535\n",
1079 "509"
1080 ]
1081 },
1082 {
1083 "output_type": "stream",
1084 "stream": "stdout",
1085 "text": [
1086 "\n",
1087 "519"
1088 ]
1089 },
1090 {
1091 "output_type": "stream",
1092 "stream": "stdout",
1093 "text": [
1094 "\n",
1095 "507"
1096 ]
1097 },
1098 {
1099 "output_type": "stream",
1100 "stream": "stdout",
1101 "text": [
1102 "\n",
1103 "1 loops, best of 3: 11min 14s per loop\n"
1104 ]
1105 }
1106 ],
1107 "prompt_number": 181
1108 },
1109 {
1110 "cell_type": "code",
1111 "collapsed": false,
1112 "input": [
1113 "%%timeit\n",
1114 "\n",
1115 "wins = 0\n",
1116 "for _ in range(1000):\n",
1117 " g = Game(random.choice(WORDS), player=PlayerAdaptivePattern(WORDS))\n",
1118 " g.play_game()\n",
1119 " if g.game_won:\n",
1120 " wins += 1\n",
1121 "print(wins)"
1122 ],
1123 "language": "python",
1124 "metadata": {},
1125 "outputs": [
1126 {
1127 "output_type": "stream",
1128 "stream": "stdout",
1129 "text": [
1130 "993\n",
1131 "990"
1132 ]
1133 },
1134 {
1135 "output_type": "stream",
1136 "stream": "stdout",
1137 "text": [
1138 "\n",
1139 "992"
1140 ]
1141 },
1142 {
1143 "output_type": "stream",
1144 "stream": "stdout",
1145 "text": [
1146 "\n",
1147 "994"
1148 ]
1149 },
1150 {
1151 "output_type": "stream",
1152 "stream": "stdout",
1153 "text": [
1154 "\n",
1155 "1 loops, best of 3: 44.1 s per loop\n"
1156 ]
1157 }
1158 ],
1159 "prompt_number": 197
1160 },
1161 {
1162 "cell_type": "code",
1163 "collapsed": false,
1164 "input": [
1165 "%%timeit\n",
1166 "\n",
1167 "wins = 0\n",
1168 "for _ in range(1000):\n",
1169 " g = Game(random.choice(WORDS), player=PlayerAdaptivePatternNegLookahead(WORDS))\n",
1170 " g.play_game()\n",
1171 " if g.game_won:\n",
1172 " wins += 1\n",
1173 "print(wins)"
1174 ],
1175 "language": "python",
1176 "metadata": {},
1177 "outputs": [
1178 {
1179 "output_type": "stream",
1180 "stream": "stdout",
1181 "text": [
1182 "989\n",
1183 "993"
1184 ]
1185 },
1186 {
1187 "output_type": "stream",
1188 "stream": "stdout",
1189 "text": [
1190 "\n",
1191 "994"
1192 ]
1193 },
1194 {
1195 "output_type": "stream",
1196 "stream": "stdout",
1197 "text": [
1198 "\n",
1199 "993"
1200 ]
1201 },
1202 {
1203 "output_type": "stream",
1204 "stream": "stdout",
1205 "text": [
1206 "\n",
1207 "1 loops, best of 3: 46 s per loop\n"
1208 ]
1209 }
1210 ],
1211 "prompt_number": 198
1212 },
1213 {
1214 "cell_type": "code",
1215 "collapsed": false,
1216 "input": [
1217 "for _ in range(1000):\n",
1218 " g = Game(random.choice(WORDS), player=PlayerAdaptivePattern(WORDS))\n",
1219 " g.play_game()\n",
1220 " if not g.game_won:\n",
1221 " print(g.target, g.discovered, g.wrong_letters)"
1222 ],
1223 "language": "python",
1224 "metadata": {},
1225 "outputs": [
1226 {
1227 "output_type": "stream",
1228 "stream": "stdout",
1229 "text": [
1230 "rutted ['_', 'u', 't', 't', 'e', 'd'] ['a', 'o', 'i', 'l', 's', 'g', 'b', 'j', 'n', 'p']\n",
1231 "cur"
1232 ]
1233 },
1234 {
1235 "output_type": "stream",
1236 "stream": "stdout",
1237 "text": [
1238 " ['_', 'u', '_'] ['a', 'o', 'e', 'i', 'b', 'g', 'n', 'm', 'p', 't']\n",
1239 "wiles"
1240 ]
1241 },
1242 {
1243 "output_type": "stream",
1244 "stream": "stdout",
1245 "text": [
1246 " ['_', 'i', '_', 'e', 's'] ['a', 'm', 'n', 'v', 't', 'r', 'k', 'f', 'p', 'd']\n",
1247 "oak"
1248 ]
1249 },
1250 {
1251 "output_type": "stream",
1252 "stream": "stdout",
1253 "text": [
1254 " ['_', 'a', '_'] ['t', 'p', 'g', 'w', 'd', 'y', 'r', 'm', 'b', 's']\n"
1255 ]
1256 }
1257 ],
1258 "prompt_number": 217
1259 },
1260 {
1261 "cell_type": "code",
1262 "collapsed": false,
1263 "input": [],
1264 "language": "python",
1265 "metadata": {},
1266 "outputs": []
1267 }
1268 ],
1269 "metadata": {}
1270 }
1271 ]
1272 }