Chess Devlog: Perft Testing

Tags: Technology

Just wanted to give an update on a cool little thing I learned about recently. phaul21 brought to my attention that I had no perft testing in my library.

Perft testing is essentially generating a tree of positions based on all the legal moves that can be made. Then by counting the leaf nodes you can compare the results of your move generation to others. If they differ you have likely made a mistake as either too many, or too few moves are being generated. And when you are generating 6 or more moves deep you are looking at hundreds of millions of possibilities, so the chances of getting a false positive are fairly low.

In my mind the big advantage of this new test was ensuring that my move generation did not generate too many moves. PGN parsing does a pretty good job of making sure I don't generate too few moves.

The code itself was fairly simple to implement:

func TestMovegenPerft(t *testing.T) {
	perftTesters, err := parsePerftFile()
	if err != nil {
		t.Fatalf("%v", err)
	}

	for i, tester := range perftTesters {
		t.Logf("perft test %d/%d", i, len(perftTesters))
		name, _ := tester.pos.MarshalText()
		t.Run(string(name), func(t *testing.T) {
			tester.Test(t)
		})
	}
}

The best part was that I didn't have to change my move generation. Maybe I just didn't implement the test correctly, or maybe I'm just that good. Either way this is another great test to have. I was surprised I didn't know about it before.