Added OO version of hangman, tweaked original.
authorNeil Smith <neil.git@njae.me.uk>
Mon, 29 Sep 2014 14:39:35 +0000 (15:39 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Mon, 29 Sep 2014 14:39:35 +0000 (15:39 +0100)
.ipynb_checkpoints/hangman-setter-oo-checkpoint.ipynb [new file with mode: 0644]
hangman-setter-oo.ipynb [new file with mode: 0644]
hangman-setter.ipynb

diff --git a/.ipynb_checkpoints/hangman-setter-oo-checkpoint.ipynb b/.ipynb_checkpoints/hangman-setter-oo-checkpoint.ipynb
new file mode 100644 (file)
index 0000000..532998b
--- /dev/null
@@ -0,0 +1,778 @@
+{
+ "metadata": {
+  "name": "",
+  "signature": "sha256:3fd62f8c6cf4619b87bb367305e68080edd846095261b09f98699554a3e60841"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import re\n",
+      "import random"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "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": 2
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "STARTING_LIVES = 10\n",
+      "lives = 0"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "wrong_letters = []"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len(WORDS)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "62856"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "WORDS[30000:30010]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 6,
+       "text": [
+        "['jotted',\n",
+        " 'jotting',\n",
+        " 'jottings',\n",
+        " 'joule',\n",
+        " 'joules',\n",
+        " 'jounce',\n",
+        " 'jounced',\n",
+        " 'jounces',\n",
+        " 'jouncing',\n",
+        " 'journal']"
+       ]
+      }
+     ],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "target = random.choice(WORDS)\n",
+      "target"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 14,
+       "text": [
+        "'rebounds'"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "discovered = list('_' * len(target))\n",
+      "discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 8,
+       "text": [
+        "['_', '_', '_', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "letter = input('Enter letter: ').strip().lower()[0]\n",
+      "letter"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: sdfsdfs\n"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 9,
+       "text": [
+        "'s'"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def find_all(string, letter):\n",
+      "    locations = []\n",
+      "    starting=0\n",
+      "    location = string.find(letter)\n",
+      "    while location > -1:\n",
+      "        locations += [location]\n",
+      "        starting = location + 1\n",
+      "        location = string.find(letter, starting)\n",
+      "    return locations"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "find_all('happy', 'q')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 12,
+       "text": [
+        "[]"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "guessed_letter = 'e'\n",
+      "locations = find_all(target, guessed_letter)\n",
+      "for location in locations:\n",
+      "    discovered[location] = guessed_letter\n",
+      "discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 15,
+       "text": [
+        "['_', 'e', '_', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def updated_discovered_word(discovered, guessed_letter):\n",
+      "    locations = find_all(target, guessed_letter)\n",
+      "    for location in locations:\n",
+      "        discovered[location] = guessed_letter\n",
+      "    return discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def initialise():\n",
+      "    global lives, target, discovered, wrong_letters\n",
+      "    lives = STARTING_LIVES\n",
+      "    target = random.choice(WORDS)\n",
+      "    discovered = list('_' * len(target))\n",
+      "    wrong_letters = []"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 19
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def do_turn():\n",
+      "    global discovered, lives, wrong_letters\n",
+      "    print('Word:', ' '.join(discovered), ' : Lives =', lives, ', wrong guesses:', ' '.join(sorted(wrong_letters)))\n",
+      "    guess = input('Enter letter: ').strip().lower()[0]\n",
+      "    if guess in target:\n",
+      "        updated_discovered_word(discovered, guess)\n",
+      "    else:\n",
+      "        lives -= 1\n",
+      "        if guess not in wrong_letters:\n",
+      "            wrong_letters += [guess]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 27
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def play_game():\n",
+      "    global discovered, lives\n",
+      "    initialise()\n",
+      "    game_finished = False\n",
+      "    do_turn()\n",
+      "    while not game_finished:\n",
+      "        if '_' not in discovered:\n",
+      "            print('You won! The word was', target)\n",
+      "            game_finished = True\n",
+      "        elif lives <= 0:\n",
+      "            print('You lost. The word was', target)\n",
+      "            game_finished = True\n",
+      "        else:\n",
+      "            do_turn()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "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: e\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e _ _ _ _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: a\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e _ _ a _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: i\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e _ _ a _ _ _ _ _ i _ i _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: o\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e _ _ a _ _ _ o _ i _ i _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: t\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e _ _ a _ _ _ o _ i t i _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: r\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: n\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 9 , wrong guesses: n\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: s\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: h\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: h e r _ a _ h r o _ i t i _  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: c\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: h e r _ a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: c\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: h e r _ a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: m\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: h e r m a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: p\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: h e r m a p h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: d\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "You won! The word was hermaphroditic\n"
+       ]
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "class Game:\n",
+      "    def __init__(self, target, lives=STARTING_LIVES):\n",
+      "        self.lives = lives\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",
+      "        locations = []\n",
+      "        starting=0\n",
+      "        location = self.target.find(letter)\n",
+      "        while location > -1:\n",
+      "            locations += [location]\n",
+      "            starting = location + 1\n",
+      "            location = self.target.find(letter, starting)\n",
+      "        return locations\n",
+      "    \n",
+      "    def updated_discovered_word(self, guessed_letter):\n",
+      "        locations = 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",
+      "        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",
+      "        if guess in self.target:\n",
+      "            updated_discovered_word(self, 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 play_game(self):\n",
+      "        do_turn()\n",
+      "        while not self.game_finished:\n",
+      "            if self.game_won:\n",
+      "                print('You won! The word was', self.target)\n",
+      "            elif self.game_lost:\n",
+      "                print('You lost. The word was', self.target)\n",
+      "            else:\n",
+      "                do_turn()\n",
+      "        return self.game_won"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 47
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g = Game(random.choice(WORDS))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 48
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.target"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 49,
+       "text": [
+        "'paintbrush'"
+       ]
+      }
+     ],
+     "prompt_number": 49
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 50,
+       "text": [
+        "['_', '_', '_', '_', '_', '_', '_', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 50
+    },
+    {
+     "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: x\n"
+       ]
+      }
+     ],
+     "prompt_number": 51
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.lives"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 52,
+       "text": [
+        "9"
+       ]
+      }
+     ],
+     "prompt_number": 52
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.wrong_letters"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 53,
+       "text": [
+        "['x']"
+       ]
+      }
+     ],
+     "prompt_number": 53
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.do_turn()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ _ _ _ _ _ _ _  : Lives = 9 , wrong guesses: x\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: t\n"
+       ]
+      },
+      {
+       "ename": "TypeError",
+       "evalue": "'Game' object does not support item assignment",
+       "output_type": "pyerr",
+       "traceback": [
+        "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
+        "\u001b[1;32m<ipython-input-54-1beb96467341>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdo_turn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+        "\u001b[1;32m<ipython-input-47-8f8ddb756c32>\u001b[0m in \u001b[0;36mdo_turn\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m     31\u001b[0m         \u001b[0mguess\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Enter letter: '\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlower\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     32\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mguess\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtarget\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 33\u001b[1;33m             \u001b[0mupdated_discovered_word\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mguess\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     34\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     35\u001b[0m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlives\u001b[0m \u001b[1;33m-=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+        "\u001b[1;32m<ipython-input-18-572b4e76dcf5>\u001b[0m in \u001b[0;36mupdated_discovered_word\u001b[1;34m(discovered, guessed_letter)\u001b[0m\n\u001b[0;32m      2\u001b[0m     \u001b[0mlocations\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfind_all\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtarget\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mguessed_letter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mlocation\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mlocations\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m         \u001b[0mdiscovered\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mlocation\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mguessed_letter\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mdiscovered\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+        "\u001b[1;31mTypeError\u001b[0m: 'Game' object does not support item assignment"
+       ]
+      }
+     ],
+     "prompt_number": 54
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/hangman-setter-oo.ipynb b/hangman-setter-oo.ipynb
new file mode 100644 (file)
index 0000000..bc528ce
--- /dev/null
@@ -0,0 +1,799 @@
+{
+ "metadata": {
+  "name": "",
+  "signature": "sha256:44071c1a95bc0678534109dd2aa9b1d6318c87aa5048ca952603795efd142b14"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import re\n",
+      "import random"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "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": 2
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "STARTING_LIVES = 10"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "class Game:\n",
+      "    def __init__(self, target, lives=STARTING_LIVES):\n",
+      "        self.lives = lives\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",
+      "        locations = []\n",
+      "        starting=0\n",
+      "        location = self.target.find(letter)\n",
+      "        while location > -1:\n",
+      "            locations += [location]\n",
+      "            starting = location + 1\n",
+      "            location = self.target.find(letter, starting)\n",
+      "        return locations\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",
+      "        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",
+      "        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 play_game(self):\n",
+      "        self.do_turn()\n",
+      "        while not self.game_finished:\n",
+      "            self.do_turn()\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\n",
+      "    \n",
+      "    def play_game_with_report(self):\n",
+      "        self.play_game()\n",
+      "        self.report_on_game()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 35
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g = Game(random.choice(WORDS))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 22
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.target"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 23,
+       "text": [
+        "'cooing'"
+       ]
+      }
+     ],
+     "prompt_number": 23
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 24,
+       "text": [
+        "['_', '_', '_', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 24
+    },
+    {
+     "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: x\n"
+       ]
+      }
+     ],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.lives"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 26,
+       "text": [
+        "9"
+       ]
+      }
+     ],
+     "prompt_number": 26
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.wrong_letters"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 27,
+       "text": [
+        "['x']"
+       ]
+      }
+     ],
+     "prompt_number": 27
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.do_turn()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ _ _ _  : Lives = 9 , wrong guesses: x\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: o\n"
+       ]
+      }
+     ],
+     "prompt_number": 28
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.lives"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 29,
+       "text": [
+        "9"
+       ]
+      }
+     ],
+     "prompt_number": 29
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 30,
+       "text": [
+        "['_', 'o', 'o', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.wrong_letters"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 31,
+       "text": [
+        "['x']"
+       ]
+      }
+     ],
+     "prompt_number": 31
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g = Game(random.choice(WORDS))\n",
+      "g.play_game_with_report()"
+     ],
+     "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"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ _ _ _ _ _ _ _  : Lives = 9 , wrong guesses: e\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: a\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ _ _  : 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: _ a _ _ _ _ a _ t _  : Lives = 9 , wrong guesses: e\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: o\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ t _  : Lives = 8 , wrong guesses: e o\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: h\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ t _  : Lives = 7 , wrong guesses: e h o\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: s\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ t s  : Lives = 7 , wrong guesses: e h o\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: r\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ t s  : Lives = 6 , wrong guesses: e h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: d\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a _ _ _ _ a _ t s  : Lives = 5 , wrong guesses: d e h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: l\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a l l _ _ a _ t s  : Lives = 5 , wrong guesses: d e h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: f\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a l l _ _ a _ t s  : Lives = 4 , wrong guesses: d e f h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: n\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ a l l _ _ a n t s  : Lives = 4 , wrong guesses: d e f h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: g\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: g a l l _ _ a n t s  : Lives = 4 , wrong guesses: d e f h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: i\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: g a l l i _ a n t s  : Lives = 4 , wrong guesses: d e f h o r\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: v\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "You won! The word was gallivants\n"
+       ]
+      }
+     ],
+     "prompt_number": 37
+    },
+    {
+     "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: e\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e _ _ _  : Lives = 10 , wrong guesses: \n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: a\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e _ _ _  : Lives = 9 , wrong guesses: a\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: i\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e i _ _  : Lives = 9 , wrong guesses: a\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: n\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e i n _  : Lives = 9 , wrong guesses: a\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: g\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e i n g  : Lives = 9 , wrong guesses: a\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: u\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: _ _ _ e e i n g  : Lives = 8 , wrong guesses: a u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: s\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ _ e e i n g  : Lives = 8 , wrong guesses: a u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: h\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ _ e e i n g  : Lives = 7 , wrong guesses: a h u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: c\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ _ e e i n g  : Lives = 6 , wrong guesses: a c h u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: t\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ _ e e i n g  : Lives = 5 , wrong guesses: a c h t u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: r\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ r e e i n g  : Lives = 5 , wrong guesses: a c h t u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: c\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Word: s _ r e e i n g  : Lives = 4 , wrong guesses: a c h t u\n"
+       ]
+      },
+      {
+       "name": "stdout",
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Enter letter: p\n"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 38,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 38
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.target"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 39,
+       "text": [
+        "'spreeing'"
+       ]
+      }
+     ],
+     "prompt_number": 39
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
index c1d2ef0d234f27e3c62c78a5b6f48ce086fc3c04..bcd2db902777a3330a00703ff12fd37901d25b72 100644 (file)
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:db806d8bbe929161fce8776d2eeac6bad40d1abb93a97d112b974b6a8d50bdd0"
+  "signature": "sha256:668f52295bb8e65ad2ddd9293b48c435ea624c27afc5b1fec5862539fb575f75"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -53,7 +53,7 @@
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 33
+     "prompt_number": 4
     },
     {
      "cell_type": "code",
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 4,
+       "prompt_number": 5,
        "text": [
         "62856"
        ]
       }
      ],
