Peter Ward committed bb016e2


Comments (0)

Files changed (10)

 BUILD_FILES = $(patsubst %,${BUILD_DIR}/%,${FILES})
+LATEX_FLAGS=-shell-escape -interaction=nonstopmode
 .PHONY: all
 	mkdir -p ${BUILD_DIR}
-${BUILD_DIR}/%.tex: %.tex ${BUILD_DIR}
+${BUILD_DIR}/%.tex: %.tex
 	./jinja2 --latex < $< > $@


     'L': (-1, 0),
     'U': (0, -1),
     'R': (1, 0),
-    'D': (1, 0),
+    'D': (0, 1),
 def closest_apple_bot(board, position):
 def up_bot(board, position):
     return 'U'
-if __name__ == '__main__':
-    from snakegame.engines.pyglet import PygletEngine
-    engine = PygletEngine(10, 10, 20)
-    engine.add_bot(up_bot)


 \section{Your First Bot}
 \fasttrack{Always move up.}
 Alright, let’s get started.
 Let’s have a look at the code:
-If you run this script (\texttt{python}),
-you should see a nice big board with some apples scattered over it, and a snake
-continually moving upwards.
-That snake is our bot: each time the game decides that our snake is allowed to
-move, it calls the \texttt{up\_bot} function, which immediately returns the
-string \mint{python}|'U'|, which means it should move the snake upwards.
+Pretty simple, huh?
+It’s a function takes as input two parameters, and returns a string.
+We’ll have a look at \texttt{board} and \texttt{position} later,
+but the important thing here is that the returned value says which direction the
+snake should move in. Each time the snake is allowed to make a move, the
+function is called, it returns one of \py|'U', 'D', 'L', 'R'|
+(indicating up, down, left and right, respectively), and the snake is moved in
+that direction.
-Got all that?
+\subsection{Running the code}
+Depending on how you have installed SnakeGame, there are a few different ways to
+run the code. If you’re in some kind of programming class, ask your instructor
+which method to use.
+\subsubsection{Method A: CLI interface}
+If you installed from the repository (using \texttt{pip}), this is the method
+you should use.
+Assuming you’ve put the \texttt{up\_bot} function in a file called
+\texttt{}, you can run this command:
+$ snakegame mybot:up_bot
+To use different viewers, you can supply the \texttt{-v VIEWER} argument:
+$ snakegame -v pyglet mybot:up_bot
+$ snakegame -v pygame mybot:up_bot
+$ snakegame -v curses mybot:up_bot
+You can specify multiple bots, and also control the width, height and number of
+apples on the board:
+$ snakegame -w 4 -h 20 -a 30 mybot:up_bot mybot:up_bot mybot:up_bot
+\subsubsection{Method B: Pyglet / Pygame}
+You can also add some code to the file containing your bot so that you can run
+that file as a normal Python program, which will run the game.
+At the end of the file, add this:
+if __name__ == '__main__':
+    from snakegame.engine import Engine
+    from snakegame.viewers.pyglet import Viewer
+    engine = Engine(10, 10, 25)
+    engine.add_bot(up_bot)
+    viewer = Viewer(engine)
+If you want to use pygame instead, change \texttt{snakegame.viewers.pyglet} to
+If neither of these work, there is also a console viewer, which works if you’re
+in a terminal (it will not work in IDLE!):
+use \texttt{snakegame.viewers.curses}.
+\subsection{Got it running?}
+Great, you should see a nice big board with some apples scattered over it,
+and a snake continually moving upwards.
 Once you’re ready, we’ll move on to something a little more interesting.


