Skip to main content

HexLogic aims to be a Python package, without dependencies outside of the built-in library, providing fully-documented functions to deal with the relations between objects on a hexagon tiled grid. Including conversion from „hexagonal“ to „pixel“ coordinates and pathfinding with varying movement cost. As well as various operations like line-drawing.

Project description

HexLogic

GitHub last commit (by committer) Static Badge GitHub PyPI - Downloads

HexLogic aims to be a Python package, without dependencies outside of the built-in library, providing fully documented classes and functions to deal with the relations between objects on a hexagon tiled grid. Including conversion from „hexagonal“ to „pixel“ coordinates and pathfinding with varying movement cost. As well as various operations like line-drawing.

Is there a requirement for Hexlogic?

Although there have been various attempts at bundling the functionalities, outlined by Amit Patel on redblobgames.com and providing them on the Python Package Index, there is currently no package available, that provides all the following features:

  • documentation
  • type-hinted
  • drop-in usability
  • includes pathfinding algorithms
  • not an OOP only implementation

On design choices

  • Drop-in usability can be achieved using an object-oriented approach, as Python allows for multiple inheritance. Despite that opting for a function based approach, has the benefit, of only having to add the coordinates to the objects positioned on the hexagonal grid, which ultimately keeps the separation between the different building blocks of code cleaner and sidesteps possible conflicts between parent classes.
  • The file started out as a part of a Pygame-CE project, as a result, the design is built around the idea of positioning units, tiles etc. being childclasses of pygame.sprite.Sprite on a map.
  • A lesson learned from this ongoing project, is that with increasing scope of the project it becomes desirable to catch errors early, which is the reason for the divergence from the minimalistic pythonic approach to code.

Prerequisites

  • Python 3.10 or newer

Installation

Python Package Index

   pip install hexlogic

Manually (Github)

  git clone https://github.com/MaximilianHauser/HexLogic.git

Usage

These functions assume you're using objects to represent tiles, units, items, etc on a map that is made up of hexagonal shaped tiles, with a flat side as top. It furthermore assumes you're using a 3-dimensional cartesian coordinate system, that assigns the coordinates along axis parallel to the orientation of the sides of each hexagon. Like in the example given below. When using Pygame-CE it is recommended to use square images and draw a hexagon on them. An example of a 64x64 tile is provided, it's intended to be used with the transparency colorcode set to (255, 0, 255). Currently the package does not support drawing hexagons.

     +s \         / -r
         \   _   /                   A: ( q=0, r=0, s=0 )
         _ / B \ _                   B: ( q=0, r=-1, s=1 )
       / G \ _ / C \                 C: ( q=1, r=-1, s=0 )
 -q __ \ _ / A \ _ / __ +q           D: ( q=1, r=0, s=-1 )
       / F \ _ / D \                 E: ( q=0, r=1, s=-1 )
       \ _ / E \ _ /                 F: ( q=-1, r=1, s=0 )
           \ _ /                     G: ( q=-1, r=0, s=1 )
        /        \
    +r /          \ -s

Contains all hextile logic, specified as logic handling the relationship between cartesian coordinates and cube coordinates, for the purpose of defining the relative position of hexagon tiles on the screen. In addition it provides calculations in regards to hextile map related formulas and algorithms.

Custom Errors:

ConstraintViolation(ValueError):
Custom Error to be raised when a logical constraint is violated.

Classes:

RectCoords(namedtuple("RectCoords", "x y")):
Coordinates in a rectangular cartesian coordinate system.

HexCoords(namedtuple("HexCoords", "q r s")):
Coordinates in a three-dimensional cartesian coordinate system, limited by the constraint q + r + s = 0.

GraphMatrix(tile_grp:set|list):
Creates a GraphMatrix object, containing a directed, weighted graph, from the objects or coordinates contained in tile_grp, organized in a Dictionary.

Functions and Methods:

float_to_int(num_in:int|float) -> int|float:
Returns an Integer if passed an Integer or if passed a Float with its decimal being zero. Returns a Float if passed a Float, with a non zero decimal.

container_or_object(container_or_object:object|tuple|RectCoords|HexCoords, expected_len:2|3, return_obj_type:str="Tuple") -> tuple|RectCoords|HexCoords|list|dict: Returns a Tuple, Namedtuple, List or Dictionary of predefined length, when passed an Object or a Tuple.

linint(a:int|float, b:int|float, t:int|float) -> int|float:
Linear interpolation returns point at t of distance between a and b.

rect_linint(xy_a:object|tuple|RectCoords, xy_b:object|tuple|RectCoords, t:int|float, return_coords_obj:bool=False) -> tuple|RectCoords:
Linear interpolation returns point at t of distance between a and b on a cartesian coordinates system.

cube_linint(obj_a:object|tuple|HexCoords, obj_b:object|tuple|HexCoords, t:int|float, return_coords_obj:bool=False) -> tuple|HexCoords:
Returns the hextile coordinates of a point situated at t part of the way from obj_a to obj_b.

round_container(container:dict|list|set|tuple|RectCoords, d:int=0) -> dict|list|set|tuple|RectCoords:
Rounds each number in a container to the specified decimal, if None is specified to the nearest Integer.

round_hex(qrs:tuple|HexCoords, return_coords_obj:bool=False) -> tuple|HexCoords:
Rounds each of the coordinates to the nearest Integer.

get_xy(obj:object, return_coords_obj:bool=False) -> tuple|RectCoords:
Returns values of attributes x and y of obj as Tuple or RectCoords.

set_xy(obj:object, x:int|float, y:int|float) -> None:
Set x and y attribute of obj to specified values.