-     "prompt_number": 4
+     "prompt_number": 5
     },
     {
      "cell_type": "code",
@@ -87,7 +87,7 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 5,
+       "prompt_number": 6,
        "text": [
         "['jotted',\n",
         " 'jotting',\n",
        ]
       }
      ],
-     "prompt_number": 5
+     "prompt_number": 6
     },
     {
      "cell_type": "code",
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 6,
+       "prompt_number": 14,
        "text": [
-        "'bluster'"
+        "'rebounds'"
        ]
       }
      ],
-     "prompt_number": 6
+     "prompt_number": 14
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "guessed_word = list('_' * len(target))\n",
-      "guessed_word"
+      "discovered = list('_' * len(target))\n",
+      "discovered"
      ],
      "language": "python",
      "metadata": {},
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 7,
+       "prompt_number": 8,
        "text": [
-        "['_', '_', '_', '_', '_', '_', '_']"
+        "['_', '_', '_', '_', '_', '_']"
        ]
       }
      ],
-     "prompt_number": 7
+     "prompt_number": 8
     },
     {
      "cell_type": "code",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: dsf\n"
+        "Enter letter: sdfsdfs\n"
        ]
       },
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 8,
+       "prompt_number": 9,
        "text": [
-        "'d'"
+        "'s'"
        ]
       }
      ],
