<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>The “Invent with Python” Blog</title>
	<atom:link href="http://inventwithpython.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://inventwithpython.com/blog</link>
	<description>News about Al Sweigart’s programming books.</description>
	<lastBuildDate>Wed, 16 May 2012 20:59:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>A Modest Proposal: Please Don&#8217;t Learn to Code Because It Will Damage Your Tiny Brain</title>
		<link>http://inventwithpython.com/blog/2012/05/16/a-modest-proposal-please-dont-learn-to-code-because-it-will-damage-your-tiny-brain/</link>
		<comments>http://inventwithpython.com/blog/2012/05/16/a-modest-proposal-please-dont-learn-to-code-because-it-will-damage-your-tiny-brain/#comments</comments>
		<pubDate>Wed, 16 May 2012 16:48:41 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=730</guid>
		<description><![CDATA[Jeff Atwood wrote a post on his Coding Horror blog entitled &#8220;Please Don&#8217;t Learn to Code&#8221; in which he rails against the idea that &#8220;everyone should learn programming&#8221;. And I couldn&#8217;t agree more. People, not everyone needs to learn programming. Only some gifted individuals (of which we professional software developers are included) need to learn [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff Atwood wrote a post on his <a href="http://www.codinghorror.com/blog/">Coding Horror</a> blog entitled <a href="http://www.codinghorror.com/blog/2012/05/please-dont-learn-to-code.html">&#8220;Please Don&#8217;t Learn to Code&#8221;</a> in which he rails against the idea that &#8220;everyone should learn programming&#8221;.</p>
<p><strong>And I couldn&#8217;t agree more.</strong></p>
<p>People, not everyone needs to learn programming. Only some gifted individuals (of which we professional software developers are included) need to learn programming. For the rest of you, unless you are srsly committed it will just be a meaningless chore that may damage your tiny brains.</p>
<p>Coding is just like surgery: if an amateur decides to code their own Angry Birds clone as a fun little project, <strong>people will literally die.</strong> Those are the stakes, folks. That&#8217;s why it should be left to those who are explicitly pursing it as a professional career.</p>
<p><a href="#toolongdidntread">TL; DR link</a></p>
<p><img src="/images/bloomberg_learn_to_code.png" /></p>
<p>You have my assurance that I find Bloomberg&#8217;s encouragement of people to learn a technical skill personally offensive. It filled me with a rage that was only subdued after discouraging a small child from learning to play the harmonica. (What&#8217;s the kid going to do with that skill anyway? There are better ways he could spend his valuable time.)</p>
<p><span id="more-730"></span></p>
<p>Meanwhile, Jeff doesn&#8217;t hold back when he deals his death blow:</p>
<blockquote><p>&#8220;Can you explain to me how Michael Bloomberg would be better at his day to day job of leading the largest city in the USA if he woke up one morning as a crack Java coder?&#8221;</p></blockquote>
<p>Gauntlet&#8230; THROWN. The especially insidious thing (which Jeff shows that he himself is well aware of) is that even if Bloomberg&#8217;s serpentine journey into forbidden coding knowledge ended up being useless (which, yeah, maybe the mayor doesn&#8217;t need to know programming), his tweet has terrible implications for those he is in communion with. The man has 252,000 followers on Twitter. <strong style="font-size: 1.1em">It&#8217;s as though the point of his tweet wasn&#8217;t just a casual announcement of his own 2012 resolutions, but also an encouragement for citizens to educate themselves on a technical subject.</strong></p>
<p><strong style="font-size: 200%">PURE EVIL.</strong></p>
<p>Think of the anarchy that would result if a fraction of them took it upon themselves to learn a new skill that is ordinarily considered not-for-average-people. They might find out that programming wasn&#8217;t as unapproachable as they previously thought!</p>
<p><center><img src="/images/pleasedont_anarchy.png" /></center></p>
<p>Those who tout the &#8220;everyone can learn to code&#8221; and &#8220;coding is increasingly becoming essential&#8221; line are unaware of how preposterous their claims are. To give an example, Jeff replaces &#8220;programming&#8221; with &#8220;plumbing&#8221; in a quote from Tim O&#8217;Reilly:</p>
<p><center><img src="/images/the_need_for_plumbers.png" /></center></p>
<p>Exactly! Plumbing and programming in this context <strong style="font-size:1.2em">are completely comparable</strong> which is why this twisted quote proves Jeff&#8217;s point. The demand for programmers isn&#8217;t high at all, and we can only expect it to decline as the 21st century progresses. And even if that wasn&#8217;t true, you don&#8217;t begin the journey to learn programming from a website like <a href="http://www.codecademy.com/">Codecademy</a>. When has anyone ever used the Internet to learn something?</p>
<p>Jeff&#8217;s bullet-pointed reasons that follow his courageous, speak-truth-to-power words are at once a soothing symphony to the nerves of our exclusive software guild and a salvo against those who dare think they could learn to fish for themselves. I iterate them here with my own praising commentary:</p>
<blockquote><p>&#8220;It assumes that more code in the world is an inherently desirable thing. [...] You should be learning to write as little code as possible. Ideally none.&#8221;</p></blockquote>
<p>What a lot of people don&#8217;t understand is that <strong style="font-size:1.1em">programmers never write throwaway code</strong>. I once had the problem of wanting to download a few hundred images off of a website that had URLs like http://example.com/1.jpg, http://example.com/2.jpg, http://example.com/3.jpg, etc. up to http://example.com/347.jpg. (A local copy of an online comic, something that plenty of non-coders would want to do.)</p>
<p>At first I thought, &#8220;No problem. I always forget the exact function names of the networking library, but wget (a command line tool for downloading files off the web) is easy enough to use. I&#8217;ll just write a small script that writes a simple batch file that calls wget  on each of these images. Something like:&#8221;</p>
<p><code>fp = open('temp.bat', 'w')<br />
for i in range(1, 348):<br />
&nbsp;&nbsp;&nbsp;&nbsp;fp.write('wget http://example.com/%s.jpg\n' % (i))</code></p>
<p>Then I&#8217;d run the temp.bat file and I wouldn&#8217;t have to type out all those wget commands myself. A couple minutes later and I have all 347 images on my hard drive.</p>
<p><strong style="1.1em">WHOA SLOW DOWN, AL.</strong> Are you sure you want to commit to writing this code? Writing a script that itself writes a script to be executed? That doesn&#8217;t sound very elegant. Isn&#8217;t that overengineering a solution to this problem? And what about supporting this code? Will it scale to millions of users? Have you thought about localization? <strong>What if I need to translate this script to Bulgarian?</strong> Do you really want to introduce this low-quality throwaway code into the world? Is that an inherently desirable thing?</p>
<p>Just imagine if your average layperson had the knowledge to automate simple, repetitive tasks with a quick hack like this. Then they wouldn&#8217;t have to struggle through all that manual typing and mouse clicking like a good techno-plebian. Or &#8220;ideally&#8221;, they could just give up on the problem and think there&#8217;s no practical solution (no code at all!).</p>
<blockquote><p>&#8220;It assumes that coding is the goal. [...] Before you go rushing out to learn to code, figure out what your problem actually is.&#8221;</p></blockquote>
<p>The core problem of this learn-coding-for-the-sake-of-coding fad is that you should have all the details of how you are going apply that skill laid out before you even write your first &#8220;Hello world&#8221; program. Having knowledge of new methods never broadens our perspectives or opens insights to novel solutions. </p>
<p>In my toolbox, there&#8217;s only a hammer and a saw because that&#8217;s all I need to build birdhouses. Sure, I might get ideas for new things to build if I had other tools. But I don&#8217;t know what those things are right now, so why do I need anything beyond what I already have? And hopefully if I stick to what I know, I&#8217;ll never find out.</p>
<blockquote><p>&#8220;Software developers tend to be software addicts who think their job is to write code. But it&#8217;s not. Their job is to solve problems. Don&#8217;t celebrate the creation of code, celebrate the creation of solutions.&#8221;</p></blockquote>
<p>Totally on the ball. It&#8217;s just like when one of my friends wanted to start an afterschool music program. &#8220;Hey now, the world doesn&#8217;t need another afterschool program. It needs an effective solution to lower drop-out rates, increase test scores, and prevent gang violence.&#8221; Thankfully, I was able to convince him to can the idea.</p>
<blockquote><p>&#8220;It assumes that adding naive, novice, not-even-sure-they-like-this-whole-programming-thing coders to the workforce is a net positive for the world.&#8221;</p></blockquote>
<p>I&#8217;ve seen some terrible code in my time, and the thought of these novice programmers being hired and putting their code on the market send shivers down my spine. <strong style="1.1em">Maybe if there was some way that companies could judge which candidates were qualified or not before hiring them</strong> (like a piece of paper listing their previous experience and education, or some sort of one-on-one conversation about their domain knowledge) it would be okay for people with less-than-absolute-mastery skill in coding to exist. Sadly, I can think of nothing that would prevent crap programmers from instantly being put in charge of the software for nuclear power plants.</p>
<p>You don&#8217;t create an effective workforce of software developers by encouraging many people to try their hand at coding and see who sticks with it. Rather, you need to scare off anyone who isn&#8217;t &#8220;serious&#8221; about coding. That&#8217;s the attitude that has led to the arrogant, petty, sarcastic, satire-writing generation of computer programmers I proudly say we have today.</p>
<blockquote><p>&#8220;It implies that there&#8217;s a thin, easily permeable membrane between learning to program and getting paid to program professionally.&#8221;</p></blockquote>
<p>The cruelest joke is played on the ones who take on the task of learning to program. Jeff specifically cites the book &#8220;Teach Yourself Perl in 24 Hours&#8221; as contributing to this misleading atmosphere. <strong>How could anyone not realize that this claim was a gimmick based on the fact that the book had 24 chapters?</strong> When I was first starting to learn Perl, I <em>literally</em> thought this $35 book and a single day would be all I needed to become an employed Perl developer who knew every facet of the language. Surely I can&#8217;t be the only one who thought this. I hadn&#8217;t been so disappointed since the day I saw &#8220;The NeverEnding Story&#8221; and ended up leaving the movie theater a mere two hours later.</p>
<p><a name="toolongdidntread"><center><img src="/images/pleasedont_teachyourselfperl.png" /></center></a></p>
<h2>In Conclusion</h2>
<p>Why would the average person need to learn programming? When would they ever use that knowledge if they weren&#8217;t going to become a software engineer? Just like mathematics, a musical instrument, a foreign language, all sports ever invented, cooking, dancing, knitting, sailing, and everything beyond a 3rd grade education, you can get by in life just fine without it. I mean, when have you ever heard of someone enjoying programming just as a hobby and creative pursuit? When has anyone said that programming is great way to improve general analytical skills?</p>
<p>Remember, Jeff isn&#8217;t <strong style="1.1em">just</strong> saying that most professions and lifestyles wouldn&#8217;t be significantly enhanced by programming ability. He isn&#8217;t just saying that &#8220;coding is the new literacy that you have to have&#8221; is hyperbole. (Both are arguable points.) If he was, he would have titled his post, <strong>&#8220;You Don&#8217;t Actually Need to Learn to Code&#8221;</strong>. Rather, he wants to keep the unwashed masses from embarrassing themselves with their amateur code which he and the other elite coders will end up having to debug. That&#8217;s why the title is <strong>&#8220;Please Don&#8217;t Learn to Code&#8221;</strong>.</p>
<p>It&#8217;s his plea for you to not even try.</p>
<p>Folks, programming is a privilege and a responsibility and not everyone should attempt to have it. In that way, it&#8217;s just like writing. If an army of amateurs took up keyboards to articulate their thoughts, just imagine what kind of dopey, smug opinions would be posted to the Internet.</p>
<p>Signed,<br />
A Concerned Rock Star Programmer</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F05%2F16%2Fa-modest-proposal-please-dont-learn-to-code-because-it-will-damage-your-tiny-brain%2F&amp;title=A%20Modest%20Proposal%3A%20Please%20Don%E2%80%99t%20Learn%20to%20Code%20Because%20It%20Will%20Damage%20Your%20Tiny%20Brain" id="wpa2a_2"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/05/16/a-modest-proposal-please-dont-learn-to-code-because-it-will-damage-your-tiny-brain/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Implement a &#8220;Save Game&#8221; Feature in Python with the shelve Module</title>
		<link>http://inventwithpython.com/blog/2012/05/03/implement-a-save-game-feature-in-python-with-the-shelve-module/</link>
		<comments>http://inventwithpython.com/blog/2012/05/03/implement-a-save-game-feature-in-python-with-the-shelve-module/#comments</comments>
		<pubDate>Thu, 03 May 2012 17:46:44 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=695</guid>
		<description><![CDATA[This post goes into the details of how you can add a &#8220;save game&#8221; feature to your games. Python&#8217;s built-in shelve module makes this very easy to do, but there are some pitfalls and tips that you might want to learn from this post before trying to code it up yourself. To give an example [...]]]></description>
			<content:encoded><![CDATA[<p>This post goes into the details of how you can add a &#8220;save game&#8221; feature to your games. <a href="http://docs.python.org/py3k/library/shelve.html">Python&#8217;s built-in shelve module</a> makes this very easy to do, but there are some pitfalls and tips that you might want to learn from this post before trying to code it up yourself.</p>
<p>To give an example of adding a &#8220;save game&#8221; feature to a game program, I&#8217;ll be taking the Flippy program (an Othello clone) from <a href="http://inventwithpython.com/pygame/chapter10.html">Chapter 10 of &#8220;Making Games with Python &#038; Pygame&#8221;</a> (and Reversi from <a href="http://inventwithpython.com/chapter15.html">Chapter 15 of &#8220;Invent Your Own Computer Games with Python&#8221;</a>.)</p>
<p>If you want to skip ahead and see the Flippy version with the &#8220;save game&#8221; feature added, you can <a href="http://inventwithpython.com/savefeature_shelve.zip">download the source code and image files</a> used by the game. You need <a href="http://pygame.org/download.shtml">Pygame</a> installed to run Flippy (but not Reversi).<br />
<span id="more-695"></span></p>
<h2>The Naïve Ways to Implement &#8220;Save Game&#8221;</h2>
<p>A save game feature works by taking all of the values in the program&#8217;s variables (which in total called the game state) and writes them out to a file on the hard drive. The game program can be shut down, and when next started again the values can be read from the file and into the program&#8217;s variables.</p>
<p><img src="/images/saved_game_diagram.png" /></p>
<p>If you are familiar with Python&#8217;s file I/O and the open(), write(), readline(), and close() functions, you might think that you can just open a file in write-mode, and then write out all the data to the hard drive that you want to load the next time the player plays the game. This is doable, but turns out to be a bad way to implement a &#8220;save game&#8221; feature.</p>
<div class="hide-this-part-wrap"><div class="hide-this-part-more" id="hide-this-part-0" morelink-text="Read the detailed explanation.">Read the detailed explanation. »</div><div class="hide-this-part" status="invisible"></p>
<p>What exactly is the format of the text you&#8217;ll write out? You could write out text like this (if you were making an RPG):</p>
<pre>name=Hero
gold=42
hp=55/60
...</pre>
<p>This has several problems. When you read the content in from the file to load a saved game, you&#8217;ll have to write a lot of code that is specific for your particular game:</p>
<pre>fp = open('savedGame.txt')
name = fp.readline().split('=')[1]
gold = int(fp.readline().split('=')[1])
currentHp, maxHp = fp.readline().split('=')[1].split('/')
currentHp = int(currentHp)
maxHp = int(maxHp)
...</pre>
<p>Yeesh. That&#8217;s going to be a lot of code we need to write, test, and debug as the game gets more complicated. Using the open(), read() and write() functions is good for basic file I/O, but not when it comes to a &#8220;save game&#8221; feature.</p>
<p>If you are familiar with JSON or XML, Python comes with built-in json and xml modules that can format your data to the JSON format or XML format. Then you can write this formatted text to a file. This is better, but still not as convenient as the shelve module.<br />
</div><!-- .hide-this-part --></div><!-- hide-this-part-wrap -->
<h2>Quick Start: The shelve Built-In Module</h2>
<p>The shelve module has a function called shelve.open() that returns a &#8220;shelf file object&#8221; that can be used to create, read, and write data to shelf files on the hard drive. These shelf files can store any Python value (even complicated values like lists of lists or objects of classes you make).</p>
<p>Say you had a variable with a list of list of strings, like the mainBoard variable in the Flippy program. Here&#8217;s how you can save the state of all 64 spaces on the board (which are 64 string values) and the other variables (playerTile, computerTile, showHints, and turn):</p>
<pre>import shelve
shelfFile = shelve.open('saved_game_filename')
shelfFile ['mainBoardVariable'] = mainBoard
shelfFile ['playerTileVariable'] = playerTile
shelfFile ['computerTileVariable'] = computerTile
shelfFile ['showHintsVariable'] = showHints
shelfFile.close()</pre>
<p>The shelve.open() function returns a &#8220;shelf file object&#8221; that you can store values in using the same syntax as a Python dictionary.</p>
<p>You don&#8217;t have to put the word &#8220;Variable&#8221; at the end of the key. I just did that to point out that the name doesn&#8217;t have to be the same as the variable with the value being stored. In fact, just like any dictionary key, it doesn&#8217;t even need to be a string.</p>
<p>The data stored in the shelf object is written out to the hard drive when shelfFile.close() is called.</p>
<p>Note that the shelf file name is &#8216;saved_game_filename&#8217;, which doesn&#8217;t have an extension. An extension isn&#8217;t needed, but you can add one if you want. This will be explained more in detail.</p>
<p>Here&#8217;s the code to load the game state from a shelf file:</p>
<pre>import shelve
shelfFile = shelve.open('saved_game_filename')
mainBoard = shelfFile ['mainBoardVariable']
playerTile = shelfFile ['playerTileVariable']
computerTile = shelfFile ['computerTileVariable']
showHints = shelfFile ['showHintsVariable']
shelfFile.close()</pre>
<p>That&#8217;s it for the basics. Think of a shelf object as a single dictionary that you store all of your game state variables in when you save a game, and then read all the game state values out of when you load a game. The shelve module handles all the file I/O details for you.</p>
<h2>The shelve.open() Function</h2>
<p>There are a few options you might want to pay attention to for the shelve.open() function. There are three optional parameters to the shelve.open() function you might want to pass, but the default values for these are what you want in 99% of the cases, so you can skip the rest of this section.</p>
<div class="hide-this-part-wrap"><div class="hide-this-part-more" id="hide-this-part-1" morelink-text="Show the optional parameter explanations.">Show the optional parameter explanations. »</div><div class="hide-this-part" status="invisible"><br />
The flag parameter can be the string &#8216;r&#8217; (to open the shelf file as read-only), &#8216;w&#8217; (to open the shelf file for reading and writing), &#8216;c&#8217; (to open for reading and writing, but also creating the shelf file if it doesn&#8217;t already exist. This is the default.), and &#8216;n&#8217; (delete the old shelf file and start with a new, blank shelf file). I don&#8217;t really find this too handy, but there might be cases where it is useful.</p>
<p>The protocol parameter is probably the one parameter you want to set. It defines the version that the &#8220;pickler&#8221; uses to store the data. (&#8220;Pickling&#8221; is the term used for converting values in your variables to text that are written out to files, which is done when you save a game. &#8220;Unpickling&#8221; is the reverse. That&#8217;s what happens when you load a saved game. The shelve module makes use of the code in the more primitive (but more flexible) <a href="http://docs.python.org/py3k/library/pickle.html">pickle module</a>.)</p>
<p>By default the call to shelve.open() uses the oldest, least efficient version. This is good because it also ensures that it will be the most widely supported no matter what version of Python people are using.</p>
<p>However, if you want more efficiency, you can pass the integer 2 for this parameter (the versions are currently 0, 1, and 2). Or if you have &#8220;import pickle&#8221; in your script, you can pass pickle.HIGHEST_PROTOCOL and this will always use the latest version of the pickling protocol. But be warned, earlier versions of Python may not be able to read the shelf files produced by later versions of Python running your game script.</p>
<p>To be safe, just use the default. There&#8217;s more info about pickle protocol versions at <a href="http://docs.python.org/py3k/library/pickle.html">http://docs.python.org/py3k/library/pickle.html</a></p>
<p>The third optional parameter to shelve.open() is the writeback parameter. This is used for a situation like this:</p>
<pre>import shelve
shelfFile = shelve.open('some_file')
myList = [1, 2, 3]
shelfFile['list'] = myList
myList.append(4)
shelfFile.close()</pre>
<p>In the above code, what is stored in the shelf file is the list [1, 2, 3] and not [1, 2, 3, 4]. The data that is stored in the shelf file is not updated even though the list that was placed in the shelfFile was updated. You need to think of the line shelfFile['list'] = myList as &#8220;Store the value in myList as it looks right now.&#8221;</p>
<p>If you want the shelf file to update whenever mutable values such as lists or dictionaries are updated, pass True for the writeback parameter. If you use shelve.open(&#8216;some_file&#8217;, writeback=True) in the above code, then the list that is stored in the shelf file will be [1, 2, 3, 4].</p>
<p>Having writeback adds some memory costs to your program, and since for saved games we usually open a shelf file, write to it, and close it immediately, it&#8217;s not a very useful feature. You can ignore it.<br />
</div><!-- .hide-this-part --></div><!-- hide-this-part-wrap -->
<p>You can read <a href="http://docs.python.org/py3k/library/shelve.html#shelve.open">the official documentation for shelve.open() and its parameters</a>.</p>
<h2>File Formats and Shelf File Extensions</h2>
<p>About the file formats that the shelve module uses:</p>
<p>It doesn&#8217;t matter. The shelve module handles all the details. You can ignore it completely. It&#8217;s one less thing you need to worry about so you can get back to making your game.</p>
<p>You may notice that when you create shelf files, there are actually three files that are created. If you used &#8216;some_file&#8217; in the shelve.open() call, the files that appear on your hard drive after you call the close() method are some_file.bak, some_file.dir, and some_file.dat.</p>
<p>You don&#8217;t really need to know what these files are used for. In my own experiments, you can delete the .bak file (I guess it&#8217;s just a backup file, but keep it around anyway) but the .dat and .dir files are needed. The only reason I point this out is because if you want to copy your saved game files to another computer, you need to know that there is more than one file that needs to be copied.</p>
<p>If you pass an extension to shelve.open() like &#8216;some_file.txt&#8217;, then the files will be some_file.txt.bak, some_file.txt.dat, and some_file.txt.dir.</p>
<h2>Security Warning</h2>
<p>Just like with any file, your players can modify the values in the shelf file. You can try obfuscated the data in it, but this never works in the long run. What this means in most cases is that people can make saved game hack programs to let players cheat. That&#8217;s not really a problem.</p>
<p>What can be a problem is if your game executes code depending on the content of the shelf file, than this can have bad security implications. Say as part of the save game file, you include a string that tells your game what program to run. Something like this:</p>
<pre>shelfFile['programToRun'] = 'notepad.exe'</pre>
<p>A malicious hacker could change the shelf file so that instead of the string &#8216;notepad.exe&#8217; it is &#8216;virus.exe&#8217; or some other value that could cause your game program to act badly because of a saved game file. In most cases, your games won&#8217;t store data like this. But it&#8217;s something that I just wanted to point out.</p>
<h2>Examples: flippy_withsavegame.py and reverse_withsavegame.py</h2>
<p>The good news is that the shelve module makes it as simple as possible to convert the values in variables to files on the hard drive, and vice versa. Just call shelve.open(), assign the values to the shelf file object, and then call the close() method.</p>
<p>But it also helps to see this used in actual code. I&#8217;ve modified a couple Othello games from &#8220;Invent Your Own Computer Games with Python&#8221; and &#8220;Making Games with Python&#8221;. Both are written for Python 3.</p>
<p>Reversi is an Othello clone that uses ASCII text for graphics. Flippy is an Othello clone that has real graphics. You will need to download and install Pygame to run it. </p>
<ul>
<li><a href="http://inventwithpython.com/savefeature_shelve.zip">Download the original and modified version of Flippy and Reversi.</a></li>
<li><a href="http://inventwithpython.com/flippy_savegame_diff.html">View the changes &#8220;diff&#8221; for Flippy.</a></li>
<li><a href="http://inventwithpython.com/reversi_savegame_diff.html">View the changes &#8220;diff&#8221; for Reversi.</a></li>
<li><a href="http://inventwithpython.com/chapter15.html">Read Chapter on Reversi.</a></li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F05%2F03%2Fimplement-a-save-game-feature-in-python-with-the-shelve-module%2F&amp;title=Implement%20a%20%E2%80%9CSave%20Game%E2%80%9D%20Feature%20in%20Python%20with%20the%20shelve%20Module" id="wpa2a_4"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/05/03/implement-a-save-game-feature-in-python-with-the-shelve-module/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stop Using &#8220;print&#8221; for Debugging: A 5 Minute Quickstart Guide to Python’s logging Module</title>
		<link>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/</link>
		<comments>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 17:15:35 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=675</guid>
		<description><![CDATA[This tutorial is short. To figure out bugs in your code, you might put in print statements/print() calls to display the value of variables. Don’t do this. Use the Python logging module. The logging is better than printing because: It&#8217;s easy to put a timestamp in each message, which is very handy. You can have [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>This tutorial is short.</li>
<li>To figure out bugs in your code, you might put in <code>print</code> statements/<code>print()</code> calls to display the value of variables.</li>
<li>Don’t do this. Use the Python <code>logging</code> module.</li>
</ul>
<p>The <code>logging</code> is better than printing because:</p>
<ul>
<li>It&#8217;s easy to put a timestamp in each message, which is very handy.</li>
<li>You can have different levels of urgency for messages, and filter how less urgent messages.</li>
<li>When you want to later find/remove log messages, you won&#8217;t get them confused for real <code>print()</code> calls.</li>
<li>If you just print to a log file, it&#8217;s easy to leave the log function calls in and just ignore them when you don&#8217;t need them. (You don&#8217;t have to constantly pull out print() calls.)</li>
</ul>
<p>Using print is for coders with too much time on their hands. Use logging instead. Also, learn to use <a href="http://mihirknows.blogspot.com/2007/10/debugging-with-python-pdb-quick-and.html">the Python debugger</a> to debug bugs and <a href="http://www.logilab.org/857">Pylint</a> to prevent bugs and make your code readable.</p>
<p>To <strong>print log messages to the screen</strong>, copy and paste this code:</p>
<blockquote><p><code>import logging<br />
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')<br />
logging.debug('This is a log message.')</code></p></blockquote>
<p>To <strong>write log messages to a file</strong>, you can copy and paste this code (the only difference is <strong>in bold</strong>):</p>
<blockquote><p><code>import logging<br />
logging.basicConfig(<strong>filename='log_filename.txt', </strong>level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')<br />
logging.debug('This is a log message.')</code></p></blockquote>
<p>Later runs of the program will append to the end of the log file, rather than overwrite the file.</p>
<p>To log messages to a file <strong>AND</strong> printed to the screen, copy and paste the following:<br />
<span id="more-675"></span></p>
<blockquote><p><code>import logging<br />
logger = logging.getLogger()<br />
logger.setLevel(logging.DEBUG)</p>
<p>formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')</p>
<p>fh = logging.FileHandler('log_filename.txt')<br />
fh.setLevel(logging.DEBUG)<br />
fh.setFormatter(formatter)<br />
logger.addHandler(fh)</p>
<p>ch = logging.StreamHandler()<br />
ch.setLevel(logging.DEBUG)<br />
ch.setFormatter(formatter)<br />
logger.addHandler(ch)</p>
<p>logger.debug('This is a test log message.')</code></p></blockquote>
<p>Make sure that the <code>logger</code> variable is global, so that you can use it in functions. (You don&#8217;t need the &#8220;<code>global logger</code>&#8221; at the top of the function, because the <code>logger</code> variable is only read, not modified.)</p>
<hr />
<p>The different levels of logging, from highest urgency to lowest urgency, are:</p>
<ol>
<li>CRITICAL</li>
<li>ERROR</li>
<li>WARNING</li>
<li>INFO</li>
<li>DEBUG</li>
</ol>
<p>The <code>setLevel()</code> call sets the minimum log level of messages it actually logs. So if you <code>fh.setLevel(logging.ERROR)</code>, then WARNING, INFO, and DEBUG log messages will not be written to the log file (since <code>fh</code> is the log handler for the log file, as opposed to <code>ch</code> which is the handler for the console screen.)</p>
<p>To write a log message in one of these five levels, use the following functions:</p>
<ol>
<li><code>logger.critical('This is a critical message.')</code></li>
<li><code>logger.error('This is an error message.')</code></li>
<li><code>logger.warning('This is a warning message.')</code></li>
<li><code>logger.info('This is an informative message.')</code></li>
<li><code>logger.debug('This is a low-level debug message.')</code></li>
</ol>
<p>There&#8217;s plenty more you can do, but this all you need to know to never again use <code>print()</code> calls to do your debugging work.</p>
<p>The <a href="http://docs.python.org/library/logging.html">Python documentation</a> has more info, including a <a href="http://docs.python.org/howto/logging.html#logging-basic-tutorial">Basic Tutorial</a>, an <a href="http://docs.python.org/howto/logging.html#logging-advanced-tutorial">Advanced Tutorial</a>, and a <a href="http://docs.python.org/howto/logging-cookbook.html#logging-cookbook">Logging Cookbook</a>.</p>
<p>Also, the <a href="http://docs.python.org/library/pprint.html#pprint.pprint">pprint.pprint() function</a> is great for &#8220;pretty printing&#8221; dictionaries and lists that have nested dictionaries and lists in them. The <a href="http://docs.python.org/library/pprint.html#pprint.pformat">pprint.pformat() function</a> returns the string of this content, rather than printing it to the screen.</p>
<hr />
<p>One final tip: You can use the <code>tail -f logfile.txt</code> command to show a file as it is being written to. The -f stands for &#8220;follow&#8221;. Just leave a terminal/console window open with this command running, and new text in the log file will appear as it is written. This way, you don&#8217;t have to keep opening/reloading a text editor to view the latest text in the log file.</p>
<p>The tail command comes on Mac OS X and Linux OSes. On Windows, you can download the <a href="http://www.cygwin.com/install.html">Cygwin project</a> to get the tail command.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F04%2F06%2Fstop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module%2F&amp;title=Stop%20Using%20%E2%80%9Cprint%E2%80%9D%20for%20Debugging%3A%20A%205%20Minute%20Quickstart%20Guide%20to%20Python%E2%80%99s%20logging%20Module" id="wpa2a_6"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>How to Code a Twitter Bot in Python on Dreamhost</title>
		<link>http://inventwithpython.com/blog/2012/03/25/how-to-code-a-twitter-bot-in-python-on-dreamhost/</link>
		<comments>http://inventwithpython.com/blog/2012/03/25/how-to-code-a-twitter-bot-in-python-on-dreamhost/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 20:46:25 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=655</guid>
		<description><![CDATA[I made a twitter bot that checks every hour for someone who has asked the question, “Why do homeless people have dogs?” and automatically replies, “Because a dog will love you even though you are homeless.” It’s running right now at @YHobosHaveDogs. Figuring out how to code this took a couple evenings and a little [...]]]></description>
			<content:encoded><![CDATA[<p>I made a twitter bot that checks every hour for someone who has asked the question, “Why do homeless people have dogs?” and automatically replies, “Because a dog will love you even though you are homeless.” It’s running right now at <a href="http://twitter.com/#!/YHobosHaveDogs">@YHobosHaveDogs</a>.</p>
<p>Figuring out how to code this took a couple evenings and a little hair pulling, so I decided to document the process in this blog article to make it easier for the next programmer. This will be making a Twitter bot in Python using the <a href="http://inventwithpython.com/python-twitter-0.8.2.tar.gz">python-twitter module</a> (which runs on Python 2, not Python 3), and then running the bot from my Dreamhost server (but most likely any web host will work just fine. Or if you have a computer that is always online, you can run the bot from that). First we will run the bot from our machine to test it out, and then load it onto the Dreamhost web host. (I’m running a Windows box, but the steps should work on any OS.)</p>
<ol>
<li>Download the <a href="http://inventwithpython.com/python-twitter-0.8.2.tar.gz">python-twitter module</a> (I tried some of the other modules but didn’t like them as much.)</li>
<li>Unzip this file and from the command line in the unzipped directory, run “python setup.py install” to install the twitter module.</li>
<p><span id="more-655"></span></p>
<li>Run Python and then type, “import twitter”. If you don’t get any error messages, the module has installed correctly.</li>
<li>Go to <a href="http://twitter.com">http://twitter.com</a> and create a new Twitter account for this bot. (You might need to get a throwaway email address to sign up with.)</li>
<li>Now you need to set up this account so your script can make calls to Twitter’s API. Go to <a href="https://dev.twitter.com/">https://dev.twitter.com/</a> and sign in.</li>
<li>Click on <strong>“Create an App”</strong>, or just go directly to <a href="https://dev.twitter.com/apps/new">https://dev.twitter.com/apps/new</a> and enter in the details. I don’t think any of this info actually matters. You don’t need a callback URL. Click <strong>“Create your Twitter Application”</strong>.</li>
<li>On the new app’s web page, and under <strong>“Application Type”</strong> click on the <strong>“Read, Write, and Access direct messages”</strong> radio button. This is so that the bot can make posts and send DMs. Click <strong>“Update this Twitter Application’s settings”</strong>.</li>
<li>Go back to the Details tab, and at the bottom of the screen click <strong>“Create my access token”</strong>.</li>
<li>When the page reloads, you will need to copy the following four pieces of information from this page:  “Consumer Key”, “Consumer Secret”, “Access Token”, and “Access Token Secret”</li>
</ol>
<p>You’re now ready to start coding your Twitter bot.</p>
<h2>Logging In Your Bot</h2>
<p>The reason you had to jump through all those hoops is because a Twitter application uses the OAuth system so that it can post tweets and DMs (Direct Messages) on behalf of other people’s accounts. This is a more than we need to do (our bot will only post from its own account), but <strong>OAuth is the only way programs can log in to Twitter</strong>. (This system is why you can give third parties’ software permission to post things from your twitter account without giving them your password, such as having Facebook tweet your Facebook status updates.)</p>
<p>If you are reading any other tutorials on the web or see twitter Python modules where you can log in with just the account’s username and password (or mention “Basic authentication”), these tutorials/modules are out of date. Twitter no longer lets you log in with just the username and password as of August of 2010.</p>
<p>Open a text editor or IDE to write Python code, or just test this code from the interactive shell (replacing the keys and secrets with the values you got for your app):</p>
<p><code>>>> import twitter<br />
>>> api = twitter.Api(consumer_key='og82uZE9GOLMDsQxileh65', consumer_secret='me7hXfqDOv0KZuHICWnpdxTNykQBoUrS1zVgb4ARFt', access_token_key='iINPSMrwktD4ZLn01WhfoRb7a2OJ6F38zKlYBTQcm5UvjgHGAe', access_token_secret='5Opjh1qMaHAyz2Bw9i4bxPKNLE0RFeJuYsn8TdtUGWv')</code></p>
<p>This will now log you in to your bot’s account. Note that if you ever revoke the access tokens (which you are unlikely to do by accident), you will have to change the value in the access_token_key and access_token_secret parameters.</p>
<p>At this point, your code can make any of the function calls that the twitter module provides. Here’s a complete API reference: <a href="http://inventwithpython.com/twitter.html">http://inventwithpython.com/twitter.html</a>. </p>
<p>Here’s the source code to my <a href="https://twitter.com/#!/YHobosHaveDogs">@YHobosHaveDogs</a> bot. It basically searches for the text &#8216;&#8221;homeless people&#8221; dogs&#8217; and then replies to them (if they posted the message in the last 24 hours, the bot hasn’t replied to them before, and if this isn’t a reply to someone the bot has replied to.) My initial testing shows that the bot’s reply to these search results is relevant most of the time.</p>
<p><a href="http://inventwithpython.com/yhobos_script.py">Download Twitter bot&#8217;s code: yhobos_script.py</a></p>
<p>It’s very important that you test your bot before putting it out in the world, especially if it messages strangers. You don’t want to accidentally spam people. The <code>PostUpdate()</code> method will give you an error if you try to post the exact same message as one you’ve posted before, but this won’t prevent all problems.</p>
<p>What I do to test is comment out the <code>PostUpdate()</code> calls and slip in a print statement instead, so I can see what the program would post without it actually posting anything. Twitter has <a href="https://dev.twitter.com/docs/rate-limiting">rate-limiting</a> for a max of 350 calls per hour. </p>
<p>Once you have your bot working, you&#8217;ll want to have the bot&#8217;s script regularly called. If you have a desktop that is always connected to the Internet, you can use <a href="http://windows.microsoft.com/en-US/windows7/schedule-a-task">Windows&#8217; Scheduled Tasks</a> or on Mac you can use iCal, cron, or <a href="http://en.wikipedia.org/wiki/Launchd">launchd</a> to have the bot&#8217;s script run every hour or so.</p>
<p>If you have a webhost like Dreamhost, you can use cron to schedule repeated calls to the bot script. But first you will have to set up the Python twitter module on Dreamhost. This requires a few extra steps because you cannot install modules to the system&#8217;s Python binary. Instead we will use virtualenv to create our own Python to install the twitter module to.</p>
<h2>Installing Modules to Python on Dreamhost</h2>
<p>SSH into your Dreamhost account (I use <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a> on Windows. Linux and Mac OS X have the command line &#8220;ssh&#8221; program that you can run from a terminal screen.) </p>
<p>run the following commands to install VirtualEnv: (you might want to read <a href="http://wiki.dreamhost.com/Python">the Dreamhost wiki&#8217;s Python page</a> for details. I also found <a href="http://nerdthings.tumblr.com/post/358234905/installing-python-modules-on-dreamhost">this page</a> to be helpful.)</p>
<p><code>wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.4.3.tar.gz<br />
tar xzvf virtualenv-1.4.3.tar.gz<br />
cd virtualenv-1.4.3/<br />
python virtualenv.py $HOME/local<br />
mv ~/local/lib/python2.5 ~/local/lib/python</code></p>
<p>(The last command is to rename the python2.5 directory to python, which the twitter module&#8217;s installer seems to demand.)</p>
<p>Then install the python-twitter module (which will also install the oauth module it needs):</p>
<p><code>wget http://python-twitter.googlecode.com/files/python-twitter-0.8.2.tar.gz<br />
tar xzvf python-twitter-0.8.2.tar.gz<br />
cd python-twitter-0.8.2/<br />
/home/yourusername/local/python setup.py install --home=~/local</code></p>
<h2>Setting Up Cron on Dreamhost for your Bot</h2>
<p>You will have to set the bot&#8217;s script file as executable, which you can do by entering this command:</p>
<p><code>chmod 774 mytwitterbot.py</code></p>
<p>And add this code to the very top of the bot script so that Dreamhost will use your virtualenv Python to run the script in /home/yourusername/local/bin instead of the system&#8217;s Python in /usr/bin:</p>
<p><code>#!/home/yourusername/local/bin/python</code></p>
<p>Also, I found that I had to change the Python path at the beginning of the script since Dreamhost&#8217;s cron daemon didn&#8217;t have it set up. There&#8217;s probably a more graceful way to handle this, but I simply added this code to the beginning of my twitter bot code:</p>
<p><code>sys.path = ['/home/yourusername/yhoboshavedogs', '/home/yourusername/local/lib/python/python_twitter-0.8.2-py2.5.egg', '/home/yourusername/local/lib/python/oauth2-1.5.211-py2.5.egg', '/home/yourusername/local/lib/python/httplib2-0.7.4-py2.5.egg', '/home/yourusername/local/lib/python/simplejson-1.9.2-py2.5-linux-x86_64.egg', '/home/yourusername/local/lib/python/python_twitter-0.8.2-py2.5.egg', '/home/yourusername/local/lib/python/oauth2-1.5.211-py2.5.egg', '/home/yourusername/local/lib/python/simplejson-1.9.2-py2.5-linux-x86_64.egg', '/home/yourusername/local/lib/python2.5', '/home/yourusername/local/lib/python', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages/Numeric', '/usr/lib/python2.5/site-packages/PIL', '/var/lib/python-support/python2.5', '/usr/lib/site-python', '/home/yourusername/local/lib/python2.5']</code></p>
<p>From the <a href="https://panel.dreamhost.com/index.cgi?tree=goodies.cron&#038;">Dreamhost Panel&#8217;s cron jobs section</a>, click on &#8220;Add a new cron job&#8221;. In the form that appears, add &#8220;/home/yourusername/mytwitterbot.py&#8221; as the command to run. You can also add your email address so that you are emailed any errors or output that appear from the cron job.</p>
<p>I have my bot set up to not print out anything if it doesn&#8217;t update anything. This way my email address doesn&#8217;t get flooded with emails when the bot doesn&#8217;t do anything.</p>
<p>At this point, the bot should be set up. Leave a comment on this blog post if you have questions about anything.</p>
<h2>API Reference Summary</h2>
<p>The <a href="http://inventwithpython.com/twitter.html">API Reference Documentation</a> has some good pointers for the functions in the module. But here&#8217;s my own remarks and summary of it. “Status” is the term that the module uses to mean a Twitter post or update. To post a twitter status message (after being authenticated):</p>
<p><code>>>> status = api.PostUpdate('I love python-twitter!')<br />
>>> print status.text<br />
I love python-twitter!</code></p>
<p>To fetch your friends (after being authenticated):</p>
<p><code>>>> users = api.GetFriends()<br />
>>> print [u.name for u in users]</code></p>
<p>To post a direct message to a user:</p>
<p><code>>>> directMessage = api.PostDirectMessage('@myfriend', 'This is my message.')</code></p>
<p>For the recipient, you can also use that user’s id.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F03%2F25%2Fhow-to-code-a-twitter-bot-in-python-on-dreamhost%2F&amp;title=How%20to%20Code%20a%20Twitter%20Bot%20in%20Python%20on%20Dreamhost" id="wpa2a_8"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/03/25/how-to-code-a-twitter-bot-in-python-on-dreamhost/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>CircleMUD Data in XML Format for Your Text Adventure Game</title>
		<link>http://inventwithpython.com/blog/2012/03/19/circlemud-data-in-xml-format-for-your-text-adventure-game/</link>
		<comments>http://inventwithpython.com/blog/2012/03/19/circlemud-data-in-xml-format-for-your-text-adventure-game/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 17:13:43 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=629</guid>
		<description><![CDATA[Long before World of Warcraft, people played text-based MMORPGs called MUDs (Multi-User Dungeon). These were basically multiplayer text adventure games where people could wander through a virtual world fighting monsters and exploring. They had several RPG elements to them. CircleMUD was a popular piece of server software for running a MUD, and it came with [...]]]></description>
			<content:encoded><![CDATA[<p>Long before World of Warcraft, people played text-based MMORPGs called MUDs (Multi-User Dungeon). These were basically multiplayer text adventure games where people could wander through a virtual world fighting monsters and exploring. They had several RPG elements to them.</p>
<p>CircleMUD was a popular piece of server software for running a MUD, and it came with a sizeable virtual world (which the admin could modify/append to customize their fantasy world.) It would be pretty handy to use parts of this data if you were creating your own virtual world for a text adventure game, but the format of CircleMUD&#8217;s data files is kind of obtuse and not amenable to manipulation.</p>
<p>So I wrote a few scripts to convert these files into a single XML file which is 4MB when unzipped. You can parse this file and modify it to suit your needs. It contains 1979 rooms across 30 different areas (called zones in the file), with 46 shops and 569 different &#8220;mobs&#8221; (mobile objects, which are the monsters and NPCs). There are 678 different types of objects, including 116 weapons and 154 types of armor.</p>
<p>The scripts and original CircleMUD data (along with descriptions of the data formats) are included in the zip:</p>
<p><a href="http://inventwithpython.com/circlemuddata.zip" style="font-size:150%">Download CircleMUD XML Data (1.3 MB zipped)</a><br />
<span id="more-629"></span><br />
Use Python&#8217;s XML parsing libraries rather than trying to write your own code to parse it. <a href="http://diveintopython3.ep.io/xml.html">Dive into Python</a> has a chapter on XML parsing and Effbot&#8217;s <a href="http://effbot.org/zone/element.htm">ElementTree</a> module can parse XML. The zip file also comes with a small script that loads the data as a giant Python dict.</p>
<p>Here&#8217;s an example of what this textual data looks like:</p>
<p><span style="color: blue; line-height: 1.1em"> &lt;mob&nbsp;vnum=&quot;907&quot;&nbsp;alignment=&quot;-1000&quot;&nbsp;type=&quot;S&quot;&nbsp;level=&quot;26&quot;&nbsp;thac0=&quot;0&quot;&nbsp;ac=&quot;-2&quot;&nbsp;<br />
<br/>maxhp=&quot;12d8+590&quot;&nbsp;barehanddmg=&quot;4d6+10&quot;&nbsp;gold=&quot;0&quot;&nbsp;xp=&quot;160000&quot;&nbsp;<br />
<br/>loadposition=&quot;standing&quot;&nbsp;defaultposition=&quot;standing&quot;&nbsp;sex=&quot;male&quot;&gt;<br/>&nbsp;&nbsp;&lt;alias&nbsp;name=&quot;minos&quot;&nbsp;/&gt;<br/>&nbsp;&nbsp;&lt;alias&nbsp;name=&quot;king&quot;&nbsp;/&gt;<br/>&nbsp;&nbsp;&lt;alias&nbsp;name=&quot;minotaur&quot;&nbsp;/&gt;<br/>&nbsp;&nbsp;&lt;shortdesc&gt;King&nbsp;Minos&nbsp;the&nbsp;Minotaur&lt;/shortdesc&gt;<br/>&nbsp;&nbsp;&lt;longdesc&gt;King&nbsp;Minos&nbsp;the&nbsp;Minotaur&nbsp;is&nbsp;ready&nbsp;and&nbsp;waiting&nbsp;to&nbsp;gore&nbsp;you&nbsp;to&nbsp;death.&lt;/longdesc&gt;<br/>&nbsp;&nbsp;&lt;detaileddesc&gt;He&nbsp;smells&nbsp;something&nbsp;awful.&lt;/detaileddesc&gt;<br/>&nbsp;&nbsp;&lt;action&nbsp;sentinel=&quot;true&quot;&nbsp;aggressive=&quot;true&quot;&nbsp;memory=&quot;true&quot;&nbsp;helper=&quot;true&quot;&nbsp;<br />
<br/>nocharm=&quot;true&quot;&nbsp;nosummon=&quot;true&quot;&nbsp;nobash=&quot;true&quot;&nbsp;/&gt;<br/>&nbsp;&nbsp;&lt;affection&nbsp;detectinvis=&quot;true&quot;&nbsp;senselife=&quot;true&quot;&nbsp;sanctuary=&quot;true&quot;&nbsp;infravision=&quot;true&quot;&nbsp;<br />
<br/>notrack=&quot;true&quot;&nbsp;/&gt;<br/>&lt;/mob&gt;</span></p>
<p>If you&#8217;d like to play a MUD for yourself, there are still many that are run on the Internet. The website <a href="http://mudconnect.com/">mudconnect.com</a> lists over a thousand of them. Just search for &#8220;CircleMUD&#8221; to find a server that runs the CircleMUD software.</p>
<p>Enjoy!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F03%2F19%2Fcirclemud-data-in-xml-format-for-your-text-adventure-game%2F&amp;title=CircleMUD%20Data%20in%20XML%20Format%20for%20Your%20Text%20Adventure%20Game" id="wpa2a_10"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/03/19/circlemud-data-in-xml-format-for-your-text-adventure-game/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>“How much math do I need to know to program?” Not That Much, Actually.</title>
		<link>http://inventwithpython.com/blog/2012/03/18/how-much-math-do-i-need-to-know-to-program-not-that-much-actually/</link>
		<comments>http://inventwithpython.com/blog/2012/03/18/how-much-math-do-i-need-to-know-to-program-not-that-much-actually/#comments</comments>
		<pubDate>Sun, 18 Mar 2012 21:11:59 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=601</guid>
		<description><![CDATA[Here are some posts I’ve seen on the r/learnprogramming subreddit forum: How much math do you need to become a good programmer? Should I brush up on math? This may be the dumbest question I have ever posted online. How much math does one actually need to be a good programmer? Math and programming have [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" href="/pygments_friendly.css">
<p>Here are some posts I’ve seen on the <a href="http://reddit.com/r/learnprogramming">r/learnprogramming subreddit forum</a>:</p>
<ul>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/i9j9n/how_much_math_do_you_need_to_become_a_good/">How much math do you need to become a good programmer?</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/pmv2n/should_i_brush_up_on_math/">Should I brush up on math?</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/pg4iu/this_may_be_the_dumbest_question_i_have_ever/">This may be the dumbest question I have ever posted online. How much math does one actually need to be a good programmer?</a></li>
</ul>
<p>Math and programming have a somewhat misunderstood relationship. Many people think that you have to be good at math or made good grades in math class before you can even begin to learn programming. But how much math does a person need to know in order to program?</p>
<p><strong>Not that much actually.</strong> This article will go into detail about the kinds of math you should know for programming. You probably know it already.</p>
<p>For general programming, you should know the following:<br />
<span id="more-601"></span></p>
<ul>
<li><strong>Addition, subtraction, division, and multiplication</strong> – And really, the computer will be doing the adding, subtracting, dividing, and multiplying for you anyway. You just have to know when you need to do these operations.
</li>
<li><strong>Mod</strong> – The mod operation is the “remainder” and its sign is usually the % percent sign. So 23 divided by 7 is 3 with a remainder of 2. But 23 mod 7 is 2.</li>
<li><strong>The even/odd mod test trick</strong> – If you want to know if a number is odd or even, mod it by 2. If the result is 0, the number is even. If the result is 1, the number is odd. 23 mod 2 is 1, so you know 23 is odd. 24 mod 2 is 0, so you know 24 is even. If x mod 2 is 0, you know that whatever number is stored in the variable x is even.</li>
<li><strong>To get a percentage of a number</strong>, multiply that number by the percent number with the decimal point in front of it. So to get 54% of 279, multiple 0.54 * 279. This is why 1.0 often means 100% and 0.0 means 0%.</li>
<li><strong>Know what <a href="http://inventwithpython.com/chapter12.html#NegativeNumbers">negative numbers</a> are.</strong> A negative number times a negative number is a positive. A negative times a positive is negative. That’s about it.</li>
<li><strong>Know what a <a href="http://inventwithpython.com/chapter12.html">Cartesian coordinate system</a> is.</strong> In programming, the (0, 0) origin is the top left corner of the screen or window, and the Y axis increases going down.</li>
<li><strong>Know the <a href="http://en.wikipedia.org/wiki/Pythagorean_theorem">Pythagorean theorem</a>, and that it can be used to find the distance between two points</strong> on a Cartesian coordinate system. The Pythagorean theorem is a^2 + b^2 = c^2. What this usually means in programming is the distance between coordinate (x1, y1) and (x2, y2) will just be sqrt( (x1 – x2)^2 + (y1 – y2)^2 ).</li>
<li><strong>Know what decimal, binary, and hexadecimal numbering systems are.</strong> Decimal numbers are the numbers we’re used to that have ten digits: 0 to 9. It’s commonly thought that humans develop this system because we have ten fingers and counted on our fingers.</li>
</ul>
<p>Computers work with binary data, which is a number system with only two digits: 0 and 1. This is because we build computers out of electronics components where it’s cheaper to make them only recognize two different states (one to represent 0 and the other to represent 1).</p>
<p><strong>The numbers are still the exact same, but they are written out differently</strong> because there are a different number of digits in each system. Because hex has 6 more digits than the 0-9 numerals can provide, we use the letters A through F for the digits above 9. The easiest way to show these number systems is with an odometer. The following three odometers <strong>always show the same number</strong>, but they are written out differently in different number systems:</p>
<p><center><a href="http://inventwithpython.com/numbersystems.html" target="_blank"><img src="http://inventwithpython.com/images/odometerpage.png" /><br />See the Odometer Number Systems page in a new window.</a></center></p>
<p>You don’t even have to know the math of <a href="http://courses.cs.vt.edu/~cs1104/number_conversion/convexp.html">converting a number from one number system to another</a>. Every programming language has functions that can do this for you.</p>
<p>(On a side note, hexadecimal is used because one hexadecimal digit can represent exactly four binary digits. So since 3 in hex represents 0011 in binary and A in hex represents 1010. This has the nice effect that the hex number 3A (which is 58 in decimal) is written in binary as 00111010. <strong>Hex is used in programming because it is a shorthand for binary.</strong> Nobody likes writing out all those ones and zeros.)</p>
<p><strong>And that’s about it.</strong> Other than the number system stuff, you probably already knew all the math you needed to know to do programming. Despite the popular conception, math isn’t really used that much in programming. You would need to know math in order to write programs that do, say, earthquake simulators. But that’s more about needing to know math for earthquakes rather than needing to know math for programming an earthquake simulator.</p>
<h2>Advanced Mathematics in Some Areas of Programming</h2>
<p>There’s a few areas of programming where some additional math knowledge might be needed (but for 95% of the software you’ll write, you don’t need to know it.)</p>
<p><strong>3D games and 3D graphics</strong> – 3D stuff will usually involve knowing trigonometry and linear algebra (that is, math dealing with matrices). Of course, there are many 3D graphics libraries that implement all this math programming for you, so you don’t need to know the math.</p>
<p><strong>2D physics (like Angry Birds) and 3D physics (like many popular 3D games use)</strong> – To do programming that involves physics, you’ll need to learn some physics equations and formulas (specifically mechanics, which is the type of physics with springs, gravity, and balls rolling down inclined planes.) However, there are several physics engines and software libraries that implement this stuff for you, so you really don’t need to know the physics equations to make a game like Angry Birds.</p>
<p><strong>Cryptography</strong> – And really, by cryptography, I just mean RSA. In which case, you’d have to learn some math about how prime numbers work and doing the Greatest Common Divisor (which is a dead simple algorithm, although plenty of programming languages have gcd() function that does this for you.) Other encryption ciphers are mostly moving data around in specific steps. For example, <a href="http://www.google.com/url?sa=t&#038;rct=j&#038;q=&#038;esrc=s&#038;source=web&#038;cd=1&#038;ved=0CDIQFjAA&#038;url=http%3A%2F%2Fwww.cs.bc.edu%2F~straubin%2Fcs381-05%2Fblockciphers%2Frijndael_ingles2004.swf&#038;ei=YVNqT_ONM-LJiQKT97X6BA&#038;usg=AFQjCNF7M-_HwuQE5KZwjYkc4FoJBUBpqQ">this Flash animation shows the steps in the AES “Rijndael” cipher</a>. All the steps are basically substituting numbers for other numbers, shifting rows of numbers over, mixing up columns of numbers, and doing basic addition with numbers.</p>
<p>And that’s just if you want to write your own encryption ciphers (which you shouldn’t do, because there are already plenty of good ones and without expertise your cipher will probably suck and be easily cracked.) If you just want to write a program that encrypts data, there are software libraries that implement encryption and decryption functions already.</p>
<p><strong>So even for the above situations, you don’t need to know the math to make programs with 3D graphics, physics, or encryption. Just learn to use the libraries.</strong></p>
<h2>What You Do Need to Learn to Do Programming</h2>
<p>What you do need to learn is how to model data and devise algorithms. This basically means, <em>how to take some real-world calculation or some data processing, and write out code that makes the computer do it</em>. For example, in the game Dungeons and Dragons the characters and monsters have several different statistics for combat:</p>
<ul>
<li><strong>HP</strong>, or hit points, is the amount of damage a person can take before dying. More HP means you can take more damage before dying.</li>
<li><strong>AC</strong>, or armor class, is a measure of the chance your armor has of blocking an attack. The lower the AC, the more protective the armor is.
</li>
<li><strong>THAC0</strong> (pronounced “thay-co”), or “To Hit Armor Class 0”, is a measure of how skillful the person is at making a successful hit on an opponent. The lower the THAC0, the more accurate the person’s attack is.</li>
<li>The <strong>damage</strong> of the weapon is written out as something like 1d6+2. This means the damage is the amount from rolling 1 six-sided dice, and then adding 2 to it. A damage stat of 2d4 would be rolling 2 four-sided dice and adding them together. (Dungeons and Dragons uses 4, 6, 8, 10, 12, and 20-sided dice.)</li>
</ul>
<p>To see if an attacker hits a defender, the attacker rolls a twenty-sided die. <strong>If this number is equal to or greater than the attacker’s THAC0 minus the defender’s AC, then the hit is successful and the defender takes damage.</strong> Otherwise, the defender has either dodged or blocked the attack and takes no damage.</p>
<p>Let’s take two Dungeon and Dragons characters, Alice and Bob, with the following stats:</p>
<ul>
<li>Alice: HP 14, AC 5, THAC0 18, DAMAGE 1d6</li>
<li>Bob: HP 12, AC 7, THAC0 16, DAMAGE 2d4</li>
</ul>
<p>So Alice has two more hit points than Bob and better armor (remember, lower AC is better). But Bob is more likely to make a successful hit (remember, lower THAC0 is better) and does more damage. We can tell Bob’s damage is better because 2d4 will result in 2 to 8 points of damage, while Alice’s 1d6 will result in 1 to 6 points of damage. (If you knew statistics math, you could calculate that Bob’s expected value of damage is 5, which is larger than Alice’s expected value of damage is 3.5.)</p>
<p>So would you bet on Alice or Bob to win in a fight? It’s hard to tell, they seem pretty evenly matched. Even if you knew a lot of statistics, doing all these calculations would be a pain. But you don’t need to know statistics in order to write a program that simulates Dungeons and Dragons combat (that is, models this process) and then run several hundred or thousand simulated fights and see who wins on average.</p>
<p>Here’s such a program written in Python: (<a href="http://inventwithpython.com/dnd_simulator.py">Download source</a>)</p>
<div class="hlcode" style="font-size: 120%">
<div class="syntax">
<pre><span class="kn">import</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">copy</span>
<span class="n">NUM_FIGHTS</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">VERBOSE</span> <span class="o">=</span> <span class="bp">True</span>
<span class="c"># Lower thac0 and lower ac values are better. Higher damage &amp; hp values are better.</span>
<span class="n">aliceTemplate</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;Alice&#39;</span><span class="p">,</span> <span class="s">&#39;hp&#39;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span> <span class="s">&#39;ac&#39;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&#39;thac0&#39;</span><span class="p">:</span> <span class="mi">18</span><span class="p">,</span> <span class="s">&#39;dmgnum&#39;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s">&#39;dmgsize&#39;</span><span class="p">:</span><span class="mi">6</span><span class="p">,</span> <span class="s">&#39;dmgmod&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
<span class="n">bobTemplate</span>   <span class="o">=</span> <span class="p">{</span><span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;Bob&#39;</span><span class="p">,</span>   <span class="s">&#39;hp&#39;</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s">&#39;ac&#39;</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span> <span class="s">&#39;thac0&#39;</span><span class="p">:</span> <span class="mi">16</span><span class="p">,</span> <span class="s">&#39;dmgnum&#39;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&#39;dmgsize&#39;</span><span class="p">:</span><span class="mi">4</span><span class="p">,</span> <span class="s">&#39;dmgmod&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
<span class="k">def</span> <span class="nf">display</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">VERBOSE</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">attack</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">attacker</span><span class="p">[</span><span class="s">&#39;thac0&#39;</span><span class="p">]</span> <span class="o">-</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;ac&#39;</span><span class="p">]:</span>
        <span class="n">damage</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">attacker</span><span class="p">[</span><span class="s">&#39;dmgnum&#39;</span><span class="p">]):</span>
            <span class="n">damage</span> <span class="o">+=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">attacker</span><span class="p">[</span><span class="s">&#39;dmgsize&#39;</span><span class="p">])</span>
        <span class="n">damage</span> <span class="o">+=</span> <span class="n">attacker</span><span class="p">[</span><span class="s">&#39;dmgmod&#39;</span><span class="p">]</span>
        <span class="n">display</span><span class="p">(</span><span class="s">&#39;</span><span class="si">%s</span><span class="s"> (</span><span class="si">%s</span><span class="s"> hp) hits </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s</span><span class="s"> hp) for </span><span class="si">%s</span><span class="s"> points of damage. </span><span class="si">%s</span><span class="s"> is reduced to </span><span class="si">%s</span><span class="s"> hp.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">attacker</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">],</span> <span class="n">attacker</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">],</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">],</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">],</span> <span class="n">damage</span><span class="p">,</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">],</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">-</span> <span class="n">damage</span><span class="p">))</span>
        <span class="n">defender</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">-=</span> <span class="n">damage</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">display</span><span class="p">(</span><span class="s">&#39;</span><span class="si">%s</span><span class="s"> misses </span><span class="si">%s</span><span class="s">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">attacker</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">],</span> <span class="n">defender</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]))</span>
<span class="n">aliceWins</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">bobWins</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">NUM_FIGHTS</span><span class="p">):</span>
    <span class="n">display</span><span class="p">(</span><span class="s">&#39;======================&#39;</span><span class="p">)</span>
    <span class="n">display</span><span class="p">(</span><span class="s">&#39;Start of combat #</span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span>
    <span class="n">alice</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">aliceTemplate</span><span class="p">)</span>
    <span class="n">bob</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">bobTemplate</span><span class="p">)</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">attack</span><span class="p">(</span><span class="n">alice</span><span class="p">,</span> <span class="n">bob</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">bob</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="n">attack</span><span class="p">(</span><span class="n">bob</span><span class="p">,</span> <span class="n">alice</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">alice</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">break</span>
    <span class="k">if</span> <span class="n">alice</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">display</span><span class="p">(</span><span class="s">&#39;Alice has died.&#39;</span><span class="p">)</span>
        <span class="n">bobWins</span> <span class="o">+=</span> <span class="mi">1</span>
    <span class="k">if</span> <span class="n">bob</span><span class="p">[</span><span class="s">&#39;hp&#39;</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">display</span><span class="p">(</span><span class="s">&#39;Bob has died.&#39;</span><span class="p">)</span>
        <span class="n">aliceWins</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Alice won </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s%%</span><span class="s">) fights. Bob won </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s%%</span><span class="s">) fights.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">aliceWins</span><span class="p">,</span> <span class="nb">round</span><span class="p">(</span><span class="n">aliceWins</span> <span class="o">/</span> <span class="n">NUM_FIGHTS</span> <span class="o">*</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="n">bobWins</span><span class="p">,</span> <span class="nb">round</span><span class="p">(</span><span class="n">bobWins</span> <span class="o">/</span> <span class="n">NUM_FIGHTS</span> <span class="o">*</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">2</span><span class="p">)))</span>
</pre>
</div>
</div>
<p>When you run this program, it produces output like this:</p>
<pre style="font-size: 120%">======================
Start of combat #1
Alice misses Bob.
Bob (12 hp) hits Alice (14 hp) for 6 points of damage. Alice is reduced to 8 hp.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice (8 hp) hits Bob (12 hp) for 5 points of damage. Bob is reduced to 7 hp.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob (7 hp) hits Alice (8 hp) for 2 points of damage. Alice is reduced to 6 hp.
Alice (6 hp) hits Bob (7 hp) for 6 points of damage. Bob is reduced to 1 hp.
Bob misses Alice.
Alice (6 hp) hits Bob (1 hp) for 1 points of damage. Bob is reduced to 0 hp.
Bob has died.
Alice won 1 (100.0%) fights. Bob won 0 (0.0%) fights.</pre>
<p>But maybe Alice just got lucky in this one fight. Let’s reprogram this program to turn off the verbose output (displaying text on the screen takes a lot more time than running the simulation) and up the number of fights to 30,000 (this is just changing the NUM_FIGHTS variable to 30000 and the VERBOSE variable to False):</p>
<pre style="font-size: 120%">Alice won 12909 (43.03%) fights. Bob won 17091 (56.97%) fights.</pre>
<p>So we can see that with the given stats, Bob is at a slight advantage. The computer just ran 30,000 simulated fights. If we were to play 30,000 fights of Dungeons and Dragons with pencil, paper, and physical dice, it would take months to calculate this. But my laptop had the results in less than 8 seconds.</p>
<p>But what if we increased Alice’s hit points from 14 to 20. Who would win then?</p>
<pre style="font-size: 120%">Alice won 19438 (64.79%) fights. Bob won 10562 (35.21%) fights.</pre>
<p>We see that those 6 extra hit points turns the tables and gives Alice the advantage. How about if her hit points were only increased to 16 instead of 20?</p>
<pre style="font-size: 120%">Alice won 15176 (50.59%) fights. Bob won 14824 (49.41%) fights.</pre>
<p>We see that just tweaking the stats by 2 hit points is just enough to even out the advantages that Bob gets from his higher level of damage.</p>
<p>And when you look at this program, <strong>the only math it uses is addition, subtraction, and multiplication and division to find a percentage</strong>. Even if we made the simulation more sophisticated to account for the effects of magic spells, healing potions, multiple attackers, and switching to different weapons in mid-combat, we wouldn’t need to know more math or have made good math grades to do the programming for it.</p>
<p>Sure, go ahead and learn more math. It can only help you become a better programmer. But how much math do you need to know to program? Very little, actually.</p>
<p><em>UPDATE: I guess I&#8217;d add basic algebra to the required knowledge, but only insofar as that if X * 3 = 12 knowing why X is 4.</em></p>
<p><em>(Here&#8217;s a list of other discussions on Reddit about this topic.)</em></p>
<ul style="font-size: 80%">
<li><a href="http://www.reddit.com/r/learnprogramming/comments/j7s8i/math_in_programming_im_concerned_that_i_should/">Math in programming &#8211; I&#8217;m concerned that I should give up trying (89 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/ngc81/is_there_hope_for_having_a_career_in_programming/">Is there hope for having a career in programming if I&#8217;m terrible at math? (50 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/qrbe8/what_areas_of_math_are_the_most_important_to/">What areas of math are the most important to computer science/programming? (26 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/m3kn3/why_is_discrete_math_so_important/">Why is Discrete Math so important? (20 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/i9j9n/how_much_math_do_you_need_to_become_a_good/">How much math do you need to become a good programmer? (20 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/r0iu6/is_it_possible_to_be_almost_ok_at_math_and_still/">Is it possible to be &#8220;almost ok&#8221; at math and still be a good desirable programmer? (13 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/pmv2n/should_i_brush_up_on_math/">Should I brush up on math? (10 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/pg4iu/this_may_be_the_dumbest_question_i_have_ever/">This may be the dumbest question I have ever posted online. How much math does one actually need to be a good programmer? (11 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/nv5lp/im_trying_to_learn_c_but_why_do_tutorials_always/">I&#8217;m trying to learn c++ but why do tutorials always have math problems? (7 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/nj60x/worth_while_improving_math_skills/">Worth while improving math skills? (8 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/l7b5c/what_math_courses_should_i_take_if_i_really_want/">What math courses should I take if I really want to delve into 3D? (15 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/i5kyd/what_is_a_better_supplement_to_a_bs_in_computer/">What is a better supplement to a BS in Computer Science? Math or Physics? (11 comments)</a></li>
<li><a href="http://www.reddit.com/r/learnprogramming/comments/bdwfq/the_importance_of_math_for_programming/">The importance of Math for Programming? (6 comments)</a></li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F03%2F18%2Fhow-much-math-do-i-need-to-know-to-program-not-that-much-actually%2F&amp;title=%E2%80%9CHow%20much%20math%20do%20I%20need%20to%20know%20to%20program%3F%E2%80%9D%20Not%20That%20Much%2C%20Actually." id="wpa2a_12"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/03/18/how-much-math-do-i-need-to-know-to-program-not-that-much-actually/feed/</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
		<item>
		<title>Nobody Wants to Learn How to Program</title>
		<link>http://inventwithpython.com/blog/2012/03/03/nobody-wants-to-learn-how-to-program/</link>
		<comments>http://inventwithpython.com/blog/2012/03/03/nobody-wants-to-learn-how-to-program/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 02:22:48 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=589</guid>
		<description><![CDATA[I frequently see a problem when people (especially techies) try to teach programming to someone (especially non-techies). Many programming tutorials begin with basic programming principles: variables, loops, data types. This is both an obvious way to teach programming and almost certainly a wrong way to teach programming. It’s wrong because nobody wants to learn how [...]]]></description>
			<content:encoded><![CDATA[<p>I frequently see a problem when people (especially techies) try to teach programming to someone (especially non-techies). Many programming tutorials begin with basic programming principles: variables, loops, data types. This is both an obvious way to teach programming and almost certainly a wrong way to teach programming. It’s wrong because nobody wants to learn how to program.</p>
<p>If you are teaching a class of adults who are paying with their own money for an education, then this is an appropriate and direct way to teach programming. It’s their money. They expect that they’ll have to focus and slug through concepts to come out the other end with programming knowledge. The start-with-variables-loops-data-types approach is fine for this. But most likely they still don’t want to learn how to program.</p>
<p>But for the casually interested or schoolchildren with several activities competing for their attention, programming concepts like variables and loops and data types aren’t interesting in themselves. They don’t want to learn how to program just for the sake of programming. They don’t want to learn about algorithm complexity or implicit casting. They want to make Super Mario or Twitter or Angry Birds. This idea is best summed up in one of <a href="http://www.qwantz.com/index.php?comic=1178">Ryan North’s Dinosaur comics</a> (click to enlarge):</p>
<p><a href="http://inventwithpython.com/images/dinosaurcomics.png"><img src="http://inventwithpython.com/images/dinosaurcomics.png" width=300></a></p>
<p>Here are my five pieces of advice to people who want to teach programming or create programming tutorials:<br />
<span id="more-589"></span></p>
<h2>1. Kits Are Not Programming</h2>
<p>If you make the realization that nobody wants to learn how to program and jump past that trap, there’s a second brick wall on the other extreme you might hit: software creation kits. This is especially notorious with drag-and-drop game creation kits. In trying to make it programming easy to do and abstract away details, these kits end up getting rid of, well, programming. (Although there’s no end to products that claim to let you create applications <a href="http://www.google.com/search?q=%22without+any+programming%22">without any programming at all.</a>)</p>
<p>But people can feel the limitations that these programs have. Many of these kits are good for creating a certain class of applications or certain genre of games, but have a restricted reach because they aren’t flexible enough. We need legos, not playsets.</p>
<p>(I enthusiastically endorse <a href="http://scratch.mit.edu">Scratch</a> for use by the pre-teen crowd, especially since typing can be a large barrier to programming for that age group. Scratch rides the kit/programming line very well. GameMaker, RPGMaker, and other kits, not so much.)</p>
<h2>2. Toy Examples Are Fine, As Long As They Are Braggable</h2>
<p>Almost every programming book and tutorial has examples, but these are usually code snippets to demonstrate a single function or concept. Breaking down learning material to single concepts and providing a simple example. This is an obvious way to teach programming, but nobody wants to learn programming.</p>
<p>The main examples in my book, <a href="http://inventwithpython.com">“Invent Your Own Computer Games with Python”</a> (free to read under Creative Commons at <a href="http://inventwithpython.com">http://inventwithpython.com</a>) present the complete source code to simple games like “Guess the Number” and “Tic Tac Toe”, and then explain how these programs work. A small amount of programming concepts had to be taught at the start and some single-concept examples are given, but the chapter always centers around a complete game.</p>
<p>The first few game programs are all under 50 lines long, but this is fine because they are still complete programs. This isn’t something they can make money off of in an appstore, but the standards for something neat enough to show someone else are much lower. By leading with complete programs and then explaining the programming concepts that go into them, you give the learner a reason to continue learning.</p>
<p>As a result of what code goes into each game program, programming concepts in “Invent with Python” are given in an unorthodox order sometimes. That’s fine. Beginning programmers don’t realize they’re learning concepts in a weird order and don’t care as long as the learning material makes sense. If you are creating tutorials for self-directed learners, they’re going to learn in a non-linear manner anyway.</p>
<h2>3. Beginner Programmers Are Plagiarists (So Give Them A Lot To Plagiarize)</h2>
<p>I began learning BASIC in the third grade. This might sound impressive to people who think that only the highly intelligent can learn to program computers. The thing is, all of my programs for the next several years were just slightly-modified copies of the same two or three types of programs I had already seen. They were mostly print and if statements with a few random numbers thrown in.</p>
<p>Newbies’ programs bear a lot of resemblance to the programs they’ve already seen because they don’t have enough experience to know how to take an original idea and deconstruct the code needed to make it. So help them along by giving them several different examples. (“Invent with Python” has simple “coin toss” guessing games, games that manipulate strings such as Hangman and Bagels, games that use 2D Cartesian coordinates, and a small encryption program).</p>
<p>It’s okay if they don’t completely understand how a program works after they’ve played with it a little. Very few ideas are completely original. The more material you give your students to plagiarize, the wider the range of derivative works they’ll make from them.</p>
<h2>4. My Programs, Let Me Show You Them</h2>
<p>One thing that MIT’s Scratch programming environment gets right is that they have a way to share programs that students create built into the software directly. Nobody wants to learn programming, they want to make cool programs. Being able to easily share their programs with a community not only provides an incentive to learn and create, but it also provides a library of examples for other people to look at to inspire their own programs. The Pygame.org website has a sidebar that is constantly updated with people’s submitted games (source included), which supplies that community with hundreds of examples to learn from. I’d say this is a major factor for Pygame’s popularity over Pyglet and other Python game frameworks.</p>
<h2>5. Don’t Distract New Programmers with OOP</h2>
<p><a href="http://prog21.dadgum.com/93.html">Enough said.</a> Things you can also toss out for the new programmer syllabus: recursion, regular expressions, MVC, networking, and file I/O. These things can come much, much later after they’ve made a few programs on their own.</p>
<p>If you are teaching programming, remember that nobody gets excited over remembering to put semicolons at the end of a line. Nobody wants to learn programming, they want to learn how to make programs.</p>
<hr />
<h2>UPDATE:</h2>
<p>Zed Shaw (author of the great book &#8220;Learn Python the Hard Way&#8221;) left this comment on Hacker News:</p>
<p><emphasis>&#8220;And no, I&#8217;m saying it&#8217;s a huge myth that nobody wants to learn the &#8220;hard stuff&#8221;. They do, you just have to teach it right. After that you just have people who aren&#8217;t interested in programming at all and no amount of graphics, games, or cute cartoons is going to make them want to. You can&#8217;t force or trick enlightenment on people.</p>
<p>But more importantly, I have evidence to back my beliefs. This article has absolutely no evidence.&#8221;</emphasis></p>
<p>He brings up a good point. Here&#8217;s my response:</p>
<p><emphasis>&#8220;Hi Zed, I&#8217;m Al, the author of article. I&#8217;ll admit the title is hyperbole. There are people who want to learn programming for the sake of programming, just like there are people who like learning math even though they don&#8217;t see immediate practical applications.</p>
<p>I teach programming to a tiny class of 10-12 year olds on Saturday mornings, and have taught a couple one-off classes at Stanford&#8217;s Splash program to a classes of a dozen students. I&#8217;ve found that having an end-goal in mind of what they will create is a much better hook than just explaining what for loops are (or the idiosyncrasies of the languages are, which Python &#038; Ruby are good about keeping to a minimum.)</p>
<p>I don&#8217;t think graphics and cute cartoons are needed to make programming engaging either. My book &#8220;Invent with Python&#8221; has games that use ascii text up until the last few chapters. There&#8217;s a pretty low standard for games/programs that are cool enough to show off to other people, but nobody ever shows off code snippets.</p>
<p>I think the best thing about &#8220;Learn Python the Hard Way&#8221; over a book like O&#8217;Reilly&#8217;s &#8220;Learning Python&#8221; is that your book cuts it down to the bare concepts: &#8220;Type this. This should appear. This is what is happening.&#8221; That&#8217;s great compared to most computer books where there are paragraphs upon paragraphs that could be whittled down to a single sentence or cut out entirely. &#8220;Learn Python the Hard Way&#8221; is barely over 200 pages. That&#8217;s much more digestible than some 600 page tome.</p>
<p>I just think that many classes where the students aren&#8217;t CS majors or necessarily dedicated to learning programming forget that it&#8217;s not just the concepts that people want to learn but what they can make using those concepts. Small games and web apps are great for that. Like in Exercise 22 of your book says, &#8220;It’s important when you are doing a boring mindless memorization exercise like this to know why. It helps you focus on a goal and know the purpose of all your efforts.&#8221;"</emphasis></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F03%2F03%2Fnobody-wants-to-learn-how-to-program%2F&amp;title=Nobody%20Wants%20to%20Learn%20How%20to%20Program" id="wpa2a_14"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/03/03/nobody-wants-to-learn-how-to-program/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>&#8220;I Need Practice Programming&#8221;: 49 Ideas for Game Clones to Code</title>
		<link>http://inventwithpython.com/blog/2012/02/20/i-need-practice-programming-49-ideas-for-game-clones-to-code/</link>
		<comments>http://inventwithpython.com/blog/2012/02/20/i-need-practice-programming-49-ideas-for-game-clones-to-code/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 21:57:57 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=559</guid>
		<description><![CDATA[So you know a little bit about programming (perhaps you&#8217;ve read the free book, &#8220;Invent Your Own Computer Games with Python&#8221;, a free programming book for beginners whose author shamelessly plugs at every chance) but you want to get better at coding. You can&#8217;t seem to find any open source projects that are at your [...]]]></description>
			<content:encoded><![CDATA[<p>So you know a little bit about programming (perhaps you&#8217;ve read the free book, <a href="http://inventwithpython.com/">&#8220;Invent Your Own Computer Games with Python&#8221;</a>, a free programming book for beginners whose author shamelessly plugs at every chance) but you want to get better at coding. You can&#8217;t seem to find any open source projects that are at your level or easy for new people to contribute to. You&#8217;ve gone through a few of the practice problems at <a href="http://projecteuler.net/">Project Euler</a> but you want to create something more substantial, or at least a cool thing you can show your friends. (Not that finding the 31337th prime number isn&#8217;t cool.)</p>
<p>Here&#8217;s a list of game clone ideas for you to implement. Each has a short description of the game, links to videos of the game, and descriptions of what kind of algorithms you&#8217;ll need to know in order to implement them. <strong>These games have been selected for their simplicity</strong>, so you don&#8217;t have to spend several weeks designing art, levels, scripted dialogue, or complicated AI. These are clones designed to be doable in roughly a weekend. A Mario or Zelda clone would be complicated to put together, but a Tetris or Asteroids clone would be doable in a weekend.</p>
<h2 id="orisinal">Orisinal Games:</h2>
<p><a href="http://inventwithpython.com/images/orisinal_tea.jpg"><img src="http://inventwithpython.com/images/orisinal_tea.jpg" width="200" /></a></p>
<p>The Orisinal website has a great collection of Flash games with very simple mechanics that can be copied. <a href="http://www.ferryhalim.com/orisinal/">http://www.ferryhalim.com/orisinal/</a></p>
<p>I especially recommend <a href="http://www.ferryhalim.com/orisinal/g3/bells.htm">Winter Bells</a>, <a href="http://www.ferryhalim.com/orisinal/g3/tea.htm">A Daily Cup of Tea</a>, <a href="http://www.ferryhalim.com/orisinal/g3/bugs.htm">Bugs</a>, and <a href="http://www.ferryhalim.com/orisinal/g2/rope.htm">Hold the Rope!</a></p>
<p>The Wikipedia entry for <a href="http://en.wikipedia.org/wiki/Video_game_clone#Notable_cloned_games">video game clones</a> also lists some ideas.</p>
<h2>Games from &#8220;Invent Your Own Computer Games with Python&#8221; and &#8220;Making Games with Python &#038; Pygame&#8221; books:</h2>
<p>These games are described in these free Python programming books and their source code is available. However, you can make your own variants.</p>
<h2 id="dodger">1. Dodger</h2>
<p><a href="http://inventwithpython.com/images/20-1.png"><img src="http://inventwithpython.com/images/20-1.png" width="200" /></a></p>
<p><strong>Description:</strong> Several bad guys fall from the top of the screen, and the user must avoid them. The player can be controlled with the arrow keys or more directly with the mouse. The longer the player lasts without being hit, the higher the score.</p>
<p><strong>Variations:</strong> Have enemies fall at different rates and be different sizes. Have enemies fall from more than one side of the game. Have power up pickups that grant invulnerability for a while, slow down bad guys, give the player a temporary &#8220;reverse bad guys&#8221; power, etc.</p>
<p>This game is covered in <a href="http://inventwithpython.com/chapter20.html">Chapter 20 of &#8220;Invent with Python&#8221;</a></p>
<p><a href="http://inventwithpython.com/dodger.zip">Download Source: dodger.zip</a></p>
<h2 id="memorypuzzle">2. Memory Puzzle</h2>
<p><a href="http://inventwithpython.com/images/memory_screenshot.png"><img src="http://inventwithpython.com/images/memory_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> A board full of overturned cards. There is a pair for each card. The player flips over two cards. If they match, then they stay overturned. Otherwise they flip back. The player needs to overturn all the cards in the fewest moves to win.</p>
<p><strong>Variations:</strong> Provide &#8220;hints&#8221; in the form of four possible matching cards after the player flips the first one. Or, quickly overturn groups of cards at the beginning of the game.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter1.html">Chapter 1 of &#8220;Making Games with Python &#038; Pygame&#8221;</a></p>
<p><a href="http://inventwithpython.com/memorypuzzle.py">Download Python Source: memorypuzzle.py</a></p>
<p><span id="more-559"></span></p>
<h2 id="slidingpuzzle">3. Sliding Puzzle</h2>
<p><a href="http://inventwithpython.com/images/slidepuzzle_screenshot.png"><img src="http://inventwithpython.com/images/slidepuzzle_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> A 4&#215;4 board of numbered tiles has one missing space and is randomly set up. To win the game, the player must slide tiles over to put the tiles back in order.</p>
<p><strong>Variants:</strong> Instead of numbers, you can have a scrambled picture cut up into 4&#215;4 tiles.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter4.html">Chapter 4 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/slidepuzzle.py">Download Python Source: slidepuzzle.py</a></p>
<h2 id="simon">4. Simon</h2>
<p><a href="http://inventwithpython.com/images/simulate_screenshot.png"><img src="http://inventwithpython.com/images/simulate_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> Four colored buttons light up in a specific pattern. After displaying the pattern, the player must repeat the pattern by clicking the buttons in proper order. The pattern gets longer each time the player completes the pattern. If the player presses a wrong button, the game ends.</p>
<p>Variant: A nine-button version can add challenge to this game (but more than that would probably just be tedious.)</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter5.html">Chapter 5 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/simulate.py">Download Pyhton Source: simulate.py</a></p>
<h2 id="nibbles">5. Nibbles</h2>
<p><a href="http://inventwithpython.com/images/snakey_screenshot.png"><img src="http://inventwithpython.com/images/snakey_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> A worm or snake constantly moves around the board. The player controls the direction the &#8220;head&#8221; of the worm moves, and the worm must try to eat apples that randomly appear. Eating an apply causes the worm to grow in length. The game ends if the worm crashes into the edge of the board or into itself.</p>
<p><strong>Variants:</strong> Add walls to the level, instead of just a blank rectangle. Add power ups that the worm can pick up. Add bad guys that move around the board that the worm must avoid. Have two worms that the player must control simultaenously. Tron (see below) is a two-player variant of this game.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter6.html">Chapter 6 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/wormy.py">Download Python Source: wormy.py</a></p>
<h2 id="tetris">6. Tetris</h2>
<p><a href="http://inventwithpython.com/images/tetromino_screenshot.png"><img src="http://inventwithpython.com/images/tetromino_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> Shapes made up of four blocks fall from the top of the board. The player must rotate and place them to create full rows with no gaps. When a full row is made, the blocks in that row disappear and the blocks above it move down. The game ends if the board fills up.</p>
<p>Variant: Several Tetris variants are listed on Wikipedia. <a href="http://en.wikipedia.org/wiki/List_of_Tetris_variants">http://en.wikipedia.org/wiki/List_of_Tetris_variants</a></p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter7.html">Chapter 7 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/tetromino.py">Download Python Source: tetromino.py</a></p>
<h2 id="katamaridamacy">7. Katamari Damacy</h2>
<p><a href="http://inventwithpython.com/images/squirrel_screenshot.png"><img src="http://inventwithpython.com/images/squirrel_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> The original Katamari Damacy game was in a 3d world, but a 2d version is also easy to implement. The player controls a small object in a world of different-sized objects. Touching the smaller objects grows the player, touching the larger objects damages or shrinks the player. The player wins when they reach a certain size.</p>
<p><a href="http://dagobah.net/flash/katamari.swf">A flash version of 2D Katamari is available.</a></p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter8.html">Chapter 8 of &#8220;Making Games with Python &#038; Pygame&#8221;</a></p>
<p><a href="http://inventwithpython.com/squirrel.zip">Download Source: squirrel.zip</a></p>
<h2 id="sokoban">8. Sokoban</h2>
<p><a href="http://inventwithpython.com/images/starpusher_screenshot1.jpg"><img src="http://inventwithpython.com/images/starpusher_screenshot1.jpg" width="200" /></a></p>
<p><strong>Description:</strong> The player is in a level with objects that need to be pushed over goals. The objects can only be pushed, they can&#8217;t be pulled. This game does require some effort to design levels for, but Sokoban levels have been <a href="http://users.bentonrea.com/~sasquatch/sokoban/">designed by others and published on the web</a>.</p>
<p>Variant: Add all sorts of level gimmicks: teleport tiles, conveyor belts, buttons that open doors/bridges, buttons that need an object left on them to keep a door open.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter9.html">Chapter 9 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/starpusher.zip">Download Source: starpusher.zip</a></p>
<h2 id="othello">9. Othello</h2>
<p><a href="http://inventwithpython.com/images/flippy_screenshot.png"><img src="http://inventwithpython.com/images/flippy_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> On a grid, a black and white player places tiles of their color on the board. The opponent&#8217;s tiles between the newly placed tile and that player&#8217;s existing tiles are flipped to become the color of the player&#8217;s tiles. The game ends when the board fills up and the player with the most tiles of their color wins.</p>
<p>Variant: Three player Othello with three different colors. Non-square boards.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter10.html">Chapter 10 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/flippy.zip">Download Source: flippy.zip</a></p>
<h2 id="floodit">10. Flood It</h2>
<p><a href="http://inventwithpython.com/images/inkspill_screenshot2.png"><img src="http://inventwithpython.com/images/inkspill_screenshot2.png" width="200" /></a></p>
<p><strong>Description:</strong> A grid of six colors of tiles starts off randomly. The player can do a &#8220;flood fill&#8221; on the top left tile, changing the color of any adjacent tiles of thesame color. The player wins if they are able to make the entire board a single color within a certain number of moves.</p>
<p><strong>Variants:</strong> Power ups gained when a certain tile is changed.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter10.html">Chapter 10 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/inkspill.zip">Download Source: inkspill.zip</a></p>
<h2 id="connectfour">11. Connect Four</h2>
<p><a href="http://inventwithpython.com/images/fourinarow_screenshot.png"><img src="http://inventwithpython.com/images/fourinarow_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> Two players of different colors drop their tokens on an upright board. The player to make four tokens in a row, column, or diagonal wins. Creating an AI for this requires a simple <a href="http://en.wikipedia.org/wiki/Minimax">minimax algorithm</a>.</p>
<p>Variant: Different board sizes. Walls inside the board that appear when the spaces beneath them are filled.</p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter10.html">Chapter 10 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/fourinarow.zip">Download Source: fourinarow.zip</a></p>
<h2 id="bejeweled">12. Bejeweled</h2>
<p><a href="http://inventwithpython.com/images/gemgem_screenshot.png"><img src="http://inventwithpython.com/images/gemgem_screenshot.png" width="200" /></a></p>
<p><strong>Description:</strong> The board is filled with seven different types of jewels. The player can swap two adjacent jewels to form a three-in-a-row, causing the jewels to disappear and the jewels on top of them to fall down. Creating chain reactions gives bonus points.</p>
<p>Variant: Different power ups for matching a particular jewel. Be able to sometimes swap jewels that are not adjacent to each other. Timed games.</p>
<p>The original Bejeweled game and its sequels are at <a href="http://www.bejeweled.com/">http://www.bejeweled.com/</a></p>
<p>This game is covered in <a href="http://inventwithpython.com/pygame/chapter10.html">Chapter 10 of &#8220;Making Games with Python &#038; Pygame&#8221;</a>.</p>
<p><a href="http://inventwithpython.com/gemgem.zip">Download Source: gemgem.zip</a></p>
<h2>Board Games:</h2>
<p>Board games are a good source for game clone ideas. A game like Monopoly has far too many rules to put together in a short time frame, but here&#8217;s a list of board games that have simple mechanics. Chess, Go, and Stratego may be too complicated to create an AI opponent, but in that case you can just make it a two-player game. These games don&#8217;t really have variants, </p>
<h2 id="mancala">13. Mancala</h2>
<p><a href="http://inventwithpython.com/images/mancala.jpg"><img src="http://inventwithpython.com/images/mancala.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=9Zvjk-OEtsw">YouTube video showing gameplay.</a> <a href="http://en.wikipedia.org/wiki/Mancala#General_gameplay">Mancala rules</a></p>
<p><strong>Description:</strong> <a href="http://en.wikipedia.org/wiki/Mancala">A stone capture game</a> where the board is made up of 12 pits and a &#8220;score pit&#8221; that the player tries to move their stones into. A simple minimax algorithm can be used by the AI.</p>
<p><strong>Variants:</strong> Wikipedia has <a href="http://en.wikipedia.org/wiki/List_of_mancala_games">a list of &#8220;mancala games&#8221;</a>.</p>
<p><a href="http://www.pygame.org/project-pyAwale-464-3779.html">Source code for Awale, a Mancala variant.</a></p>
<h2 id="tictactoe">14. Tic-tac-toe</h2>
<p><a href="http://en.wikipedia.org/wiki/Tic_tac_toe">Wikipedia page explaining rules.</a></p>
<p><strong>Description:</strong> Players put down their X or O symbol on a 3&#215;3 board and try to get three in a row.</p>
<p><strong>Variants:</strong> Using a 3x3x3 board for 3D Tic-tac-toe. Wikipedia has a <a href="http://en.wikipedia.org/wiki/Tic_tac_toe#Variations">list of variations</a>.</p>
<h2 id="quarto">15. Quarto</h2>
<p><a href="http://inventwithpython.com/images/quarto.jpg"><img src="http://inventwithpython.com/images/quarto.jpg" width="200" /></a></p>
<p><a href="http://en.wikipedia.org/wiki/Quarto_(board_game)">Quarto rules</a> <a href="http://www.youtube.com/watch?v=8yMqxUKQgkI">YouTube video explaining the rules</a></p>
<p><strong>Description:</strong> Two players take turns setting one of the 16 pieces which is either: tall/short, light/dark, square/circular, and hollow/solid. The goal is to get four in a row of a common trait.</p>
<p><strong>Variants:</strong> You can increase the board size and the number of types of pieces.</p>
<h2 id="abalone">16. Abalone</h2>
<p><a href="http://inventwithpython.com/images/abalone.jpg"><img src="http://inventwithpython.com/images/abalone.jpg" width="200" /></a></p>
<p><a href="http://en.wikipedia.org/wiki/Abalone_(board_game)#Gameplay">Wikipedia page with game rules.</a> <a href="http://www.youtube.com/watch?v=zIwLPGkpuiA">YouTube video explaining the rules.</a></p>
<p><strong>Description:</strong> Players move their marbles around a hexagonal board, trying to be the first to push six of the opponent&#8217;s marbles off the edge of the board.</p>
<h2 id="quoridor">17. Quoridor</h2>
<p><a href="http://inventwithpython.com/images/quoridor.gif"><img src="http://inventwithpython.com/images/quoridor.gif" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=zrIiWN4cnxg">YouTube video explaining the Quoridor rules</a></p>
<p><strong>Description:</strong> Two players try to move their token to the other side of the board. On their turn, they can either move their token one space or place a wall on the board. A player cannot completely seal in the other player with a wall. An AI for this game may be too complex, but a two-player version should be simple to implement.</p>
<p><strong>Variants:</strong> See Minotaurus, the next game.</p>
<h2 id="minotaurus">18: Minotaurus</h2>
<p><a href="http://www.youtube.com/watch?v=5tNkPuYveXw">YouTube video showing gameplay.</a></p>
<p><strong>Description:</strong> This game is essentially a more complex and multiplayer version of Quoridor, with a &#8220;Minotaur&#8221; monster added in that can attack players.</p>
<p><strong>Variants:</strong> Add different level/wall designs instead of the standard board. Add teleports, or buttons that can activate doors and bridges.</p>
<h2 id="stratego">19: Stratego</h2>
<p><a href="http://inventwithpython.com/images/stratego.jpg"><img src="http://inventwithpython.com/images/stratego.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=9_-dabt0ee8">YouTube video explaining the rules and demonstrating gameplay.</a> <a href="http://en.wikipedia.org/wiki/Stratego#Gameplay">Wikipedia page explaining rules.</a></p>
<p><strong>Description:</strong> Two players set up army units on the board and try to determine the strength of their opponent&#8217;s units. Disinformation is an important aspect of the game.</p>
<h2 id="blackjack">20: Blackjack</h2>
<p><a href="http://en.wikipedia.org/wiki/Blackjack">Rules of Blackjack</a></p>
<p><strong>Description:</strong> Blackjack is a classic card game that is simple enough to implement a dealer AI for.</p>
<p><strong>Variants:</strong> Variants of Blackjack are <a href="http://en.wikipedia.org/wiki/Blackjack#Variants_of_the_game">listed on the Wikipedia page.</a></p>
<h2 id="scrabble">21: Scrabble</h2>
<p><a href="http://www.youtube.com/watch?v=swlg3vQXboE&#038;t=5s">YouTube video explaining the rules</a></p>
<p><strong>Description:</strong> Player form words from letter tiles on a board. Rare letters are worth more points. Some spaces on the board give letter or word bonuses. You will need a dictionary file for this program, which you can download from <a href="http://wordlist.sourceforge.net/">http://wordlist.sourceforge.net/</a>.</p>
<p><strong>Variants:</strong> There are too many to list here. <a href="http://en.wikipedia.org/wiki/Scrabble_variants">See the Wikipedia entry for Scrabble Variants.</a></p>
<h2 id="gridlock">22: Grid Lock / Traffic Jam</h2>
<p><a href="http://inventwithpython.com/images/gridlock.jpg"><img src="http://inventwithpython.com/images/gridlock.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=6sDl_MiivqU&#038;t=7s">YouTube video showing gameplay.</a></p>
<p><strong>Description:</strong> The player must slide a target car through an exit, but other cars are blocking the way. Cars can only be moved vertically or horizontally depending on their starting orientation. Level designs can be copied from existing games.</p>
<h2 id="yahtzee">23: Yahtzee</h2>
<p><a href="http://en.wikipedia.org/wiki/Yahtzee#Rules_overview">Yahtzee rules explained.</a></p>
<p><strong>Description:</strong> Dice rolling game where the players try to achieve specific patterns of rolls.</p>
<p><strong>Variants:</strong> Variants are listed <a href="http://en.wikipedia.org/wiki/Yahtzee#Similar_games">on the Wikipedia page</a>.</p>
<h2 id="risk">24: Risk</h2>
<p><a href="http://inventwithpython.com/images/dicewars.jpg"><img src="http://inventwithpython.com/images/dicewars.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=5oMPUE0fc34&#038;t=1m50s">YouTube video of Dicewars gameplay.</a></p>
<p><strong>Description:</strong> Each territory has a certain number of armies which can be used to attack adjacent territories. The player can attack as often as they want, but conquering too many territories stretches out their troops so that the territories can be reclaimed easily. Additional armies are given based on conquered territories, so not expanding fast enough will also lead to losing. A straight forward AI is relatively easy to produce.</p>
<p><strong>Variants:</strong> <a href="http://www.gamedesign.jp/flash/dice/dice.html">Dice Wars</a> is a high-speed Flash game that is similar to Risk.</p>
<h2 id="checkers">25: Checkers / Draughts</h2>
<p><a href="http://www.youtube.com/watch?v=urxaeIn6lFo">YouTube link of a Checkers game.</a></p>
<p><strong>Description:</strong> A player moves their pieces diagonally on a board and tries to &#8220;jump&#8221; the opponent&#8217;s pieces.</p>
<p><strong>Variants:</strong> Some variants are listed <a href="http://en.wikipedia.org/wiki/Draughts#Invented_variants">on the Wikipedia page for Draughts</a>.</p>
<h2 id="chess">26: Chess</h2>
<p><strong>Description:</strong> Chess is a classic game, and <a href="http://en.wikipedia.org/wiki/Chess#Rules">the rules are explained on Wikipedia</a>.</p>
<p><strong>Variants:</strong> Some variants are listed <a href="http://en.wikipedia.org/wiki/Chess_variant">on the Wikipedia page for Chess Variants</a>.</p>
<h2 id="go">27: Go</h2>
<p><a href="http://en.wikipedia.org/wiki/Go_(game)#Rules">Rules explained</a> <a href="http://www.youtube.com/watch?v=I_Ij-xhr_w0&#038;t=39s">YouTube video show</a></p>
<p><strong>Description:</strong> Players take turns laying down stones and try to capture areas of the board. See the rules for full details. Even simple Go-playing AIs require deep levels of knowledge, but a two-player game is easy to create.</p>
<h2>Action Games:</h2>
<h2 id="asteroids">28: Asteroids</h2>
<p><a href="http://www.youtube.com/watch?v=okRZNrqPjUk">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> The player rotates a ship to shoot asteroids, which break into two smaller asteroids when hit. The player must avoid being hit by the asteroids which slowly move around the screen. The player has no brakes, and can only slow or stop by using thrust in the opposite direction they are traveling.</strong> </p>
<p><strong>Variants:</strong> Having different weapons and an occasional UFO that shoots directly at the player.</strong> </p>
<h2 id="spaceinvaders">29: Space Invaders</h2>
<p><a href="http://www.youtube.com/watch?v=ccJQ8TxzS_A">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A few rows of enemies gradually makes they&#8217;re way down to the player. The player must shoot them all before they reach the bottom.</strong> </p>
<h2 id="tron">30: Tron</h2>
<p><a href="http://www.youtube.com/watch?v=3SsRP2_fr3w">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Players control a constantly moving object that leaves a trail of walls behind it. The player who avoids crashing into a wall longest wins.</p>
<p><strong>Variants:</strong> </p>
<h2 id=""missilecommand>31: Missile Command</h2>
<p><a href="http://inventwithpython.com/images/missilecommand.gif"><img src="http://inventwithpython.com/images/missilecommand.gif" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=D_14fDNdbTc">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Missiles are shot up from the ground to hit falling meteors before they hit cities. The missiles must be timed so that they reach their target at the same time that the meteor is there.</p>
<p><strong>Variants:</strong> See Rampart below. Different weapon types (the kind used in Scorched Earth) are also possible.</p>
<p><a href="http://www.pygame.org/project-Patriot+Command-1394-2708.html">Python source code</a></p>
<h2 id="pong">32: Pong</h2>
<p><a href="http://www.youtube.com/watch?v=it0sf4CMDeM&#038;t=43s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A tennis game where players bounce a ball passed the other.</p>
<p><strong>Variants:</strong> Several of the same variations found in Arkanoid can be used in Pong. Obstacles can be placed on the map instead of just an open field.</p>
<h2 id="arkanoid">33: Arkanoid</h2>
<p><a href="http://inventwithpython.com/images/arkanoid.png"><img src="http://inventwithpython.com/images/arkanoid.png" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=VhFkfaI4RTo&#038;t=14s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> The player controls a paddle that bounces a ball off of bricks in the level. The bricks break when the ball bounces off of them. The level is cleared when all the bricks are destroyed.</p>
<p><strong>Variants:</strong> Power ups fall from smashed blocks, including: triple ball, longer paddle, ball breaks through bricks, a laser shoots out from the paddle.</p>
<p><a href="http://www.pygame.org/project-Arkanoid-1422-.html">Python source</a>, <a href="http://www.pygame.org/project-Pyarkanoid+(BSG+Arkanoid)-1474-2631.html">another Python source</a>, <a href="http://www.pygame.org/projects/20/250/">and another</a>, <a href="http://www.pygame.org/project-Brickout-1786-3109.html">and another.</a></p>
<h2 id="maze">34: Maze</h2>
<p><a href="http://en.wikipedia.org/wiki/Maze_generation_algorithm">Wikipedia entry on Maze Generation Algorithms</a></p>
<p><strong>Description:</strong> Player runs through a maze to the exit. This is more of an exercise in writing maze-generation algorithms.</p>
<p><strong>Variants:</strong> Teleports, buttons to control doors, keys to unlock doors, having multiple characters to move around that must work in sync to unblock each other&#8217;s paths.</p>
<p><a href="http://www.pygame.org/project-Bipo+Maze-2159-.html">Python source code</a>, <a href="http://www.pygame.org/project-labyrinthe-1511-.html">and another</a>.</p>
<h2 id="scorchedearth">35: Scorched Earth / Worms / Gorillas / Angry Birds</h2>
<p><a href="http://inventwithpython.com/images/scorchedearth.gif"><img src="http://inventwithpython.com/images/scorchedearth.gif" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=Io3LjftP6YQ">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Players control tanks on a 2D hilly terrain and enter the numeric angle and velocity of a cannonball shot. The object is hit the other player&#8217;s tanks.</p>
<p><strong>Variants:</strong> Angry Birds is a version of this game that adds a physics engine instead of hills. Different weapon types besides the standard cannonball can be added. Several UI improvements can be made over the original game (using the mouse to enter the angle and velocity, displaying the previous turn&#8217;s angle and velocity, etc.) Destructible terrain and being able to move the tanks adds a new dimension to the game.</p>
<h2 id="lunarlander">36: Lunar Lander</h2>
<p><a href="http://inventwithpython.com/images/lunarlander.png"><img src="http://inventwithpython.com/images/lunarlander.png" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=NyAT9ot7Nu4&#038;t=59s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> The player controls a ship that must gently land on a flat surface of the moon. The ship has limited fuel, and using the thrusters affects the momentum of the ship (much like Asteroids).</p>
<h2 id="snood">37: Snood / Bust-a-Move</h2>
<p><a href="http://inventwithpython.com/images/bustamove.jpg"><img src="http://inventwithpython.com/images/bustamove.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=1446Bag4OzA">YouTube video showing gameplay of Snood</a> <a href="http://www.youtube.com/watch?v=PrEbsvWM3Jo&#038;t=24s">YouTube video showing gameplay of Bust-a-Move</a></p>
<p><strong>Description:</strong> The top of the board is filled with different colored bubbles. The player must shoot bubbles from the bottom to form a set of three bubbles of the same color in a row to make them disappear. The ceiling lowers over time. The player wins if the board is cleared of bubbles, and loses if the bubbles reach the bottom.</p>
<p><strong>Variants:</strong> This is a similar game to Bejeweled, and the power ups used in that game could be used in this one.</p>
<h2 id="fruitninja">38: Fruit Ninja</h2>
<p><a href="http://www.youtube.com/watch?v=-tBCqkzpm7U&#038;t=28s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Objects are thrown up over the screen and the player must drag the mouse over them.</p>
<p><strong>Variants:</strong> Bonuses for combos. Some objects cause the player to lose if they are touched.</p>
<h2 id="laststand">39: Last Stand</h2>
<p><a href="http://inventwithpython.com/images/laststand.jpg"><img src="http://inventwithpython.com/images/laststand.jpg" width="200" /></a></p>
<p><a href="http://www.newgrounds.com/portal/view/375622">Link to the original Flash game</a></p>
<p><strong>Description:</strong> On each round, a wave of zombies attacks a barricade while the player shoots from behind it. Several shots are needed to kill a zombie and accuracy counts. When the zombies reach the barricade they begin to damage it. The player loses if the barricade is destroyed. After each round, the player can spend actions on finding new weapons, finding other survivors to help defend, or repairing the barricade.</p>
<p><strong>Variants:</strong> Different zombie types (armored, fast moving-dog zombies, etc.) and weapons can be used (mines, grenades, traps).</p>
<h2 id="duckhunt">40: Duck Hunt</h2>
<p><a href="http://www.youtube.com/watch?v=Cx5XGOQVx-4">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Ducks fly around the screen and the player must click on them to shoot them. The player has limited ammo.</p>
<p><strong>Variants:</strong> The flight patterns of the ducks/objects can be changed.</p>
<h2 id="rampart">41: Rampart</h2>
<p><a href="http://inventwithpython.com/images/rampart.jpg"><img src="http://inventwithpython.com/images/rampart.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=PLR9yxIV8DQ&#038;t=17">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> The player alternates between building fortifications (to house cannons) and shooting at incoming ships. This game is similar to Missile Command, with a building mechanic added in.</p>
<p><strong>Variants:</strong> Different enemy types (slow moving, armored ships or fast moving airplanes) and weapons can be added. Add different strength walls to build.</p>
<h2 id="bloxorz">42: Bloxorz</h2>
<p><a href="http://inventwithpython.com/images/bloxorz.jpg"><img src="http://inventwithpython.com/images/bloxorz.jpg" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=MEaisV4MNlY&#038;t=16">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A puzzle game where the player must roll over a 2&#215;1 brick to an exit point on the map. The brick cannot be moved off the edge of the board, and since it can only be flipped end over end and not slid around, the 2&#215;1 nature restricts the types of moves it can make.</p>
<h2 id="drmario">43: Dr. Mario</h2>
<p><a href="http://www.youtube.com/watch?v=3ziH6tVJwEU&#038;t=21s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A Tetris-like game where two-colored pills fall on different colored germs. Forming four in a row of the same color germ/pills causes them to disappear. The player wins when all the germs are cleared from the board, and loses if the pills fill up the board.</p>
<p><strong>Variants:</strong> Similar to Puyo Puyo.</p>
<h2>44: Kirby&#8217;s Avalanche / Puyo Puyo</h2>
<p><a href="http://www.youtube.com/watch?v=RrOJ9rZbbrU&#038;t=41s">YouTube video showing Kirby&#8217;s Avalanche gameplay</a> <a href="http://en.wikipedia.org/wiki/Puyo_Puyo">Wikipedia entry for Puyo Puyo</a></p>
<p><strong>Description:</strong> Essentially like a two-player Dr. Mario without the germs.</p>
<h2 id="firenice">45: Fire &#8216;N&#8217; Ice</h2>
<p><a href="http://inventwithpython.com/images/firenice.gif"><img src="http://inventwithpython.com/images/firenice.gif" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=1t782B0zK3Y">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A very original but obscure puzzle game on the NES. The player controls a wizard who can make and unmake ice cubes, which need to fall on all the fire in a level to clear it. The ice can also be used as platforms, and individual blocks of ice can be pushed around. (As a platformer, making a clone of this might be a bit more involved. But the concept is original enough where I think it&#8217;d be worth the effort.)</p>
<h2 id="typespeed">46: Typespeed</h2>
<p><a href="http://inventwithpython.com/images/typespeed.png"><img src="http://inventwithpython.com/images/typespeed.png" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=ENF_q-rRrcU&#038;t=30s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A typing game where words slowly move to the right side of the screen. The player must type the word to make them disappear. The player loses after enough words hit the right side of the screen.</p>
<h2 id="dinerdash">47: Diner Dash</h2>
<p><a href="http://www.youtube.com/watch?v=-mhwkNR2nrk&#038;t=37s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> A game where several different tasks in sequence must be managed simultaneously. Diner Dash has a restaurant theme, but other themes could be applied.</p>
<p><strong>Variants:</strong> Usually there are ways to streamline tasks by doing them in a certain order (e.g. the player can carry meals for two tables at the same time).</p>
<h2 id="pipedream">48: Pipe Dream</h2>
<p><a href="http://inventwithpython.com/images/pipedream.png"><img src="http://inventwithpython.com/images/pipedream.png" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=qQNnJQIPHV4&#038;t=27s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> The player must put down different shaped pipes on the board. The pipes cannot be rotated or moved after placement, but the player does get to see the next several pipes that will be used. A little after the start of the game, water begins to flow through the pipes.</p>
<h2 id="zoop">49: Zoop</h2>
<p><a href="http://inventwithpython.com/images/zoop.gif"><img src="http://inventwithpython.com/images/zoop.gif" width="200" /></a></p>
<p><a href="http://www.youtube.com/watch?v=C7501LkNvyI&#038;t=36s">YouTube video showing gameplay</a></p>
<p><strong>Description:</strong> Colored bubbles begin to appear from four sides of the board. The player can assume the color of the bubbles, and then destroy bubbles of a similar color. The game ends if the bubbles fill up one side of the board.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F02%2F20%2Fi-need-practice-programming-49-ideas-for-game-clones-to-code%2F&amp;title=%E2%80%9CI%20Need%20Practice%20Programming%E2%80%9D%3A%2049%20Ideas%20for%20Game%20Clones%20to%20Code" id="wpa2a_16"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/02/20/i-need-practice-programming-49-ideas-for-game-clones-to-code/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>New Book: &#8220;Making Games with Python &amp; Pygame&#8221;</title>
		<link>http://inventwithpython.com/blog/2012/02/10/new-book-making-games-with-python-pygame/</link>
		<comments>http://inventwithpython.com/blog/2012/02/10/new-book-making-games-with-python-pygame/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 21:13:03 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[News]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=554</guid>
		<description><![CDATA[I&#8217;ve completed my next book, which focuses on the Pygame library and making graphical games in Python. It assumes you have a little bit of Python programming knowledge. The book is free to read online from http://inventwithpython.com/pygame and can also be bought on Amazon.com for $25. Thanks to everyone who helped me out with this [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://inventwithpython.com/pygame"><img src="http://inventwithpython.com/images/cover_makinggames_thumb.png" alt="" /></a></p>
<p>I&#8217;ve completed my next book, which focuses on the Pygame library and making graphical games in Python. It assumes you have a little bit of Python programming knowledge. The book is free to read online from <a href="http://inventwithpython.com/pygame">http://inventwithpython.com/pygame</a> and can also be <a href="http://www.amazon.com/Making-Games-Python-Pygame-Sweigart/dp/1469901730?ie=UTF8&#038;tag=playwithpyth-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0982106017">bought on Amazon.com for $25</a>.</p>
<p>Thanks to everyone who helped me out with this book over the last year and a half.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F02%2F10%2Fnew-book-making-games-with-python-pygame%2F&amp;title=New%20Book%3A%20%E2%80%9CMaking%20Games%20with%20Python%20%26%20Pygame%E2%80%9D" id="wpa2a_18"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/02/10/new-book-making-games-with-python-pygame/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Pyganim &#8211; A Pygame module to make sprite animation dead simple.</title>
		<link>http://inventwithpython.com/blog/2011/12/09/pyganim-a-pygame-module-to-make-sprite-animation-dead-simple/</link>
		<comments>http://inventwithpython.com/blog/2011/12/09/pyganim-a-pygame-module-to-make-sprite-animation-dead-simple/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 01:20:06 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=519</guid>
		<description><![CDATA[Download pyganim.py and example programs. (Works on both Python 2 and 3.) Details at http://inventwithpython.com/pyganim/ Pyganim is a module that you can import into your Pygame games to handle sprite animation. Creating an animation is simply a matter of supplying a list of image filenames (or pygame.Surface objects) for each frame of animation, along with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://inventwithpython.com/pyganim/"><img alt="" src="http://inventwithpython.com/pyganim/images/pyganim_logo.jpg" class="alignnone" width="400" height="210" /></a></p>
<p><a href="http://inventwithpython.com/pyganim/pyganim_examples.zip">Download pyganim.py and example programs.</a> (Works on both Python 2 and 3.)</p>
<p>Details at <a href="http://inventwithpython.com/pyganim/">http://inventwithpython.com/pyganim/</a></p>
<p>Pyganim is a module that you can import into your Pygame games to handle sprite animation. Creating an animation is simply a matter of supplying a list of image filenames (or pygame.Surface objects) for each frame of animation, along with the duration that each frame lasts. Then call the play() method to start the animation and then call blit() each time you draw the window. The blit() function automatically draws the correct frame based on the amount of real time that has passed since the play() method was called. There are many, many other methods to provide finer levels of control as well.</p>
<p>There is more information available on the <a href="http://inventwithpython.com/pyganim/tutorial.html">Tutorial</a> and <a href="http://inventwithpython.com/pyganim/reference.html">Reference</a> page.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F12%2F09%2Fpyganim-a-pygame-module-to-make-sprite-animation-dead-simple%2F&amp;title=Pyganim%20%E2%80%93%20A%20Pygame%20module%20to%20make%20sprite%20animation%20dead%20simple." id="wpa2a_20"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/12/09/pyganim-a-pygame-module-to-make-sprite-animation-dead-simple/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 2.157 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-17 01:44:39 -->