get_qrs(obj:object, return_coords_obj:bool=False) -> tuple|HexCoords:
Returns values of attributes q, r, s of obj.

set_qrs(obj:object, q:int|float, r:int|float, s:int|float) -> None:
Set q r and s attribute of obj to specified values.

hex_to_pixel(qrs:object|tuple|HexCoords, tile_width:int=64, tile_height:int=64, return_coords_obj:bool=False) -> tuple|RectCoords:
Converts cube coordinates to pixel coordinates.

pixel_to_hex(xy:object|tuple|RectCoords, tile_width:int=64, tile_height:int=64, return_coords_obj:bool=False) -> tuple|HexCoords:
Converts pixel coordinates to cube coordinates.

get_angle(obj_a:object|tuple|HexCoords, obj_b:object|tuple|HexCoords) -> float:
Returns the angle from a line through obj_a and abj_b relative to the x-axis of a two dimensional cartesian coordinate system.

neighbors(qrs:object|tuple|HexCoords) -> set:
Return a List of coordinates of neighboring hexagons.

distance(obj_a:object|tuple|HexCoords, obj_b:object|tuple|HexCoords) -> int|float: Returns distance from one Object to another in a cube coordinate system.

in_range(obj:object|tuple|HexCoords, n:int) -> set: Returns a Set containing the cube coordinates of every hexagon in distance n from obj.

line_draw(obj_a:object|tuple|HexCoords, obj_b:object|tuple|HexCoords) -> tuple:
Draws a line from one hexagon to another, returns a Tuple containing the hexagons with the center closest to the line.

dist_lim_flood_fill(start_obj:object|tuple|HexCoords, n:int, obj_grp:list|set, movement_var:str=None) -> set:
All cube coordinates within n distance from an Object, factoring in movement_var (variable if 0 blocks object traversability).

GraphMatrix.update_entry(self, from_coord:object|tuple|HexCoords, to_coord:object|tuple|HexCoords, movement_cost:int|float) -> None: Add or update a one-directional entry in the adjacency matrix.

GraphMatrix.del_entry(self, from_coord:object|tuple|HexCoords, to_coord:object|tuple|HexCoords) -> None: Delete a one-directional entry in the adjacency matrix. Does not raise an Error or Warning if no entry matching the input exists.

GraphMatrix.connected(self, from_coord:object|tuple|HexCoords) -> set: Return all connected coordinates. Returns None, in case of there aren't being any.

GraphMatrix.get_movement_cost(self, from_coord:object|tuple|HexCoords, to_coord:object|tuple|HexCoords) -> int|float: Get the movement cost from one Object or coordinate to another.

GraphMatrix.a_star_algorithm(start:object|tuple|HexCoords, goal:object|tuple|HexCoords, test_accessibility:bool=False) -> list:
Modified version of Dijkstra’s Algorithm that is optimized for a single destination. It prioritizes paths that seem to be leading closer to a goal.

To Do

List of issues to be solved and features to be added.

  • modify round_container to work for infinitely nested containers
  • "from_c not in self.matrix_coords and from_c not in destinations" printout in console when running unittests

References

redblobgames.com (Amit Patel):
Hexagons
Hexagons Implementation Guide
Hexagons Generated Code
Pathfinding
Pathfinding Implementation Guide
NumPy Style Guide:
syntax and best practices for docstrings

Other packages on the Python Package Index offering hexagonal grid functionalities:

Prior to deciding to make Hexlogic a package available on PyPI, I researched other available implementations to check if it had already been implemented in the way envisioned and on the other hand to learn from other people's work. Below is a list of the packages found which are thematically closest to my own. Check them out! Depending on what you're trying to do some of them might be better suited for your needs.

HexPex
GitHub last commit (by committer) PyPI - Downloads https://pypi.org/project/hexpex/

  • OOP implementation based on single coordinate
  • cube and axial coordinates, directions (facing up)
  • distances, neighbors, range, rings, rotation, spiral

Hexutil
GitHub last commit (by committer) PyPI - Downloads https://pypi.org/project/hexutil/

  • OOP implementation based on single coordinate
  • comprehensive implementation of "pointy side up" hexagonal game focused map logic
  • including pathfinding and field of view

pygame-pgu
GitHub last commit (by committer) PyPI - Downloads https://pypi.org/project/pygame-pgu/

  • a COMPREHENSIVE collection of handy modules and scripts for PyGame

HexGrid
GitHub last commit (by committer) PyPI - Downloads https://pypi.org/project/hexgrid/

  • "Settlers of Catan" - grid, complete with tile, edge and node coordinates
  • Used by JSettlers2, described in "Thomas, Robert S. 2003. Real-time Decision Making for Adversarial Environments Using a Plan-based Heuristic. PhD thesis, Northwestern University"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hexlogic-1.0.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hexlogic-1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file hexlogic-1.0.tar.gz.

File metadata

  • Download URL: hexlogic-1.0.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for hexlogic-1.0.tar.gz
Algorithm Hash digest
SHA256 86b77accf735fb9c8fece749b8b0e4a36c5b452698d5a55ac16fe9f51429ac49
MD5 c74db132e8b9713130ac944f8d9311c4
BLAKE2b-256 a792d784f5046835cbda83202031f3779c80e031647c5adecf06585783536e97

See more details on using hashes here.

File details

Details for the file hexlogic-1.0-py3-none-any.whl.

File metadata

  • Download URL: hexlogic-1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for hexlogic-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a875095935a2cf37e1077ea2a25f7eff3b99dc6094ebaaa76aee2ae858b795b7
MD5 760deabc0b500b440f99296780702f8f
BLAKE2b-256 054442116b29f67ab03c113cc902e5922610287c5aa86c2f9f6ef79227ee5e5b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page