-     "prompt_number": 8
+     "prompt_number": 9
     },
     {
      "cell_type": "code",
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 9
+     "prompt_number": 11
     },
     {
      "cell_type": "code",
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 10,
+       "prompt_number": 12,
        "text": [
         "[]"
        ]
       }
      ],
-     "prompt_number": 10
+     "prompt_number": 12
     },
     {
      "cell_type": "code",
       "guessed_letter = 'e'\n",
       "locations = find_all(target, guessed_letter)\n",
       "for location in locations:\n",
-      "    guessed_word[location] = guessed_letter\n",
-      "guessed_word"
+      "    discovered[location] = guessed_letter\n",
+      "discovered"
      ],
      "language": "python",
      "metadata": {},
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 11,
+       "prompt_number": 15,
        "text": [
-        "['_', '_', '_', '_', '_', 'e', '_']"
+        "['_', 'e', '_', '_', '_', '_']"
        ]
       }
      ],
-     "prompt_number": 11
+     "prompt_number": 15
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "def updated_guessed_word(guessed_word, guessed_letter):\n",
+      "def updated_discovered_word(discovered, guessed_letter):\n",
       "    locations = find_all(target, guessed_letter)\n",
       "    for location in locations:\n",
-      "        guessed_word[location] = guessed_letter\n",
-      "    return guessed_word"
+      "        discovered[location] = guessed_letter\n",
+      "    return discovered"
      ],
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 13
+     "prompt_number": 18
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
       "def initialise():\n",
