{
- "metadata": {
- "name": "",
- "signature": "sha256:374900202f4f7c3f157762c0d012b597cc502efce4de220013e3cc9cd8dfc896"
- },
- "nbformat": 3,
- "nbformat_minor": 0,
- "worksheets": [
+ "cells": [
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Hangman 1: set a puzzle\n",
- "\n",
- "A fairly traditional hangman game. The computer chooses a word, the (human) player has to guess it without making too many wrong guesses. You'll need to find a list of words to chose from and develop a simple UI for the game (e.g. text only: display the target word with underscores and letters, lives left, and maybe incorrect guesses). \n",
- "\n",
- "## Data structures\n",
- "\n",
- "* What do we need to track?\n",
- "* What operations do we need to perform on it?\n",
- "* How to store it?\n",
- "\n",
- "## Creating a game\n",
- "* 'List' of words to choose from\n",
- " * Pick one at random\n",
- "\n",
- "## Game state\n",
- "\n",
- "<table>\n",
- "<tr valign=\"top\">\n",
- "<th>Data</th>\n",
- "<th> </th>\n",
- "<th>Operations</th>\n",
- "</tr>\n",
- "<tr valign=\"top\">\n",
- "<td>\n",
- "\n",
- "* Target word\n",
- "* Discovered letters\n",
- " * In order in the word\n",
- "* Lives left\n",
- "* Wrong letters?\n",
- "\n",
- "</td>\n",
- "<td></td>\n",
- "<td>\n",
- "\n",
- "* Get a guess\n",
- "* Update discovered letters\n",
- "* Update lives\n",
- "* Show discovered word\n",
- "* Detect game end, report\n",
- "* Detect game win or loss, report\n",
- "\n",
- "</td>\n",
- "</tr>\n",
- "</table>"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "import re\n",
- "import random"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 3
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Get the words\n",
- "Read the words the game setter can choose from. The list contains all sorts of hangman-illegal words, such as proper nouns and abbreviations. We'll remove them by taking the pragmatic approach that if a word contains a non-lowercase letter (capital letters, full stops, apostrophes, etc.), it's illegal. "
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# Just use a regex to filter the words. There are other ways to do this, as you know.\n",
- "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": 4
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "A few quick looks at the list of words, to make sure it's sensible."
- ]
- },
- {
- "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": "markdown",
- "metadata": {},
- "source": [
- "## Constants and game states"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## The target word"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "target = random.choice(WORDS)\n",
- "target"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 7,
- "text": [
- "'rocketing'"
- ]
- }
- ],
- "prompt_number": 7
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "STARTING_LIVES = 10\n",
- "lives = 0"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 8
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "wrong_letters = []"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 9
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We'll represent the partially-discovered word as a list of characters. Each character is either the letter in the target (if it's been discovered) or an underscore if it's not.\n",
- "\n",
- "Use a `list` as it's a mutable data structure. That means we can change individual elements of a list, which we couldn't if we represented it as a `string`.\n",
- "\n",
- "We can also use `discovered` to check of a game win. If `discovered` contains an underscore, the player hasn't won the game."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "discovered = list('_' * len(target))\n",
- "discovered"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 10,
- "text": [
- "['_', '_', '_', '_', '_', '_', '_', '_', '_']"
- ]
- }
- ],
- "prompt_number": 10
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We can use `' '.join(discovered)` to display it nicely."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "' '.join(discovered)"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 11,
- "text": [
- "'_ _ _ _ _ _ _ _ _'"
- ]
- }
- ],
- "prompt_number": 11
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Read a letter\n",
- "Get rid of fluff and make sure we only get one letter."
- ]
- },
- {
- "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: r\n"
- ]
- },
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 9,
- "text": [
- "'r'"
- ]
- }
- ],
- "prompt_number": 9
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Finding a letter in a word\n",
- "One operation we want to to is to update `discovered` when we get a `letter`. The trick is that we want to update every occurrence of the `letter` in `discovered`. \n",
- "\n",
- "We'll do it in two phases. In the first phase, we'll find all the occurences of the `letter` in the `target` and return a list of those locations. In the second phase, we'll update all those positions in `discovered` with the `letter`. \n",
- "\n",
- "There's probaby a clever way of doing this in one pass, but it's complicated (or at least not obvious), so let's just do it the easy way."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# Note that find returns either the first occurrence of a substring, or -1 if it doesn't exist.\n",
- "def find_all_explicit(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": 25
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# A simpler way using a list comprehension and the built-in enumerate()\n",
- "def find_all(string, letter):\n",
- " return [p for p, l in enumerate(string) if l == letter]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 12
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "find_all('happy', 'p')"
- ],
- "language": "python",
- "metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 13,
- "text": [
- "[2, 3]"
- ]
- }
- ],
- "prompt_number": 13
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Updating the discovered word\n",
- "Now we can update `discovered`. We'll look through the `locations` list and update that element of `discovered`."
- ]
- },
- {
- "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": "markdown",
- "metadata": {},
- "source": [
- "## Putting it all together\n",
- "We've not got quite a few bits and pieces of how the game should work. Now it's time to start putting them together into the game.\n",
- "\n",
- "```\n",
- "to play a game:\n",
- " initialise lives, target, etc.\n",
- " finished? = False\n",
- " handle a turn\n",
- " while not finished?:\n",
- " if guessed all letters:\n",
- " report success\n",
- " finished? = True\n",
- " elif run out of lives:\n",
- " report failure\n",
- " finished? = True\n",
- " else:\n",
- " handle a turn\n",
- "```\n",
- "\n",
- "```\n",
- "to handle a turn:\n",
- " print the challenge\n",
- " get the letter\n",
- " if letter in target:\n",
- " update discovered\n",
- " else:\n",
- " update lives, wrong_letters\n",
- "```\n",
- "\n",
- "```\n",
- "to update discovered:\n",
- " find all the locations of letter in target\n",
- " replace the appropriate underscores in discovered\n",
- "```\n",
- "\n",
- "We pretty much know how to do all these bits, so let's just start at the bottom and off we go!\n",
- "\n",
- "###Syntax note\n",
- "Note the use of Python's `global` statement, to tell Python that we're updating the global variables in each procedure. We'll fix that later."
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Hangman 1: set a puzzle\n",
+ "\n",
+ "A fairly traditional hangman game. The computer chooses a word, the (human) player has to guess it without making too many wrong guesses. You'll need to find a list of words to chose from and develop a simple UI for the game (e.g. text only: display the target word with underscores and letters, lives left, and maybe incorrect guesses). \n",
+ "\n",
+ "## Data structures\n",
+ "\n",
+ "* What do we need to track?\n",
+ "* What operations do we need to perform on it?\n",
+ "* How to store it?\n",
+ "\n",
+ "## Creating a game\n",
+ "* 'List' of words to choose from\n",
+ " * Pick one at random\n",
+ "\n",
+ "## Game state\n",
+ "\n",
+ "### Data\n",
+ "* Target word\n",
+ "* Discovered letters\n",
+ " * In order in the word\n",
+ "* Lives left\n",
+ "* Wrong letters?\n",
+ "\n",
+ "### Operations\n",
+ "* Get a guess\n",
+ "* Update discovered letters\n",
+ "* Update lives\n",
+ "* Show discovered word\n",
+ "* Detect game end, report\n",
+ "* Detect game win or loss, report\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "import re\n",
+ "import random"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Get the words\n",
+ "Read the words the game setter can choose from. The list contains all sorts of hangman-illegal words, such as proper nouns and abbreviations. We'll remove them by taking the pragmatic approach that if a word contains a non-lowercase letter (capital letters, full stops, apostrophes, etc.), it's illegal. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Just use a regex to filter the words. There are other ways to do this, as you know.\n",
+ "WORDS = [w.strip() for w in open('/usr/share/dict/british-english').readlines() \n",
+ " if re.match(r'^[a-z]*$', w.strip())]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "A few quick looks at the list of words, to make sure it's sensible."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "62856"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(WORDS)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['jotted',\n",
+ " 'jotting',\n",
+ " 'jottings',\n",
+ " 'joule',\n",
+ " 'joules',\n",
+ " 'jounce',\n",
+ " 'jounced',\n",
+ " 'jounces',\n",
+ " 'jouncing',\n",
+ " 'journal']"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "WORDS[30000:30010]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Constants and game states"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## The target word"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'rocketing'"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "target = random.choice(WORDS)\n",
+ "target"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "STARTING_LIVES = 10\n",
+ "lives = 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "wrong_letters = []"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We'll represent the partially-discovered word as a list of characters. Each character is either the letter in the target (if it's been discovered) or an underscore if it's not.\n",
+ "\n",
+ "Use a `list` as it's a mutable data structure. That means we can change individual elements of a list, which we couldn't if we represented it as a `string`.\n",
+ "\n",
+ "We can also use `discovered` to check for a game win. If `discovered` contains an underscore, the player hasn't won the game."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['_', '_', '_', '_', '_', '_', '_', '_', '_']"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "discovered = list('_' * len(target))\n",
+ "discovered"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can use `' '.join(discovered)` to display it nicely."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'_ _ _ _ _ _ _ _ _'"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "' '.join(discovered)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Read a letter\n",
+ "Get rid of fluff and make sure we only get one letter."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Enter letter: r\n"
]
},
{
- "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": 16
- },
- {
- "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",
+ "data": {
+ "text/plain": [
+ "'r'"
+ ]
+ },
+ "execution_count": 9,
"metadata": {},
- "outputs": [],
- "prompt_number": 17
- },
- {
- "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": 18
- },
- {
- "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": 19
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Playing the game\n",
- "That seemed straightforward. Let's see if it works!"
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "letter = input('Enter letter: ').strip().lower()[0]\n",
+ "letter"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Finding a letter in a word\n",
+ "One operation we want to to is to update `discovered` when we get a `letter`. The trick is that we want to update every occurrence of the `letter` in `discovered`. \n",
+ "\n",
+ "We'll do it in two phases. In the first phase, we'll find all the occurences of the `letter` in the `target` and return a list of those locations. In the second phase, we'll update all those positions in `discovered` with the `letter`. \n",
+ "\n",
+ "There's probaby a clever way of doing this in one pass, but it's complicated (or at least not obvious), so let's just do it the easy way."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Note that find returns either the first occurrence of a substring, or -1 if it doesn't exist.\n",
+ "def find_all_explicit(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"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# A simpler way using a list comprehension and the built-in enumerate()\n",
+ "def find_all(string, letter):\n",
+ " return [p for p, l in enumerate(string) if l == letter]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2, 3]"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "find_all('happy', 'p')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Updating the discovered word\n",
+ "Now we can update `discovered`. We'll look through the `locations` list and update that element of `discovered`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['_', '_', '_', '_', 'e', '_', '_', '_', '_']"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "guessed_letter = 'e'\n",
+ "locations = find_all(target, guessed_letter)\n",
+ "for location in locations:\n",
+ " discovered[location] = guessed_letter\n",
+ "discovered"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Putting it all together\n",
+ "We've not got quite a few bits and pieces of how the game should work. Now it's time to start putting them together into the game.\n",
+ "\n",
+ "```\n",
+ "to play a game:\n",
+ " initialise lives, target, etc.\n",
+ " finished? = False\n",
+ " handle a turn\n",
+ " while not finished?:\n",
+ " if guessed all letters:\n",
+ " report success\n",
+ " finished? = True\n",
+ " elif run out of lives:\n",
+ " report failure\n",
+ " finished? = True\n",
+ " else:\n",
+ " handle a turn\n",
+ "```\n",
+ "\n",
+ "```\n",
+ "to handle a turn:\n",
+ " print the challenge\n",
+ " get the letter\n",
+ " if letter in target:\n",
+ " update discovered\n",
+ " else:\n",
+ " update lives, wrong_letters\n",
+ "```\n",
+ "\n",
+ "```\n",
+ "to update discovered:\n",
+ " find all the locations of letter in target\n",
+ " replace the appropriate underscores in discovered\n",
+ "```\n",
+ "\n",
+ "We pretty much know how to do all these bits, so let's just start at the bottom and off we go!\n",
+ "\n",
+ "###Syntax note\n",
+ "Note the use of Python's `global` statement, to tell Python that we're updating the global variables in each procedure. We'll fix that later."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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 = []"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Playing the game\n",
+ "That seemed straightforward. Let's see if it works!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Word: _ _ _ _ _ _ _ : Lives = 10 , wrong guesses: \n",
+ "Enter letter: e\n",
+ "Word: _ _ _ _ _ _ e : Lives = 10 , wrong guesses: \n",
+ "Enter letter: a\n",
+ "Word: _ _ _ _ _ _ e : Lives = 9 , wrong guesses: a\n",
+ "Enter letter: i\n",
+ "Word: _ _ _ _ i _ e : Lives = 9 , wrong guesses: a\n",
+ "Enter letter: o\n",
+ "Word: _ o _ _ i _ e : Lives = 9 , wrong guesses: a\n",
+ "Enter letter: n\n",
+ "Word: _ o n _ i _ e : Lives = 9 , wrong guesses: a\n",
+ "Enter letter: v\n",
+ "Word: _ o n _ i _ e : Lives = 8 , wrong guesses: a v\n",
+ "Enter letter: t\n",
+ "Word: _ o n _ i _ e : Lives = 7 , wrong guesses: a t v\n",
+ "Enter letter: s\n",
+ "Word: _ o n _ i _ e : Lives = 6 , wrong guesses: a s t v\n",
+ "Enter letter: h\n",
+ "Word: _ o n _ i _ e : Lives = 5 , wrong guesses: a h s t v\n",
+ "Enter letter: f\n",
+ "Word: _ o n f i _ e : Lives = 5 , wrong guesses: a h s t v\n",
+ "Enter letter: b\n",
+ "Word: b o n f i _ e : Lives = 5 , wrong guesses: a h s t v\n",
+ "Enter letter: r\n",
+ "You won! The word was bonfire\n"
]
- },
- {
- "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 : 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: _ _ _ _ i _ e : Lives = 9 , wrong guesses: a\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: o\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o _ _ i _ e : 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: _ o n _ i _ e : Lives = 9 , wrong guesses: a\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: v\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o n _ i _ e : Lives = 8 , wrong guesses: a v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: t\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o n _ i _ e : Lives = 7 , wrong guesses: a t v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: s\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o n _ i _ e : Lives = 6 , wrong guesses: a s t v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: h\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o n _ i _ e : Lives = 5 , wrong guesses: a h s t v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: f\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: _ o n f i _ e : Lives = 5 , wrong guesses: a h s t v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: b\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Word: b o n f i _ e : Lives = 5 , wrong guesses: a h s t v\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Enter letter: r\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "You won! The word was bonfire\n"
- ]
- }
- ],
- "prompt_number": 22
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [],
- "language": "python",
- "metadata": {},
- "outputs": [],
- "prompt_number": 17
}
],
- "metadata": {}
+ "source": [
+ "play_game()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "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+"
}
- ]
-}
\ No newline at end of file
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}