Package: hexutil
hexutil=======Classes and functions to deal with hexagonal grids.[Screenshot of example.py]Introduction------------This module provides the following functionality.1.  Manipulation of grid coordinates in a hexagonal grid.2.  Converting between hexagonal grid coordinates and screencoordinates.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 example.py containsexample coding using this functionality. The above image is a screenshotfrom this example.Manipulation of grid coordinates in a hexagonal grid.-----------------------------------------------------The class hexagon.Hex represents a particular hexagon in a grid. ClassHex takes two integer arguments, x and y. These need to satisfy theproperty that their sum is even.The following (x,y) coordinate system is used to address hexagons in thegrid.[Hexgrid coordinate system]At 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. This alsosimplifies 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 is notsatisfied, an InvalidHex exception is thrown.Note that Hex is a namedtuple. That means that it can be used wherever a2-tuple (x, y) is required. It also means that is is immutable.Important functionality on instances of Hex. * The hex.x and hex.yfields for accessing the x- and y-coordinate, respectively. * Arithmeticoperations hex1 + hex2, hex1 - hex2 and - hex are supported. * Themethod hex.neighbours() returns the 6 direct neighbours of a hex. * Themethod hex1.distance(hex2) returns the distance in terms of steps on thehexagon 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 shows how theserelate to the hexagon size.[Hexgrid width and height]For a perfectly regular hexagon, the relationship height = ⅓√3 widthshould hold. In practice, we typically want integral pixel coordinates.The class HexGrid captures such a pair of width and height values. Itcan be initialized as HexGrid(width, height) or HexGrid(width). In thelatter case, height is automatically computed as round(⅓√3 * width).Important functionality on instances of Hex. * The hexgrid.width andhexgrid.height fields for accessing the width and height, respectively.* Method hexgrid.center(hex) returns a pair (x, y) of screen coordinatesof the center of hex. * Method hexgrid.corners(hex) returns a sequenceof 6 pairs (x, y) of screen coordinates of the 6 corners of hex. *Method hexgrid.bounding_box(hex) returns a hexutil.Rectangle objectdescribing the bounding box of hex. * Methodhexgrid.hex_at_coordinate(x, y) returns the Hex at screen coordinate(x,y). * Method hexgrid.hexes_in_rectangle(rect) returns a sequence ofall 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 Hexinstances.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) is done by the following method onHex 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 avalue ≥ 1. By default all costs are 1.This returns the path (as a sequence of Hex-es, including start pointand destination), or None if no path could be found.