-      "    global lives, target, guessed_word, wrong_letters\n",
+      "    global lives, target, discovered, wrong_letters\n",
       "    lives = STARTING_LIVES\n",
       "    target = random.choice(WORDS)\n",
-      "    guessed_word = list('_' * len(target))\n",
+      "    discovered = list('_' * len(target))\n",
       "    wrong_letters = []"
      ],
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 30
+     "prompt_number": 19
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
       "def do_turn():\n",
-      "    global guessed_words, lives, wrong_letters\n",
-      "    print('Word:', ' '.join(guessed_word), ' : Lives =', lives, ', wrong guesses:', ' '.join(sorted(wrong_letters)))\n",
+      "    global discovered, lives, wrong_letters\n",
+      "    print('Word:', ' '.join(discovered), ' : Lives =', lives, ', wrong guesses:', ' '.join(sorted(wrong_letters)))\n",
       "    guess = input('Enter letter: ').strip().lower()[0]\n",
       "    if guess in target:\n",
-      "        updated_guessed_word(guessed_word, guess)\n",
+      "        updated_discovered_word(discovered, guess)\n",
       "    else:\n",
       "        lives -= 1\n",
-      "        wrong_letters += [guess]"
+      "        if guess not in wrong_letters:\n",
+      "            wrong_letters += [guess]"
      ],
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 41
+     "prompt_number": 27
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
       "def play_game():\n",
