Package: chexutil
chexutil========C++ accelerated classes and functions to deal with hexagonal grids... figure:: img/screenshot.png:alt: Screenshot of chex\_example.pyScreenshot of chex\_example.pyIntroduction------------This module provides the following functionality.1. Manipulation of grid coordinates in a hexagonal grid.2. Converting between hexagonal grid coordinates and screen coordinates.3. Field-of-view calculation on a hexagonal grid.4. A\* path-finding on a hexagonal grid.All this is provided by the module ``hexutil``. The file`chex\_example.py <chex_example.py>`__ contains example coding usingthis functionality. The above image is a screenshot from this example.Manipulation of grid coordinates in a hexagonal grid.-----------------------------------------------------The class ``chexutil.Hex`` represents a particular hexagon in a grid.Class ``Hex`` takes two integer arguments, ``x`` and ``y``. These needto satisfy the property that their sum is even.The following (x,y) coordinate system is used to address hexagons in thegrid... figure:: img/hexcoords.png:alt: Hexgrid coordinate systemHexgrid coordinate systemAt first, it may seem weird that this coordinate system leaves "holes"in the representation, i.e. there is no hexagon corresponding to, say,(0, 1). However, that turns out to be not a real problem in practise.The advantage is that relationship to the actual center points of thehexagons becomes very simple, namely, just multiply ``y`` with √3. Thisalso simplifies screen coordinate calculations.The only time the "holes" are an issue is if you want to pack grid datadensely into a 2D (numpy) array or a list-of-lists. In that case, justuse ``ar[hexagon.x//2][hexagon.y]`` to index into array ``ar``.The constructor of ``Hex`` checks the "x+y is even" property. If it isnot satisfied, an ``InvalidHex`` exception is thrown.Note that ``Hex`` is a namedtuple. That means that it can be usedwherever a 2-tuple (x, y) is required. It also means that is isimmutable.Important functionality on instances of ``Hex``. \* The ``hex.x`` and``hex.y`` fields for accessing the x- and y-coordinate, respectively. \*Arithmetic operations ``hex1 + hex2``, ``hex1 - hex2`` and ``- hex`` aresupported. \* The method ``hex.neighbours()`` returns the 6 directneighbours of a hex. \* The method ``hex1.distance(hex2)`` returns thedistance in terms of steps on the hexagon grid between ``hex1`` and``hex2``.Converting between hexagonal grid coordinates and screen coordinates.---------------------------------------------------------------------The mapping of a hexagon to screen (pixel) coordinates can be describedby two parameters ``width`` and ``height``. The following image showshow these relate to the hexagon size... figure:: img/widthheight.png:alt: Hexgrid width and heightHexgrid width and heightFor a perfectly regular hexagon, the relationship ``height = ⅓√3 width``should hold. In practice, we typically want integral pixel coordinates.The class ``HexGrid`` captures such a pair of ``width`` and ``height``values. It can be initialized as ``HexGrid(width, height)`` or``HexGrid(width)``. In the latter case, ``height`` is automaticallycomputed as ``round(⅓√3 * width)``.Important functionality on instances of ``Hex``. \* The``hexgrid.width`` and ``hexgrid.height`` fields for accessing the widthand height, respectively. \* Method ``hexgrid.center(hex)`` returns apair (x, y) of screen coordinates of the center of ``hex``. \* Method``hexgrid.corners(hex)`` returns a sequence of 6 pairs (x, y) of screencoordinates of the 6 corners of ``hex``. \* Method``hexgrid.bounding_box(hex)`` returns a ``chexutil.Rectangle`` objectdescribing the bounding box of ``hex``. \* Method``hexgrid.hex_at_coordinate(x, y)`` returns the ``Hex`` at screencoordinate (x,y). \* Method ``hexgrid.hexes_in_rectangle(rect)`` returnsa sequence of all ``Hex``-es which overlap with ``Rectangle`` rect.Field-of-view calculation on a hexagonal grid.----------------------------------------------Field-of-view calculation is done by the following method on ``Hex``instances.``hex.field_of_view(self, transparent, max_distance, visible=None)``-  transparent -- from a Hex to a boolean, indicating of the Hex istransparent-  max\_distance -- maximum distance you can view-  visible -- if provided, should be a dict which will be filled andreturnedReturns a dict which has as its keys the hexagons which are visible. Thevalue is a bitmask which indicates which sides of the hexagon arevisible. The bitmask is useful if you want to use this function also tocompute light sources.::view_set = player_pos.field_of_view(...)light_set = light_source.field_of_view(...)# Is pos visible?if view_set.get(pos, 0) & light_set.get(pos, 0):# yes it isA\* path-finding on a hexagonal grid.-------------------------------------Path-finding (using the `A\*algorithm <https://en.wikipedia.org/wiki/A*_search_algorithm>`__) isdone by the following method on ``Hex`` instances.``hex.find_path(self, destination, passable, cost=lambda pos: 1)``-  hex -- Starting position (``Hex`` object) for path finding.-  destination -- Destination position for path finding.-  passable -- Function of one position, returning True if we can movethrough this hex.-  cost -- cost function for moving through a hex. Should return a value≥ 1. By default all costs are 1.This returns the path (as a sequence of ``Hex``-es, including startpoint and destination), or ``None`` if no path could be found.