State of Mzinga, March 2021

Mzinga is my collection of open-source software to play the board game Hive, and I last posted about it back in November 2018.

A lot has happened since then, so this feels almost like a re-launch than anything. Essentially, Mzinga development stalled at the end of 2019. I made a variety of internal performance improvements, but the biggest changes were polishing the UI of the Viewer, including adding the ability to save and review games later, in a new review mode.

Nothing happened for Mzinga in 2020, though I did spend some time getting acquainted with .Net Core and Avalonia, an exciting cross-platform UI framework similar to WPF.

I did some smaller projects with this “new” way to write C#, and when Avalonia released their big 0.10.0 update in December 2020, I decided it was time to try porting one of my bigger apps to this new platform.

So in January of this year I ported Mzinga to .NET 5, and rewrote the Viewer in Avalonia instead of WPF. The end result has been more than worth the effort.

I got to keep 99% of my existing code, and with a just couple weekends of work, starting with Mzinga v0.10.0, the entire project is cross-platform, with releases on Windows, MacOS, and Linux.

Here’s the announcement on BoardGameGeek: Mzinga, open-source Hive, now cross-platform (Windows, MacOS, Linux)

Having the code cross-platform really opens up the opportunity for getting other developers working on their own AIs. By having the Viewer available on Mac and Linux, more developers are willing to invest in writing their own UHP engines and Hive AIs, which was the whole point of Mzinga in the first place.

I’m in conversations with several such developers- one even found a bug in Mzinga that’s been there for years! They all appreciate the level of documentation and tools I’ve provided to help give them a place to get started.

To that end, I’ve also taken some stabs at building some more engines myself. I started a UHP Sample Code repo, with simple sample engines to get people started. They only implement the base game (no expansions), have no AI, and are not optimized, but they meet the minimum requirements for an engine, and therefore are yet another starting point for developers. I’ve got versions in both C++ and C#, and I’ll probably also create versions in Python and JavaScript too.

For Mzinga itself, it’s a big, complicated codebase, and I don’t see any “easy wins” for making it faster or the AI stronger.

So on top of everything else, I’ve also started MzingaCpp, which is a brand new engine written completely in C++. Here I’m taking all that I’ve learned and focusing on making the fastest possible engine, with hopefully the strongest AI. Right now it’s got the base game and expansions up and running, and while it doesn’t have any AI yet, its move generator is already 1.5x -2x the speed of Mzinga, which is a great start.

That’s all for now! I’ve you’re interested in playing a game of Hive on your computer, give Mzinga a try. If you’re interested in developing your own Hive AI, drop me a line!

/jon

 

Introducing the HawKeys utility

Last year I started learning Hawaiian in an effort to improve my understanding of the music that I love. I found that I wasn’t satisfied with the available tools for typing the ʻokina and kahakōs used in the Hawaiian language.

At first I wrote a little AutoHotKey script to make it easier, and it works, but AutoHotKey is kind of a heavy tool for so simple a use case.

This year I set about writing a simple Windows app that gave the same result: global hotkeys to quickly type ʻokinas and kahakōs. It mean learning some old-school Windows coding around creating hot keys and simulating the keyboard, but the result is a simple .NET 2.0 WinForms app called HawKeys. It works great, and even better, HawKeys is my first app published on the Microsoft Store!

So if you’re on Windows 10, get HawKeys on the Microsoft Store. Otherwise. if you’re on Windows XP SP3 or greater, go to Latest HawKeys Release, download the zip file and run HawKeys.exe.

You can follow the development at HawKeys on GitHub.

Enjoy!

/jon

State of Mzinga, November 2018

Mzinga is my open-source AI for the board game, Hive, and I last posted about it back in February 2018.

So what’s changed in the last nine months?

From an end user standpoint, the high-level highlights are:

  • The official expansion pieces (Mosquito, Ladybug, Pillbug) are now fully supported
  • Lots of Viewer updates, including:
    • Graphical bug pieces, rather than just the text names
    • Sound effects
    • Progress bars while the AI is thinking
    • Improved layout to maximize the playing area
    • Ability to “lift” pieces that are stacked to see underneath them
    • “BoardSpace” notation (the defacto way to record Hive games)
  • The Viewer now includes an “Internal” implementation of the Mzinga Engine, in case no engine executable is available
  • Engines can now expose their options to be set by the Viewer
  • There is now a “portable” release, ie. a simple zip file for users who can’t/won’t install
  • The “updater” now only checks for updates but doesn’t offer to download and install them (security issue)

From an engine / AI standpoint, the highlights are:

  • Switched to a Principal Variation Search, ie., assume that the best move from a previous, shallow search, is the best place to when starting a deeper search
  • Pre-sort moves to try moves with the most potential to upset the game first (ie moves that affect how surrounded the queens are)
  • Switched to tapered evaluation, ie. how you should play near the start of the game can be different than how you should play near the end of the game, so evaluate the board with different metric weights as the game progresses
  • Different metrics for different game types: one general set of metric weights for all game types (all the combinations of with/without expansions pieces) just isn’t effective, so the AI now has different specialized metric weights for each game type
  • Better usage of multi-threaded searches
  • Various perf improvements

I think the biggest upgrades for users are the inclusion of the expansion pieces, the much friendlier Viewer, and the fact that it’s now portable. Technically all you need to play Hive is the single Mzinga.Viewer.exe from the portable release. You can throw it on a flash drive and play Hive on any Windows (Vista or higher) computer.