-      "    global guessed_word, lives\n",
+      "    global discovered, lives\n",
       "    initialise()\n",
       "    game_finished = False\n",
       "    do_turn()\n",
       "    while not game_finished:\n",
-      "        if '_' not in guessed_word:\n",
-      "            print('You won!')\n",
+      "        if '_' not in discovered:\n",
+      "            print('You won! The word was', target)\n",
       "            game_finished = True\n",
       "        elif lives <= 0:\n",
       "            print('You lost. The word was', target)\n",
      "language": "python",
      "metadata": {},
      "outputs": [],
-     "prompt_number": 36
+     "prompt_number": 25
     },
     {
      "cell_type": "code",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
+        "Word: _ _ _ _ _ _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: _ _ _ _ _ e _ _ _  : Lives = 10 , wrong guesses: \n"
+        "Word: _ e _ _ _ _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ _ _ e _ _ _  : Lives = 10 , wrong guesses: \n"
+        "Word: _ e _ _ a _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: t\n"
+        "Enter letter: i\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ _ _ e t _ _  : Lives = 10 , wrong guesses: \n"
+        "Word: _ e _ _ a _ _ _ _ _ i _ i _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ o _ e t _ _  : Lives = 10 , wrong guesses: \n"
+        "Word: _ e _ _ a _ _ _ o _ i _ i _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: i\n"
+        "Enter letter: t\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ o _ e t _ _  : Lives = 9 , wrong guesses: i\n"
+        "Word: _ e _ _ a _ _ _ o _ i t i _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: n\n"
+        "Enter letter: r\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ o _ e t _ _  : Lives = 8 , wrong guesses: i n\n"
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: s\n"
+        "Enter letter: n\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ o _ e t _ _  : Lives = 7 , wrong guesses: i n s\n"
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 9 , wrong guesses: n\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: h\n"
+        "Enter letter: s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a _ _ o _ e t _ _  : Lives = 6 , wrong guesses: h i n s\n"
+        "Word: _ e r _ a _ _ r o _ i t i _  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: r\n"
+        "Enter letter: h\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t _ _  : Lives = 6 , wrong guesses: h i n s\n"
+        "Word: h e r _ a _ h r o _ i t i _  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: g\n"
+        "Enter letter: c\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t _ _  : Lives = 5 , wrong guesses: g h i n s\n"
+        "Word: h e r _ a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: r\n"
+        "Enter letter: c\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t _ _  : Lives = 5 , wrong guesses: g h i n s\n"
+        "Word: h e r _ a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: d\n"
+        "Enter letter: m\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t _ _  : Lives = 4 , wrong guesses: d g h i n s\n"
+        "Word: h e r m a _ h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: l\n"
+        "Enter letter: p\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t _ _  : Lives = 3 , wrong guesses: d g h i l n s\n"
+        "Word: h e r m a p h r o _ i t i c  : Lives = 8 , wrong guesses: n s\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: u\n"
+        "Enter letter: d\n"
        ]
       },
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r _ o r e t u _  : Lives = 3 , wrong guesses: d g h i l n s\n"
+        "You won! The word was hermaphroditic\n"
        ]
