Skip to main content

UHP Utils

Dependency-free Python tools for running, testing, and comparing Universal Hive Protocol (UHP) engines.

Installation

Python 3.9 or newer is required. From the repository root, run:

python3 -m pip install .

Use without installation

Run the provided files from the repository root. They accept the same options as the installed commands:

Utility Without installation
uhp-wrapper python3 uhp_wrapper.py
uhp-arena python3 arena.py
uhp-compare-validmoves python3 compare_validmoves.py
uhp-compare-perft python3 compare_perft.py
uhp-to-pgn python3 uhp_to_pgn.py

For example:

python3 arena.py ./engine-a ./engine-b

Quick example

Start one game between two engines:

uhp-arena ./engine-a ./engine-b

Every command provides its full option list through --help.

Contents

Utility Functionality
Use without installation Run each utility from its provided Python file.
Engine inputs Use native executables or local Docker images.
uhp-wrapper Send UHP commands to one engine interactively.
uhp-arena Play matches between two engines and save results.
uhp-compare-validmoves Find legal-move differences across recorded positions.
uhp-compare-perft Compare perft counts and isolate the first divergent branch.
uhp-to-pgn Convert a UHP game string to readable PGN-style text.
Python API Use the same utilities as a library.

Engine inputs

Whenever a utility asks for an engine, provide one of these values:

  • A local executable: ./engine
  • A command available on PATH: hive-engine
  • A local Docker image: example/hive-engine:latest

The utility first looks for an executable or command. If none is found, it looks for a local Docker image with that name. Images are never pulled: the image must already exist and its ENTRYPOINT must start the UHP engine.

Native engine flags use options such as --engine-arg, --white-arg, or --engine-a-arg. Write a flag that begins with - using the equals form, for example --engine-arg=--fast. Environment variables use --env KEY=value or an engine-specific option such as --white-env KEY=value. Docker images accept environment variables, but not native engine flags.

uhp-wrapper

Open a terminal connected to one engine:

uhp-wrapper ./engine

Type UHP commands at the UHP> prompt. The wrapper prints the complete engine response. Use restart to restart the engine, terminate to stop it, and quit or exit to close the wrapper.

To pass a native engine flag, set an environment variable, and limit how long each command may run:

uhp-wrapper ./engine --engine-arg=--fast --env THREADS=4 --timeout 10

Use --startup-timeout if engine startup needs a separate limit.

uhp-arena

Play one game between two engines:

uhp-arena ./engine-a ./engine-b

By default, each engine gets five seconds per move. Multiple games alternate which engine plays White. Results are saved to logs/results.json with the final state and complete move list.

To play 20 games using a fixed search depth and a 300-move draw limit:

uhp-arena ./engine-a ./engine-b --games 20 --depth 6 --max-moves 300

Choose either --depth N or --time SECONDS. The default game type is Base+MLP. Use --results-file PATH to change the output file or --no-results to disable it. Optional --command-timeout and --search-timeout values set wall-clock limits.

uhp-compare-validmoves

Compare the legal moves reported by two engines:

uhp-compare-validmoves ./engine-a ./engine-b positions.uhp

positions.uhp must contain one UHP game string per line. By default, the utility checks the position before the last move of each game and prints any moves reported by only one engine. Blank lines and # comments are ignored.

To check every position in every game using four workers:

uhp-compare-validmoves ./engine-a ./engine-b positions.txt \
  --full-game --workers 4

Use - instead of the file name to read stdin. Differences are also verified by playing the other engine's moves; --no-cross-check skips this. Each worker starts one copy of both engines.

uhp-compare-perft

Compare perft counts from the initial Base-game position through depth 2:

uhp-compare-perft ./engine-a ./engine-b 'Base;NotStarted;White[1]' 2

The arguments are the two engines, the UHP position, and the maximum depth. The utility compares every reported count and, when they differ, follows the tree to find the first divergent position.

To test a position from a game through depth 4 with a 30-second command limit:

uhp-compare-perft ./engine-a ./engine-b \
  'Base+MLP;InProgress;White[2];wA1;bA1 -wA1' 4 --timeout 30

Expected perft command

Both engines must accept this line-oriented command after the position has been loaded with newgame:

perft N

N is a positive integer. For every depth from 1 through N, the engine must return the number of leaf nodes reachable in exactly that many plies from the current position. A depth 0 row with count 1 is optional. The response must finish with ok on its own line.

The preferred response format is:

perft 3
1: 37
2: 1,369
3: 65,631
ok

The first line above is the command sent to the engine; the remaining lines are its response. Counts must be decimal integers and may contain comma separators. DEPTH COUNT is also accepted. Engines may instead return a table:

depth  count  time
1      37     5us
2      1369   112us
3      65631  2ms
ok

In table output, the first two columns must be the numeric depth and count. A header and extra columns are ignored. Missing depths, non-numeric counts, or a missing ok terminator are invalid responses.

If counts differ, the utility uses validmoves, play or pass, and undo 1 to locate the first divergent branch, so both engines must support those UHP commands too. Use --valid-moves-only to skip perft and compare only the legal moves at the supplied position.

uhp-to-pgn

Convert a UHP game string and print the PGN-style result:

uhp-to-pgn 'Base;WhiteWins;Black[1];wA1'

The output contains game metadata followed by the numbered moves. It is printed to the terminal by default.

To add player names and save the result to a file:

uhp-to-pgn 'Base;WhiteWins;Black[1];wA1' \
  --white Alice --black Bob --output game.pgn

Input may also come from --input FILE or stdin. Use --site, --date, and repeatable --tag KEY=value options for additional metadata.

Python API

from uhp_utils import EngineWrapper

with EngineWrapper("./engine") as engine:
    moves = engine.command("validmoves")

EngineWrapper starts the engine, sends complete UHP commands, and closes the process automatically. The package also exports Arena, UHPState, compare_valid_moves, compare_perft, convert_uhp_to_pgn, structured result types, Docker helpers, and engine error classes.

License

MIT

With love @dortojekyll

Download files

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

Source Distribution

uhp_utils-0.1.0.tar.gz (133.2 kB view details)

Uploaded Source

Built Distribution

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

uhp_utils-0.1.0-py3-none-any.whl (29.5 kB view details)

Uploaded Python 3

File details

Details for the file uhp_utils-0.1.0.tar.gz.

File metadata

  • Download URL: uhp_utils-0.1.0.tar.gz
  • Upload date:
  • Size: 133.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for uhp_utils-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3a7df115261daa4feea97fb8543b73d031722cd48ad7d5eda446e0a3cd735c82
MD5 bf94b9c11e7a5ac7f51b960b1fd74091
BLAKE2b-256 544423d678fec60d2a3a14cf22ee0f8fea5954f914d2fc1a05b2ccee7476b081

See more details on using hashes here.

File details

Details for the file uhp_utils-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: uhp_utils-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for uhp_utils-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c13d08e62bbf8b7dea130a24865d924270357cc2d8dc784ed5b61908edee853a
MD5 1e48feb4d94ad792a74f482370faab19
BLAKE2b-256 27f245bc07a7a66242005cf3910a179e61a92ed1b9ddc5d5aeed5f85147ffa37

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page