-I assume you know the basics of Python:
-printing stuff,
-for and while loops and lists.
-That’s really all you need to follow along at least the first four sections,
-and then dictionaries will start to come in handy.
+Before starting this tutorial, you should \emph{already} know the basics of
+Python. Specifically, you should know these bits of Python:
+    \item How to \py|print| things
+    \item \py|if|, \py|elif| and \py|else|
+    \item \py|for| and \py|while| loops
+    \item \py|list|s and \py|dict|ionaries
+    \item functions (\py|def|)
-If you have no idea what I was just talking about, \emph{don’t panic}.
-All that means is that you’re not quite ready for this yet,
-and you need to start by learning Python using some of these excellent
+\subsection{Help! I don’t know what these are…}
+If you have no idea what any of those things are, \emph{don’t panic}.
+All that means is that you’re not quite ready to follow this tutorial yet, and
+you need to learn the basics of Python first.
+There are many excellent \emph{free} resources for doing this:
-    \item \url{}
-    \item \url{}
-    \item \url{}
-    \item Anyone you know who knows about Python, or is a programmer.
+    \item How to Think Like a Computer Scientist \\
+        (\url{})
+    \item Learn Python the Hard Way \\
+        \url{}
+    \item The official tutorial in the Python documentation \\
+        \url{}
-Don’t be discouraged if it doesn’t immediately make sense:
-programming can be difficult and frustrating,
-but if you put the effort in, it can also be a very rewarding, interesting and
-fun activity.
-If you are stuck with anything, Google it first.
+The most important resource to learn programming, however, are the people you
+know who are learning Python with you, already know Python, or some other
+programming language.
+You can spend hours trying to understand something in books and not get it,
+but ask another person to explain it, and it will all suddenly ‘click’ and make
-You’ll need to start by getting the code.
-The repository is at
-you can install it with pip:
+\subsection{Yeah, I know what those are.}
+Excellent! Let’s get started then.
+If you’re doing this in some kind of programming class, your instructor may have
+provided you with a zip file (or similar) containing SnakeGame and pyglet.
+If so, follow their instructions for setting it up, and head straight on to
+Your First Bot.
+Otherwise, you’ll need to first install the code. The latest version of
+SnakeGame is available in a Mercurial repository at
+You can install it using pip:
 $ pip install hg+
-Each section starts with a Fast track note:
-if you know what you’re doing, just write a bot which moves according to what it
-says in the fast track note, and you can skip that section.
+If you wish to have a pretty graphical viewer for watching the game being
+played, you will also need to install pyglet\footnoteurl{}
+and/or pygame\footnoteurl{}.
+\subsection{Skipping ahead}
+If you already know Python, you will probably want to skip some sections of this
+tutorial. To make this easier, there is a \emph{Fast track} note at the start of
+each section: if you can write a bot which does what it says, you can safely
+skip that section.


 def print_bot(board, position):
     print position
     print board
-if __name__ == '__main__':
-    from snakegame.engines.pyglet import PygletEngine
-    engine = PygletEngine(3, 4, 3)
-    engine.add_bot(print_bot)


 But rather than me just telling you what they are,
 why not have a look yourself?
 You should see something like this (on a 4x3 board):
 Ignore all the Exception stuff, that’s just because we didn’t return one of
-\pyinline|'L'|, \pyinline|'U'|, \pyinline|'D'| or \pyinline|'R'|.
-The first line is our position: it’s a \pyinline|tuple| of the x and y
+\py|'L'|, \py|'U'|, \py|'D'| or \py|'R'|.
+The first line is our position: it’s a \py|tuple| of the x and y
 coordinates of our snake’s head.
 The second line is the board: it’s a list of each row in the board,
 and each row is a list of the cells in that row.
 Notice that if we index the board first by the y coordinate and then by the x
 coordinate, we can get the character in the board where our snake is:
-\pyinline|board[y][x] == board[2][1] == 'A'|.
+\py|board[y][x] == board[2][1] == 'A'|.
 The head of our snake is always an uppercase character in the board,
 and the rest of our body (the tail) are always lowercase characters.
 Remember that our board is a list of rows (stacked vertically),
 and each row is a list of cells (stacked horizontally).
 So we need to first find the right row, which we will do by using the y
-coordinate: \pyinline|board[y]|.
+coordinate: \py|board[y]|.
 Then we need to find the right cell in the row, using the x coordinate:
-\pyinline|board[y][(x + 1) % width]|.
+\py|board[y][(x + 1) % width]|.
 We’re almost at the end: all we need to do is build up a list of each cell we
 can move into. We know that we can move into cells which are


 chooses a direction at random to move in.
 Go on, try writing it yourself! I’ll wait here until you’re ready.
+Hint: check out the \texttt{random} module.
 Got it working? Good work!
 But you’ve probably noticed that there’s a problem:
 it doesn’t take long for our random bot to die.


 \setmainfont{Linux Libertine O}
 \newcommand\fasttrack[1]{\vspace{-2ex}\hfill\emph{Fast track: #1}\nopagebreak}
 \title{Writing SnakeGame bots}


         '-w', '--width',
+        type=int,
         '-h', '--height',
+        type=int,
         '-a', '--apples',
+        type=int,
     parser.add_argument('bot', nargs='+')
     args = parser.parse_args(argv)