-      },
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "class Game:\n",
+      "    def __init__(self, target, lives=STARTING_LIVES):\n",
+      "        self.lives = lives\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",
+      "        locations = []\n",
+      "        starting=0\n",
+      "        location = self.target.find(letter)\n",
+      "        while location > -1:\n",
+      "            locations += [location]\n",
+      "            starting = location + 1\n",
+      "            location = self.target.find(letter, starting)\n",
+      "        return locations\n",
+      "    \n",
+      "    def updated_discovered_word(self, guessed_letter):\n",
+      "        locations = find_all(self, guessed_letter)\n",
+      "        for location in locations:\n",
+      "            self.discovered[location] = guessed_letter\n",
+      "        return self.discovered\n",
+      "    \n",
+      "    def do_turn(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",
+      "        if guess in self.target:\n",
+      "            updated_discovered_word(self, 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 play_game(self):\n",
+      "        do_turn()\n",
+      "        while not self.game_finished:\n",
+      "            if self.game_won:\n",
+      "                print('You won! The word was', self.target)\n",
+      "            elif self.game_lost:\n",
+      "                print('You lost. The word was', self.target)\n",
+      "            else:\n",
+      "                do_turn()\n",
+      "        return self.game_won"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 47
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g = Game(random.choice(WORDS))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 48
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.target"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 49,
+       "text": [
+        "'paintbrush'"
+       ]
+      }
+     ],
+     "prompt_number": 49
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.discovered"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 50,
+       "text": [
+        "['_', '_', '_', '_', '_', '_', '_', '_', '_', '_']"
+       ]
+      }
+     ],
+     "prompt_number": 50
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.do_turn()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
       {
-       "name": "stdout",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: b\n"
+        "Word: _ _ _ _ _ _ _ _ _ _  : Lives = 10 , wrong guesses: \n"
        ]
       },
       {
+       "name": "stdout",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Word: a r b o r e t u _  : Lives = 3 , wrong guesses: d g h i l n s\n"
+        "Enter letter: x\n"
        ]
-      },
+      }
+     ],
+     "prompt_number": 51
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.lives"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 52,
+       "text": [
+        "9"
+       ]
+      }
+     ],
+     "prompt_number": 52
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.wrong_letters"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 53,
+       "text": [
+        "['x']"
+       ]
+      }
+     ],
+     "prompt_number": 53
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "g.do_turn()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
       {
-       "name": "stdout",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "Enter letter: m\n"
+        "Word: _ _ _ _ _ _ _ _ _ _  : Lives = 9 , wrong guesses: x\n"
        ]
       },
       {
+       "name": "stdout",
        "output_type": "stream",
        "stream": "stdout",
        "text": [
-        "You won!\n"
+        "Enter letter: t\n"
+       ]
+      },
+      {
+       "ename": "TypeError",
+       "evalue": "'Game' object does not support item assignment",
+       "output_type": "pyerr",
+       "traceback": [
+        "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
+        "\u001b[1;32m<ipython-input-54-1beb96467341>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdo_turn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+        "\u001b[1;32m<ipython-input-47-8f8ddb756c32>\u001b[0m in \u001b[0;36mdo_turn\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m     31\u001b[0m         \u001b[0mguess\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Enter letter: '\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlower\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     32\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mguess\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtarget\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 33\u001b[1;33m             \u001b[0mupdated_discovered_word\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mguess\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     34\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     35\u001b[0m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlives\u001b[0m \u001b[1;33m-=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+        "\u001b[1;32m<ipython-input-18-572b4e76dcf5>\u001b[0m in \u001b[0;36mupdated_discovered_word\u001b[1;34m(discovered, guessed_letter)\u001b[0m\n\u001b[0;32m      2\u001b[0m     \u001b[0mlocations\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfind_all\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtarget\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mguessed_letter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mlocation\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mlocations\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m         \u001b[0mdiscovered\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mlocation\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mguessed_letter\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mdiscovered\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+        "\u001b[1;31mTypeError\u001b[0m: 'Game' object does not support item assignment"
        ]
       }
      ],
-     "prompt_number": 42
+     "prompt_number": 54
     },
     {
      "cell_type": "code",