The code is not very pretty at this stage, but it is typical of projects that I've done. While I'm still getting things to work, there are lots of extra print statements, and there are places where a similar operation is repeated, just because that seemed to be faster to write. We'll sort it out later. The main thing is to look carefully at the output to check that when we reject "duplicates" and "permutations" the decision is correct.
Here is a small part of the output at round 3:
A partial list of the mistakes from before (and the dups) is:
By my count now, we have 53 possible boards at stage 3. Next, going on to stage 4. But first we will have to analyze the boards for forced moves.