On the research front, the biggest discovery for me was of the TreeStrap self-training algorithm. I won’t go into details here, (I talk about it a little in this BoardGameGeek post), but suffice it to say that it provided a more targeted way to improve Mzinga’s AI. Rather than rely solely on my evolution-based model (which, due to the limitations of my population sizes and my “rough” implementation of genetics, produced an often homogeneous pool of AIs) TreeStrap let me force an individual AI to self-train by playing games against itself and intelligently updating its own metric weights.

It was through using TreeStrap that I created a decent AI for playing games with both the Mosquito and Ladybug expansion pieces. However, it was only in testing that AI against my existing pool of evolved AIs that I learned that it only excelled in that game type. In fact that AI did horribly in other game types, which lead me to believe that it might not be possible to create one set of weights that works in all game types. This propelled me to finally expand Mzinga to support specialized weights for each game type.

But now I have a pretty robust “pipeline” for improving Mzinga’s AI. First, I have eight special AIs, each self-training against for one particular game type. Then I push those AIs into my pool of other AIs and have them all fight each other (no more evolution, just the fighting) to evaluate their strength. Then I take the top AIs for each game type (usually, but not always, the self-trained AIs) and inject their weights into Mzinga’s Engine.

In theory, if I keep repeating that loop then Mzinga’s AI should get stronger and stronger. Also I can keep “snapshot” the AI every time I release a new version and keep it in the AI pool, so I can track that the newer AIs are objectively stronger than the older ones.

As this self-improvement loop is already starting to pan out, I’ve begun spreading the load across multiple computers. I can now have one set of computers that continuously run the self-training algorithm on the special AIs and push the results to OneDrive, while another computer regularly grabs those AIs and tests them in combat.

/jon

 

Introducing the RomSort utility

 

About a year ago I wrote a little command-line tool for sorting ROM files into alphabetical sub-directories. The main feature was it could intelligently combine the smaller sub-directories, which is useful when you’re browsing on low-resolution screens. However after I got the code working I never got around to sharing it.

So I took some time to re-package the code into a small .NET 2.0 WinForms app. It is pretty straightforward to use, and even gives you a live preview of what the end result will be before you use it. Note that filename collisions will be marked in red and it won’t let you perform the sort if there are any.

Source and binaries (under releases) @ RomSort on GitHub.

Enjoy!

/jon

The State of Mzinga, February 2018

Mzinga is my open-source AI for the board game, Hive, and I can’t believe that the last time I posted it was all the way back in Summer 2016.

So much has happened since then!

At the time, my focus was on the Mzinga Trainer, a tool for improving my board evaluation function, ie. if I look at a given board, how accurately can I answer: who is winning and by how much?

The Mzinga Trainer does this through a genetic evolution algorithm, whereby a population of AIs (each with their own evaluation function) endlessly battle one another, and the winners earn the right to “breed” new AIs (passing on a mix of both parents’ functions) while the losers get culled from the population.

So in July 2016, I was just getting AIs to battle one another. Fast forward to July 2017, and I had:

  • A feature-rich Trainer with dozens of options, including support for running multiple battles concurrently on different processors
  • A refactored AI, making it much easier to validate that I was implementing the algorithms properly
  • Some key performance tests to evaluate changes to the core code

I had also spent several hundreds of hours of computing time in running experiments with the Trainer. Hundreds of AIs lived and died as I tweaked parameters and followed the most successful AIs (and their children). But by July 2017 I stepped away from Mzinga and started spending my spare time on other projects.

Then around December of last year, having not touched Mzinga for months, I suddenly had the inspiration for how to fix a particular performance bug I’d had, and by the start of the new year, I was back on the Mzinga bandwagon.

Since I’d spent so much time on the Trainer, from a regular user’s perspective, Mzinga hadn’t changed much since 2016. The Viewer (where you can actually play games) had seen some minor bug fixes, and while the Engine (with the core of the game and the AI), was technically faster and stronger, I doubt it was noticeable to most players. I regularly lose to people playing for the first time, and I could still beat the Mzinga AI.

I spent most of January focused on code performance – nothing AI-specific, nothing that needed any study or research, just analyzing the code and removing every little bottleneck I could find.

Then, after nearly eight years on my venerable, dual-core laptop, I finally bit the bullet and bought a new PC. A custom, fancy, rocking, eight-core beast with horsepower to spare. And wouldn’t you know, suddenly I had an interest in hitting the old chess AI sites and researching how the best chess AIs take advantage of multiple processors.

Now Mzinga’s AI is starting to get fancy:

  • It spreads its search across multiple processors, via “Lazy SMP”
  • It searches during your turn instead of waiting, aka “Pondering”
  • When it finds the “best move”, it peeks just a little further ahead to make sure, via “Quiescence Search”
  • It keeps you updated each time it finds a better move

On top of all that, everything is all nice and asynchronous, meaning I can cancel a search when I want to. I don’t have to say, “search 2 moves deep” or “search for 5 seconds” and then sit and wait for it to stop. If I want to stop it early, I can. If I want to just let it search, I can, and stop it when I’m good and ready.

Now sometimes the AI beats me.

I’ve also started addressing the Mzinga Viewer:

  • It’s faster and more responsive
  • It’s finally got some options, so you can tweak your experience:
    • Do you like your pieces with the flat or the pointy side up?
    • Do you want pieces that can’t move to be “grayed-out”?
    • Do you want to see certain things highlighted, like your opponents last move or what the valid moves are?

Some of these features are new, but some already existed in the Viewer and were always on because I liked them. Now you can turn them off if you don’t.

These are just a taste of how much Mzinga has changed, and there’s still more to come! Check it out today if you haven’t and send your feedback my way!

Stay tuned,

/jon