summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Makefile4
-rw-r--r--docs/closest_apple.py2
-rw-r--r--docs/firstbot.py6
-rw-r--r--docs/firstbot.tex73
-rw-r--r--docs/introduction.tex86
-rw-r--r--docs/print_bot.py6
-rw-r--r--docs/random_avoid.tex12
-rw-r--r--docs/random_simple.tex2
-rw-r--r--docs/tutorial.tex11
-rw-r--r--snakegame/__init__.py3
10 files changed, 143 insertions, 62 deletions
diff --git a/docs/Makefile b/docs/Makefile
index 0b05cb0..5cd4a7e 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -4,7 +4,7 @@ FILES = $(wildcard *.tex *.py)
BUILD_FILES = $(patsubst %,${BUILD_DIR}/%,${FILES})
LATEX=xelatex
-LATEX_FLAGS=-shell-escape
+LATEX_FLAGS=-shell-escape -interaction=nonstopmode
.PHONY: all
@@ -13,7 +13,7 @@ all: tutorial.pdf
${BUILD_DIR}:
mkdir -p ${BUILD_DIR}
-${BUILD_DIR}/%.tex: %.tex ${BUILD_DIR}
+${BUILD_DIR}/%.tex: %.tex
./jinja2 --latex < $< > $@
${BUILD_DIR}/%.py: %.py
diff --git a/docs/closest_apple.py b/docs/closest_apple.py
index 8f8c560..3696bfa 100644
--- a/docs/closest_apple.py
+++ b/docs/closest_apple.py
@@ -2,7 +2,7 @@ DIRECTIONS = {
'L': (-1, 0),
'U': (0, -1),
'R': (1, 0),
- 'D': (1, 0),
+ 'D': (0, 1),
}
def closest_apple_bot(board, position):
diff --git a/docs/firstbot.py b/docs/firstbot.py
index b7abf4b..6eb8484 100644
--- a/docs/firstbot.py
+++ b/docs/firstbot.py
@@ -1,8 +1,2 @@
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)
- engine.run()
diff --git a/docs/firstbot.tex b/docs/firstbot.tex
index 221928c..7e95b85 100644
--- a/docs/firstbot.tex
+++ b/docs/firstbot.tex
@@ -1,4 +1,5 @@
\section{Your First Bot}
+\label{sec:firstbot}
\fasttrack{Always move up.}
Alright, let’s get started.
@@ -10,13 +11,71 @@ useless as that: our bot is just going to continually move up.
Let’s have a look at the code:
\pythonfile{firstbot.py}
-If you run this script (\texttt{python firstbot.py}),
-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.
+
+\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{mybot.py}, you can run this command:
+
+\begin{shell}
+$ snakegame mybot:up_bot
+\end{shell}
+
+To use different viewers, you can supply the \texttt{-v VIEWER} argument:
+\begin{shell}
+$ snakegame -v pyglet mybot:up_bot
+$ snakegame -v pygame mybot:up_bot
+$ snakegame -v curses mybot:up_bot
+\end{shell}
+
+You can specify multiple bots, and also control the width, height and number of
+apples on the board:
+\begin{shell}
+$ snakegame -w 4 -h 20 -a 30 mybot:up_bot mybot:up_bot mybot:up_bot
+\end{shell}
+
+\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:
+\begin{pythoncode}
+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)
+ viewer.run()
+\end{pythoncode}
+
+If you want to use pygame instead, change \texttt{snakegame.viewers.pyglet} to
+\texttt{snakegame.viewers.pygame}.
+
+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.
-Got all that?
Once you’re ready, we’ll move on to something a little more interesting.
diff --git a/docs/introduction.tex b/docs/introduction.tex
index 3f8d1d8..5a149b7 100644
--- a/docs/introduction.tex
+++ b/docs/introduction.tex
@@ -1,37 +1,61 @@
\section{Introduction}
-I assume you know the basics of Python:
-printing stuff,
-if/elif/else,
-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.
-
-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
-resources:
+Before starting this tutorial, you should \emph{already} know the basics of
+Python. Specifically, you should know these bits of Python:
\begin{itemize}
- \item \url{http://openbookproject.net/thinkcs/python/english2e/}
- \item \url{http://learnpythonthehardway.org/}
- \item \url{http://docs.python.org/tutorial/}
- \item Anyone you know who knows about Python, or is a programmer.
+ \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|)
\end{itemize}
-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.
-
-You’ll need to start by getting the code.
-The repository is at
-\url{http://hg.flowblok.id.au/snakegame},
-you can install it with pip:
-\begin{minted}{sh}
+
+\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:
+\begin{itemize}
+ \item How to Think Like a Computer Scientist \\
+ (\url{http://openbookproject.net/thinkcs/python/english2e/})
+ \item Learn Python the Hard Way \\
+ \url{http://learnpythonthehardway.org/}
+ \item The official tutorial in the Python documentation \\
+ \url{http://docs.python.org/tutorial/}
+\end{itemize}
+
+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
+sense.
+
+\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
+\url{http://hg.flowblok.id.au/snakegame}.
+You can install it using pip:
+\begin{shell}
$ pip install hg+http://hg.flowblok.id.au/snakegame#egg=SnakeGame
-\end{minted}
+\end{shell}
+
+If you wish to have a pretty graphical viewer for watching the game being
+played, you will also need to install pyglet\footnoteurl{http://pyglet.org/}
+and/or pygame\footnoteurl{http://pygame.org}.
+
+\subsection{Skipping ahead}
-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 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.
diff --git a/docs/print_bot.py b/docs/print_bot.py
index 8352aec..5adee1f 100644
--- a/docs/print_bot.py
+++ b/docs/print_bot.py
@@ -1,9 +1,3 @@
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)
- engine.run()
diff --git a/docs/random_avoid.tex b/docs/random_avoid.tex
index 042c947..90ac183 100644
--- a/docs/random_avoid.tex
+++ b/docs/random_avoid.tex
@@ -15,7 +15,7 @@ are.
But rather than me just telling you what they are,
why not have a look yourself?
-\pythonfile{print\_bot.py}
+\pythonfile{print_bot.py}
You should see something like this (on a 4x3 board):
\begin{minted}{pytb}
@@ -31,15 +31,15 @@ AssertionError: Return value should be a string.
\end{minted}
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.
@@ -131,9 +131,9 @@ cell.
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
diff --git a/docs/random_simple.tex b/docs/random_simple.tex
index 7ccb3a5..a1ff557 100644
--- a/docs/random_simple.tex
+++ b/docs/random_simple.tex
@@ -7,6 +7,8 @@ The next bot we’ll write is one which instead of moving in just one direction,
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.
diff --git a/docs/tutorial.tex b/docs/tutorial.tex
index e67b824..a76760b 100644
--- a/docs/tutorial.tex
+++ b/docs/tutorial.tex
@@ -16,20 +16,24 @@
\usepackage{minted}
\usemintedstyle{tango}
-\newmint[pyinline]{python}{}
+\newmint[py]{python}{}
\newminted{python}{}
\newmintedfile{python}{}
+\newminted[shell]{sh}{}
+
\setmainfont{Linux Libertine O}
\setmonofont[AutoFakeBold]{Inconsolata}
\setlength\parskip{2ex}
\setlength\parindent{0mm}
-\widowpenalty=1000
-\clubpenalty=1000
+%\widowpenalty=1000
+%\clubpenalty=1000
\newcommand\fasttrack[1]{\vspace{-2ex}\hfill\emph{Fast track: #1}\nopagebreak}
+\newcommand\footnoteurl[1]{\footnote{\url{#1}}}
+
\begin{document}
\title{Writing SnakeGame bots}
@@ -51,6 +55,7 @@
\input{look_ahead.tex}
+\break
\input{closest_apple.tex}
\end{document}
diff --git a/snakegame/__init__.py b/snakegame/__init__.py
index c4dbc83..be1f7a7 100644
--- a/snakegame/__init__.py
+++ b/snakegame/__init__.py
@@ -26,14 +26,17 @@ def main(argv=None):
parser.add_argument(
'-w', '--width',
default=30,
+ type=int,
)
parser.add_argument(
'-h', '--height',
default=20,
+ type=int,
)
parser.add_argument(
'-a', '--apples',
default=40,
+ type=int,
)
parser.add_argument('bot', nargs='+')
args = parser.parse_args(argv)