Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install ao.tron

How to install ao.tron

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install ao.tron
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
1.0.0 Available View build log
Windows (64-bit)
1.0.0 Available View build log
Mac OS X (10.5+)
1.0.0 Available View build log
Linux (32-bit)
1.0.0 Available View build log
Linux (64-bit)
1.0.0 Available View build log
 
Author
License
GNU GPL
Dependencies
Imports
Lastest release
version 1.0.0 on Jan 5th, 2011
Yet another tron board
======================

``ao.tron`` is a Python module for working with tron boards. For more
information and examples, take a look at the documented tests.


The tron board
--------------

The class ``ao.tron.Board`` represents the state of the tron board in discrete
time. It has some utility functions to make it easier for your bot to work
with the board object. To construct a simple board object, we'll use the
``ao.tron.generate`` generator::

>>> import sys
>>> from StringIO import StringIO
>>> sys.stdin = StringIO("""5 5
... #####
... #  2#
... #   #
... #1  #
... #####
... """)

>>> from ao.tron import generate
>>> board = generate().next()
>>> board


To see that we actually have the correct board, we can use the
``ao.tron.Board.board`` property. Note that this property is lazy, as are most
other properties: they won't calculate the result unless you ask for it, and
once calculated, they store it in the object for later use::

>>> print board.board
#####
#  2#
#   #
#1  #
#####

We can ask our coordinates using the ``ao.tron.Board.me`` property (or it's
alias, ``ao.tron.Board.m``)::

>>> me = board.me
>>> me
(1, 1)

Similarly, we can use ``ao.tron.Board.them`` (and it's alias,
``ao.tron.Board.t``)::

>>> them = board.them
>>> them
(3, 3)

As you can see, the coordinates start from the lower left corner. The first
coordinate is the X axis, the second is the Y axis. We can ask for any
coordinate on the boar like this::

>>> board[0, 0]
'#'

>>> board[me]
'1'

>>> board[them]
'2'

>>> board[10, 10]
Traceback (most recent call last):
...
IndexError: tuple index out of range

You can use the object's field markers for comparison::

>>> assert all(((board.ME  == '1'),
...     (board.THEM == '2'),
...     (board.WALL == '#'),
...     (board.FLOOR == ' '),
... ))

If we iterate over the board, it will yield it's blocks and coordinates::

>>> for block, coords in board:
...     print block, coords
# (0, 0)
# (1, 0)
...
1 (1, 1)
...
2 (3, 3)
...
# (4, 4)

To check for possible moves from a certain position, we call
``ao.tron.Board.possibilities``::

>>> board.possibilities(me)
((1, 2), (2, 1))

>>> board.possibilities(them)
((3, 2), (2, 3))

To check the distance between us and the opponent, we can use the
``ao.tron.Board.distance`` property::

>>> board.distance
3

Let's try it with a more complex board::

>>> sys.stdin = StringIO("""7 5
... #######
... #   #2#
... # # # #
... #1#   #
... #######
... """)

>>> board = generate().next()
>>> board.distance
9

Or an even more complex one::

>>> sys.stdin = StringIO("""14 10
... ##############
... #            #
... #          2 #
... #   ######   #
... #   #    #   #
... #   #    #   #
... #   ######   #
... # 1          #
... #            #
... ##############
... """)

>>> board = generate().next()
>>> board.distance
13

Let's try an isolated board::

>>> sys.stdin = StringIO("""14 10
... ##############
... ###         ##
... #  #    #  2 #
... #   ######   #
... #      #     #
... #     #      #
... #   ######   #
... # 1  #    #  #
... ##         ###
... ##############
... """)

>>> board = generate().next()
>>> board.distance
-1

Asking it the second time it should be slightly faster::

>>> board.distance
-1

Note that if we're isolated, calling distance will also calculate our space
left::

>>> board.space
35

If the two players are adjacent, the result is zero::

>>> sys.stdin = StringIO("""7 6
... #######
... #     #
... #  2  #
... #  1  #
... #     #
... #######
... """)

>>> board = generate().next()
>>> board.distance
0

To calculate one of the shortest paths between us and the opponent, we can use
the ``ao.tron.Board.path`` property::

>>> board.path
()

