Exemple #1
0
def create_torus(width=1, height=None):
    """
	Returns a mapping of boards containing width * height threeboards connected in
	a torus with corresponding hexagonal coordinates. If height is not specified,
	height = width.
	"""

    height = width if height is None else height

    boards = {}

    # Create the boards
    for coord in threeboards(width, height):
        boards[coordinates.Hexagonal(*coord)] = Board()

    # Link the boards together
    for coord in boards:
        for direction in [
                Direction.east, Direction.north_east, Direction.north
        ]:
            # Get the coordinate of the neighbour in each direction
            n_coord = wrap_around(add_direction(list(coord) + [0], direction),
                                  (width, height))

            # Connect the boards together
            boards[coord].connect_wire(boards[n_coord], direction)

    return [(b, c) for (c, b) in iteritems(boards)]
Exemple #2
0
def test_hexagonal():
    a = coordinates.Hexagonal(1, 2, 3)
    b = coordinates.Hexagonal(-1, -1, -1)

    # Should always equal their equivilent tuples
    assert a == (1, 2, 3)
    assert b == (-1, -1, -1)

    # Basic operators
    assert a + b == (0, 1, 2)
    assert a - b == (2, 3, 4)
    assert abs(b) == (1, 1, 1)

    # Magnitude
    assert a.magnitude() == 2
    assert b.magnitude() == 0
Exemple #3
0
def add_direction(vector, direction):
    """
	Returns the vector moved one unit in the given direction.
	"""
    return coordinates.Hexagonal(*(v + a
                                   for (v,
                                        a) in zip(vector, direction.vector)))
Exemple #4
0
def threeboards(width=1, height=None):
    r"""
	Generates a list of width x height threeboards. If height is not specified,
	height = width. Width defaults to 1. Coordinates are given as (x,y,0) tuples
	on a hexagonal coordinate system like so::
		
		
		    | y
		    |
		   / \
		z /   \ x
	
	A threeboard looks like so::
		
		   ___
		  / 1 \___
		  \___/ 2 \
		  / 0 \___/
		  \___/
	
	With the bottom-left hexagon being at (0,0).
	
	And is tiled in to long rows like so::
		
		   ___     ___     ___     ___
		  / 0 \___/ 1 \___/ 2 \___/ 3 \___
		  \___/ 0 \___/ 1 \___/ 2 \___/ 3 \
		  / 0 \___/ 1 \___/ 2 \___/ 3 \___/
		  \___/   \___/   \___/   \___/
	
	And into a mesh like so::
		
		   ___     ___     ___     ___
		  / 4 \___/ 5 \___/ 6 \___/ 7 \___
		  \___/ 4 \___/ 5 \___/ 6 \___/ 7 \
		  / 4 \___/ 5 \___/ 6 \___/ 7 \___/
		  \___/ 0 \___/ 1 \___/ 2 \___/ 3 \___
		      \___/ 0 \___/ 1 \___/ 2 \___/ 3 \
		      / 0 \___/ 1 \___/ 2 \___/ 3 \___/
		      \___/   \___/   \___/   \___/
	
	"""

    height = width if height is None else height

    # Create the boards
    for y in range(height):
        for x in range(width):
            # z is the index of the board within the set. 0 is the bottom left, 1 is
            # the top, 2 is the right
            for z in range(3):
                # Offset within threeboard --+
                # Y offset ---------+        |
                # X offset -+       |        |
                #           |       |        |
                x_coord = (x * 2) + (-y) + (z >= 2)
                y_coord = (x) + (y) + (z >= 1)
                yield coordinates.Hexagonal(x_coord, y_coord, 0)
Exemple #5
0
def board_to_chip(coords, layers=4):
    """
	Convert a hexagonal board coordinate into a hexagonal chip coordinate for the
	chip at the bottom-left of a board that size.
	"""
    x, y = hex_to_skewed_cartesian(coords)
    x *= layers
    y *= layers
    return coordinates.Hexagonal(x, y, 0)
Exemple #6
0
def wrap_around(coord, bounds):
    """
	Wrap the coordinate given around the edges of a torus made of hexagonal
	pieces. Assumes that the world is a NxM arrangement of threeboards (see
	threeboards function) with bounds = (N, M).
	
	XXX: Implementation could be nicer (and non iterative)...
	"""

    w, h = bounds
    x, y = to_xy(coord)

    assert (w > 0)
    assert (h > 0)

    while True:
        # Where is the coordinate relative to the world
        left = x + y < 0
        right = x + y >= w * 3
        below = (2 * y) - x < 0
        above = (2 * y) - x >= h * 3

        if below and left:
            x += 1 + (w - 1) * 2 - (h - 1)
            y += 2 + (w - 1) + (h - 1)
            continue

        if above and right:
            x -= 1 + (w - 1) * 2 - (h - 1)
            y -= 2 + (w - 1) + (h - 1)
            continue

        if left:
            x += w * 2
            y += w
            continue

        if right:
            x -= w * 2
            y -= w
            continue

        if below:
            x -= h
            y += h
            continue

        if above:
            x += h
            y -= h
            continue

        break

    return coordinates.Hexagonal(x, y, 0)
Exemple #7
0
def to_shortest_path(vector):
    """
	Converts a vector into the shortest-path variation.
	
	A shortest path has at least one dimension equal to zero and the remaining two
	dimensions have opposite signs (or are zero).
	"""
    assert (len(vector) == 3)

    # The vector (1,1,1) has distance zero so this can be added or subtracted
    # freely without effect on the destination reached. As a result, simply
    # subtract the median value from all dimensions to yield the shortest path.
    median = median_element(vector)
    return coordinates.Hexagonal(*(v - median for v in vector))
Exemple #8
0
def test___repr__():
    # Make sure the generic repr implementation uses the correct name and lists
    # all dimensions in the correct order.
    assert repr(coordinates.Hexagonal(1, 2, 3)) == "Hexagonal(1, 2, 3)"
    assert repr(coordinates.Cartesian2D(1, 2)) == "Cartesian2D(1, 2)"