{
- "metadata": {
- "name": "",
- "signature": "sha256:5e9f030b42097ebbcce2654cdb1d9370fde38b61bdbfa85a0cc700e76d5a8a71"
- },
- "nbformat": 3,
- "nbformat_minor": 0,
- "worksheets": [
+ "cells": [
{
- "cells": [
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import re\n",
- "import random\n",
- "import string\n",
- "import collections"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 71
- },
- {
- "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": 72
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "STARTING_LIVES = 10"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 73
- },
- {
- "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",
- " self.do_turn()\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": 74
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS))"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 75
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.target"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 76,
- "text": [
- "'strife'"
- ]
- }
- ],
- "prompt_number": 76
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.discovered"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 77,
- "text": [
- "['_', '_', '_', '_', '_', '_']"
- ]
- }
- ],
- "prompt_number": 77
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.do_turn()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: e\n"
- ]
- }
- ],
- "prompt_number": 78
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.lives"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 79,
- "text": [
- "10"
- ]
- }
- ],
- "prompt_number": 79
- },
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Putting both halves together\n",
+ "We now have systems that can do both halves of the Hangman game. Now it's time to put them together so that we can get a machine to play itself. At the moment, let's concentrate on just the plumbing: let's get the two halves working together. In the next step, we'll think about different strategies and compare their effectiveness.\n",
+ "\n",
+ "The word of this section is \"encapsulation.\" \n",
+ "\n",
+ "First, a change in terminology. We'll call a `player` the thing that makes the guesses (the guesser player from before). We'll call a `game` the thing that handles receiving guesses, updating `discovered` words, updating lives and all of that. That's what was the setting player from before, but without the bit about picking a random word. We'll have the `game` accept the `target` as a parameter, so that we can test everything more easily (if we know what word the `player` is trying to guess, we can predict what it should do).\n",
+ "\n",
+ "Back to encapsulation.\n",
+ "\n",
+ "We want to bundle all the state information for a `game` into one 'thing' so that we don't need to worry about global variables. We will also want to bundle up everything to do with a `player` into one 'thing' so we can tell the game about it. For the `player`, the thing will include both any state it needs and the definition of that `player`'s guessing strategy. We're also going to have a bunch of related players, all doing much the same thing but with different strategies.\n",
+ "\n",
+ "In this case, objects seem like a natural fit.\n",
+ "\n",
+ "(Insert Neil's aikido instructor story here.)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Object-orientation in Python\n",
+ "There are a few things to remember about object orientation in Python.\n",
+ "\n",
+ "1. It's an ugly kludge that was bolted on long after the language was defined.\n",
+ "\n",
+ "2. `self` needs to be passed in to all object methods as the first parameter, though it doesn't appear when you call the method.\n",
+ "\n",
+ "3. Use `self.whatever` to refer to the instance variable `whatever`\n",
+ "\n",
+ "4. Use `self.however(arg1, arg2)` when one method calls another in the same object.\n",
+ "\n",
+ "Apart from that, it's pretty straightforward."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "import re\n",
+ "import random\n",
+ "import string\n",
+ "import collections"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "WORDS = [w.strip() for w in open('/usr/share/dict/british-english').readlines() \n",
+ " if re.match(r'^[a-z]*$', w.strip())]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "STARTING_LIVES = 10"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This is pretty much the same code as for the `setter` part, just with plenty of `self` statements scatter around. A few things to note:\n",
+ "\n",
+ "* `initialise()` is now named `__init__()` (note the double underscores fore and aft).\n",
+ "* `player` and `lives` are parameters to the `game`, but with default values.\n",
+ "* I've added two new flags, `game_won` and `game_lost`.\n",
+ "* `do_turn` asks the player for a guess, if there is a player.\n",
+ "* The `guess()` method of the `player` is passed the `lives`, in case the guess should change depending on the progress of the game (the `player` can always ignore it).\n",
+ "* After a guess has been processed, `do_turn` has a few more statements to set the relevant flags to represent the state of the game.\n",
+ "* `report_on_game()` has been added for when the game is being played against a human."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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",
+ " self.do_turn()\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"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's test it!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "g = Game(random.choice(WORDS))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.wrong_letters"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "'distension'"
+ ]
+ },
+ "execution_count": 48,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 80,
- "text": [
- "[]"
- ]
- }
- ],
- "prompt_number": 80
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.target"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.do_turn()"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "['_', '_', '_', '_', '_', '_', '_', '_', '_', '_']"
+ ]
+ },
+ "execution_count": 49,
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ e : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: d\n"
- ]
- }
- ],
- "prompt_number": 81
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.discovered"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.lives"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 82,
- "text": [
- "9"
- ]
- }
- ],
- "prompt_number": 82
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Word: _ _ _ _ _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n",
+ "Enter letter: e\n"
+ ]
+ }
+ ],
+ "source": [
+ "g.do_turn()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.discovered"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "10"
+ ]
+ },
+ "execution_count": 51,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 83,
- "text": [
- "['_', '_', '_', '_', '_', 'e']"
- ]
- }
- ],
- "prompt_number": 83
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.lives"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.wrong_letters"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "[]"
+ ]
+ },
+ "execution_count": 52,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 84,
- "text": [
- "['d']"
- ]
- }
- ],
- "prompt_number": 84
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.wrong_letters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS))\n",
- "g.play_game()"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: d\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ _ d : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: e\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: f\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 9 , wrong guesses: f\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: e\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 9 , wrong guesses: f\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: s\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 8 , wrong guesses: f s\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: t\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 7 , wrong guesses: f s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: n\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 6 , wrong guesses: f n s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: m\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 5 , wrong guesses: f m n s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: h\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 4 , wrong guesses: f h m n s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: o\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ _ _ e d : Lives = 3 , wrong guesses: f h m n o s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: i\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ e _ i _ e d : Lives = 3 , wrong guesses: f h m n o s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: r\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: r e _ i r e d : Lives = 3 , wrong guesses: f h m n o s t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: w\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "You won! The word was rewired\n"
- ]
- },
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 85,
- "text": [
- "True"
- ]
- }
- ],
- "prompt_number": 85
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Word: _ _ _ _ e _ _ _ _ _ : Lives = 10 , wrong guesses: \n",
+ "Enter letter: q\n"
+ ]
+ }
+ ],
+ "source": [
+ "g.do_turn()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS))\n",
- "g.play_game()"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "9"
+ ]
+ },
+ "execution_count": 54,
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ : Lives = 10 , wrong guesses: \n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: e\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ _ : Lives = 9 , wrong guesses: e\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: s\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 9 , wrong guesses: e\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: t\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 8 , wrong guesses: e t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: o\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 7 , wrong guesses: e o t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: i\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 6 , wrong guesses: e i o t\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: u\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 5 , wrong guesses: e i o t u\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: a\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ _ _ _ s : Lives = 4 , wrong guesses: a e i o t u\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: y\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ y _ _ s : Lives = 4 , wrong guesses: a e i o t u\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: w\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ y _ _ s : Lives = 3 , wrong guesses: a e i o t u w\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: h\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: h y _ _ s : Lives = 3 , wrong guesses: a e i o t u w\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: m\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: h y m _ s : Lives = 3 , wrong guesses: a e i o t u w\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: n\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "You won! The word was hymns\n"
- ]
- },
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 86,
- "text": [
- "True"
- ]
- }
- ],
- "prompt_number": 86
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.lives"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.target"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "['_', '_', '_', '_', 'e', '_', '_', '_', '_', '_']"
+ ]
+ },
+ "execution_count": 55,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 108,
- "text": [
- "'six'"
- ]
- }
- ],
- "prompt_number": 108
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.discovered"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "class PlayerAlphabetical:\n",
- " def guess(self, discovered, missed, lives):\n",
- " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
- " return [l for l in string.ascii_lowercase if l not in guessed_letters][0]"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "['q']"
+ ]
+ },
+ "execution_count": 56,
"metadata": {},
- "outputs": [],
- "prompt_number": 109
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.wrong_letters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerAlphabetical())"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 110
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Word: _ _ _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n",
+ "Enter letter: e\n",
+ "Word: e _ e _ _ _ _ e : Lives = 10 , wrong guesses: \n",
+ "Enter letter: x\n",
+ "Word: e _ e _ _ _ _ e : Lives = 9 , wrong guesses: x\n",
+ "Enter letter: s\n",
+ "Word: e _ e _ _ _ _ e : Lives = 8 , wrong guesses: s x\n",
+ "Enter letter: l\n",
+ "Word: e _ e _ _ _ _ e : Lives = 7 , wrong guesses: l s x\n",
+ "Enter letter: t\n",
+ "Word: e _ e _ _ _ _ e : Lives = 6 , wrong guesses: l s t x\n",
+ "Enter letter: m\n",
+ "Word: e _ e _ _ _ _ e : Lives = 5 , wrong guesses: l m s t x\n",
+ "Enter letter: h\n",
+ "Word: e _ e _ _ _ _ e : Lives = 4 , wrong guesses: h l m s t x\n",
+ "Enter letter: i\n",
+ "Word: e _ e _ _ _ _ e : Lives = 3 , wrong guesses: h i l m s t x\n",
+ "Enter letter: a\n",
+ "Word: e _ e _ _ _ _ e : Lives = 2 , wrong guesses: a h i l m s t x\n",
+ "Enter letter: o\n",
+ "Word: e _ e _ _ o _ e : Lives = 2 , wrong guesses: a h i l m s t x\n",
+ "Enter letter: n\n",
+ "Word: e _ e _ _ o n e : Lives = 2 , wrong guesses: a h i l m s t x\n",
+ "Enter letter: r\n",
+ "Word: e _ e r _ o n e : Lives = 2 , wrong guesses: a h i l m s t x\n",
+ "Enter letter: v\n",
+ "Word: e v e r _ o n e : Lives = 2 , wrong guesses: a h i l m s t x\n",
+ "Enter letter: y\n",
+ "You won! The word was everyone\n"
+ ]
},
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.play_game()"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 57,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 111,
- "text": [
- "False"
- ]
- }
- ],
- "prompt_number": 111
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS))\n",
+ "g.play_game()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.discovered"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 112,
- "text": [
- "['l', 'e', 'g', 'a', 'l', 'l', '_']"
- ]
- }
- ],
- "prompt_number": 112
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Word: _ _ _ _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n",
+ "Enter letter: q\n",
+ "Word: _ _ _ _ _ _ _ _ _ : Lives = 9 , wrong guesses: q\n",
+ "Enter letter: z\n",
+ "Word: _ _ _ _ _ _ _ _ _ : Lives = 8 , wrong guesses: q z\n",
+ "Enter letter: x\n",
+ "Word: _ _ _ _ _ _ _ _ _ : Lives = 7 , wrong guesses: q x z\n",
+ "Enter letter: e\n",
+ "Word: _ _ _ _ _ _ _ _ _ : Lives = 6 , wrong guesses: e q x z\n",
+ "Enter letter: a\n",
+ "Word: _ _ a _ _ _ _ _ _ : Lives = 6 , wrong guesses: e q x z\n",
+ "Enter letter: v\n",
+ "Word: _ _ a _ _ _ _ _ _ : Lives = 5 , wrong guesses: e q v x z\n",
+ "Enter letter: b\n",
+ "Word: _ _ a _ _ _ _ _ _ : Lives = 4 , wrong guesses: b e q v x z\n",
+ "Enter letter: k\n",
+ "Word: _ _ a _ k _ k _ _ : Lives = 4 , wrong guesses: b e q v x z\n",
+ "Enter letter: l\n",
+ "Word: _ _ a _ k _ k _ _ : Lives = 3 , wrong guesses: b e l q v x z\n",
+ "Enter letter: j\n",
+ "Word: _ _ a _ k _ k _ _ : Lives = 2 , wrong guesses: b e j l q v x z\n",
+ "Enter letter: p\n",
+ "Word: _ _ a _ k _ k _ _ : Lives = 1 , wrong guesses: b e j l p q v x z\n",
+ "Enter letter: d\n",
+ "You lost. The word was sharkskin\n"
+ ]
},
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g.target"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 58,
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 113,
- "text": [
- "'legally'"
- ]
- }
- ],
- "prompt_number": 113
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS))\n",
+ "g.play_game()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 59,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "'sharkskin'"
+ ]
+ },
+ "execution_count": 59,
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: cavalry ; Discovered: ['c', 'a', '_', 'a', 'l', '_', '_'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 114
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.target"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Player objects\n",
+ "Let's work ourselves gently into this.\n",
+ "\n",
+ "In the first instance, the only thing a `player` needs is to respond to the `guess` method. Let's make objects with just this method. Let's even make it simpler than the player from the `guesser` stage, and have it just guess letters in alphabetical order."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 60,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "class PlayerAlphabetical:\n",
+ " def guess(self, discovered, missed, lives):\n",
+ " return [l for l in string.ascii_lowercase if l not in discovered + missed][0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "That wasn't too hard, was it?\n",
+ "\n",
+ "Let's use it to play a game."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerAlphabetical())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 70,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "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()]\n",
- "\n",
- "class PlayerFreqOrdered:\n",
- " def guess(self, discovered, missed, lives):\n",
- " guessed_letters = [l.lower() for l in discovered + missed if l in string.ascii_letters]\n",
- " return [l for l in LETTERS_IN_ORDER if l not in guessed_letters][0]"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 70,
"metadata": {},
- "outputs": [],
- "prompt_number": 115
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.play_game()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "['c', 'e', '_', '_', 'i', 'f', 'i', 'c', 'a', '_', 'e', '_']"
+ ]
+ },
+ "execution_count": 71,
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: deathblow ; Discovered: ['d', 'e', 'a', 't', 'h', '_', 'l', 'o', 'w'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 116
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.discovered"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
+ "data": {
+ "text/plain": [
+ "'certificates'"
+ ]
+ },
+ "execution_count": 72,
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: littered ; Discovered: ['l', 'i', 't', 't', 'e', 'r', 'e', 'd'] ; Lives remaining: 5\n"
- ]
- }
- ],
- "prompt_number": 117
- },
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g.target"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Bored with looking at all the state of the game with different cells. Let's have a `print()` statement that tells us what we need."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: licenced ; Discovered: ['l', 'i', 'c', 'e', 'n', 'c', 'e', 'd'] ; Lives remaining: 1\n"
- ]
- }
- ],
- "prompt_number": 118
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: turnoffs ; Discovered: ['_', '_', '_', '_', '_', 'f', 'f', '_'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Another player\n",
+ "Let's reimplement our player that does letters in frequency order. Again, this is essentially code reused from earlier."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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()]\n",
+ "\n",
+ "class PlayerFreqOrdered:\n",
+ " def guess(self, discovered, missed, lives):\n",
+ " return [l for l in LETTERS_IN_ORDER if l not in discovered + missed][0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "class PlayerFixedOrder:\n",
- " def __init__(self, ordered_letters):\n",
- " self.ordered_letters = ordered_letters\n",
- " \n",
- " def guess(self, discovered, missed, lives):\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]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 119
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: cartons ; Discovered: ['c', 'a', 'r', 't', 'o', 'n', 's'] ; Lives remaining: 2\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "class PlayerAlphabetical(PlayerFixedOrder):\n",
- " def __init__(self):\n",
- " super().__init__(string.ascii_lowercase)\n",
- "\n",
- "class PlayerFreqOrdered(PlayerFixedOrder):\n",
- " def __init__(self):\n",
- " super().__init__(LETTERS_IN_ORDER)\n"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 120
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: douching ; Discovered: ['d', 'o', 'u', 'c', 'h', 'i', 'n', '_'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: unworthier ; Discovered: ['u', 'n', 'w', 'o', 'r', 't', 'h', 'i', 'e', 'r'] ; Lives remaining: 5\n"
- ]
- }
- ],
- "prompt_number": 121
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: minimisation ; Discovered: ['m', 'i', 'n', 'i', 'm', 'i', 's', 'a', 't', 'i', 'o', 'n'] ; Lives remaining: 4\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Player subclasses and inheritance\n",
+ "Time to DRY the code a little. Both of these players (`PlayerAlphabetical` and `PlayerFreqOrdered`) are essentially the same. The only difference is the set of letters used in the middle of the `guess` method. \n",
+ "\n",
+ "Let's create a generic \"letters in a fixed order\" class that has that implementation of `guess` and is passed in a set of letters in order. The two players we already have are subclasses of that, where we have pre-packaged letter orders.\n",
+ "\n",
+ "Here's the generic player. Note that the ordered letters are passed in as a parameter to the `__init__()` method, and `guess()` uses that letter sequence."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "class PlayerFixedOrder:\n",
+ " def __init__(self, ordered_letters):\n",
+ " self.ordered_letters = ordered_letters\n",
+ " \n",
+ " def guess(self, discovered, missed, lives):\n",
+ " return [l for l in self.ordered_letters if l not in discovered + missed][0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can now specify the subclasses, using the fixed order. The initialisation of the subclasses now takes no additional parameter, but we pass the hardcoded order to the superclass's `__init__()`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "class PlayerAlphabetical(PlayerFixedOrder):\n",
+ " def __init__(self):\n",
+ " super().__init__(string.ascii_lowercase)\n",
+ "\n",
+ "class PlayerFreqOrdered(PlayerFixedOrder):\n",
+ " def __init__(self):\n",
+ " super().__init__(LETTERS_IN_ORDER)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Does it work?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: kneel ; Discovered: ['_', 'n', 'e', 'e', 'l'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 122
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: yogi ; Discovered: ['_', 'o', '_', 'i'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: provisoes ; Discovered: ['_', '_', '_', '_', 'i', '_', '_', 'e', '_'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 123
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: slimmest ; Discovered: ['s', 'l', 'i', 'm', 'm', 'e', 's', 't'] ; Lives remaining: 3\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: invincible ; Discovered: ['_', '_', 'v', '_', '_', '_', '_', '_', '_', '_'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 124
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: diseases ; Discovered: ['d', 'i', '_', 'e', 'a', '_', 'e', '_'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Can we use the generic version directly?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
- "g.play_game()\n",
- "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Target: clogging ; Discovered: ['_', '_', '_', '_', '_', '_', '_', '_'] ; Lives remaining: 0\n"
- ]
- }
- ],
- "prompt_number": 125
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: pardon ; Discovered: ['p', '_', 'r', '_', 'o', 'n'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "wins = 0\n",
- "for _ in range(1000):\n",
- " g = Game(random.choice(WORDS), player=PlayerAlphabetical())\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": [
- "44\n"
- ]
- }
- ],
- "prompt_number": 126
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Target: grouchier ; Discovered: ['_', 'r', 'o', 'u', '_', '_', '_', '_', 'r'] ; Lives remaining: 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
+ "g.play_game()\n",
+ "print('Target:', g.target, '; Discovered:', g.discovered, '; Lives remaining:', g.lives)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Mass gaming\n",
+ "Now we can get machines playing each other, we get get them playing *lots* of games and just tell us the summaries. \n",
+ "\n",
+ "Which of these three methods (alphabetical, frequency ordered, reverse alphabetical) is the best? Let's get each player to play 1000 random games and see which gets the most wins."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 92,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "wins = 0\n",
- "for _ in range(1000):\n",
- " g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\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": [
- "320\n"
- ]
- }
- ],
- "prompt_number": 127
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "49\n"
+ ]
+ }
+ ],
+ "source": [
+ "wins = 0\n",
+ "for _ in range(1000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerAlphabetical())\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 96,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "wins = 0\n",
- "for _ in range(1000):\n",
- " g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\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": [
- "7\n"
- ]
- }
- ],
- "prompt_number": 128
- },
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "309\n"
+ ]
+ }
+ ],
+ "source": [
+ "wins = 0\n",
+ "for _ in range(1000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerFreqOrdered())\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 94,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
{
- "cell_type": "code",
- "collapsed": false,
- "input": [],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 128
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n"
+ ]
}
],
- "metadata": {}
+ "source": [
+ "wins = 0\n",
+ "for _ in range(1000):\n",
+ " g = Game(random.choice(WORDS), player=PlayerFixedOrder(list(reversed(string.ascii_lowercase))))\n",
+ " g.play_game()\n",
+ " if g.game_won:\n",
+ " wins += 1\n",
+ "print(wins)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Frequency ordered is much better than the others, but still only wins about 30% of the time. I'm sure we can do better.\n",
+ "\n",
+ "That's the next part..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": []
}
- ]
-}
\ No newline at end of file
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.2+"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}