>>> sys.stdin = StringIO("""14 10
... ##############
... ###         ##
... #  #    #  2 #
... #   ######   #
... #       #    #
... #    #       #
... #   ######   #
... # 1  #    #  #
... ##         ###
... ##############
... """)

>>> board = generate().next()
>>> board.path
((2, 3), (2, 4), (2, 5), ..., (10, 5), (10, 6), (10, 7))

To get directions for an adjacent coordinate, call ``ao.tron.Board.direction``::

>>> board.direction((2, 3))
1

>>> board.direction((board.me[0]-1, board.me[1])) == board.WEST
True

Thus, if we want to head towards the enemy, we can easily get directions::

>>> board.direction(board.path[0]) == board.NORTH
True

The absolute distance between us and the enemy can be accessed with the
``ao.tron.Board.flight`` property::

Note that walls are not taken account of. We may even be separated. This is
just a cheap call to see if we're far away on a huge map::

>>> board.flight
14

The accurate way to go in the enemys direction is to to access the
``ao.tron.Board.chase`` property. Note that this will call ``ao.tron.Board.path``,
which may be quite expensive on huge boards. Use it with caution. If you need
a cheaper version, try ``ao.tron.Board.charge``.

>>> board.chase
(2, 3)

A cheaper way to do the same is to call ``ao.tron.Board.charge`` This call is
very cheap, but it does not check for the shortest path; It doesn't even check
if we're separated from the enemy or not. Use it when you're far from the
enemy and want to get closer as quickly as possible. In this particular case,
it will show us different results::

>>> board.charge
(3, 2)

The value is cached; calling it again is much faster::

>>> board.charge
(3, 2)

If we're trapped, it will return ``None``::

>>> sys.stdin = StringIO("""7 7
... #######
... #     #
... #  2  #
... #     #
... # ### #
... # #1# #
... #######
... """)

>>> board = generate().next()
>>> board.charge is None
True

As usual, the value is cached::

>>> board.charge is None
True

The opposite of ``ao.tron.Board.charge`` is ``ao.tron.Board.flee``. This call
is very cheap, but it does not check for the shortest path; It doesn't even
check if we're separated from the enemy or not. Use it when you want to run
away as quickly as possible::

>>> board.flee is None
True

As usual, the value is cached::

>>> board.flee is None
True

>>> sys.stdin = StringIO("""7 7
... #######
... #     #
... #  2  #
... #  1  #
... #     #
... #     #
... #######
... """)

>>> board = generate().next()
>>> board.flee
(2, 3)

>>> board.flee
(2, 3)

To make a random possible move, just call ``ao.tron.Board.random``::

>>> board.random in board.possibilities(board.me)
True


Clean up after the tests::

>>> from zope.testing import cleanup
>>> cleanup.cleanUp()


Reading the board from a file
-----------------------------

``ao.tron.generate`` is a simple function that reads the tron board from
the standard input and and generates ``ao.tron.Board`` instances. Format
the input like this::

5 5
#####
#  2#
#   #
#1  #
#####

The numbers on the first line show the height and withd of the board,
respectively. The following lines represent the board, where::

* `"#"` are walls
* `" "` (whitespaces) are the floor
* `"1"` is our player
* `"2"` is the opponent

To use the function, in your source file you can do something like this::

from ao.tron import generate, move
for board  in generate():
# do your stuff here
move(board.NORTH)

For testing, we'll create a file-like object and mangle sys.stdin to
demonstrate how it works::

>>> import sys
>>> from StringIO import StringIO
>>> sys.stdin = StringIO("""5 5
... #####
... #  2#
... #   #
... #1  #
... #####
... """)

Now we can use the board generator as usual::

>>> from ao.tron import generate
>>> board = generate().next()
>>> board


>>> sys.stdin = StringIO("""5 5
... #####
... #  2#
... #   #
... #1  #
... #####
... 4 4
... ####
... # 2#
... #1 #
... ####
... 4 4
... ####
... #1 #
... # 2#
... ####
... """)

>>> for board in generate():
...     print board




To make a move, we can use the ``ao.tron.board.move`` method, which is an
alias for the module-global ``ao.tron.move`` function::

>>> board.move(board.NORTH)
1

Clean up after the tests::

>>> from zope.testing import cleanup
>>> cleanup.cleanUp()


1.0.0 (unreleased)
==================

* First public release.

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:3

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.