1. Build the entire game tree, evaluating each terminal node, and backing the result up the tree (minimax). This finds 549945 possible board positions, each one with a game result.
2. To make life easier for a linear polynomial to express the result from any position, those 549945 positions were split into groups based on number of men on the board, nine groups.
3. To make life even easier, each group was cut down to remove all symmetrical positions. For example, at ply one, there are 9 positions, but this reduces to 3 once symmetries are taken out. Ply 5 reduces from 15120 positions to 174 and so on.
print("Noughts and crosses")
print("===================")
print("total possible boards from start position 549945")
print("ply 1 total non-mirror boards 3 of 9")
print("ply 2 total non-mirror boards 12 of 72")
print("ply 3 total non-mirror boards 38 of 504")
print("ply 4 total non-mirror boards 108 of 3024")
print("ply 5 total non-mirror boards 174 of 15120")
print("ply 6 total non-mirror boards 204 of 54720")
print("ply 7 total non-mirror boards 154 of 148176")
print("ply 8 total non-mirror boards 59 of 200448")
print("ply 9 total non-mirror boards 15 of 127872")
print()
4. For each ply depth, a network was (relatively exhaustively) trained, with position as input (18 cells, first 9 set to 1 if 'O', second nine set to 1 if 'X', and game result either 0.0, 0.5 or 1.0
5. First results are for a network with no hidden layer, eg a linear polynomial. At nply=1, a network will produce constant results, of course, all ply one positions are draws. A linear polynomial can disentangle the 12 cases at ply 2, and the 15 cases at ply 9, but intermediate plies not.
print("Results, no hidden layer, 2x9 inputs")
print("====================================")
print("nply 1 cases 3 errors 0")
print("nply 2 cases 12 errors 0")
print("nply 3 cases 38 errors 6")
print("nply 4 cases 108 errors 22")
print("nply 5 cases 174 errors 98")
print("nply 6 cases 204 errors 78")
print("nply 7 cases 154 errors 85")
print("nply 8 cases 59 errors 36")
print("nply 9 cases 15 errors 0")
print()
6. Next, a hidden layer is added (9 neurons). This improves the results, but is still not able to resolve the all non-linearities.
# 18 x 9 x 1 lots of errors
print("Results, one hidden layer of 9, 2x9 inputs")
print("==========================================")
print("nply 1 cases 3 errors 0")
print("nply 2 cases 12 errors 0")
print("nply 3 cases 38 errors 0")
print("nply 4 cases 108 errors 12")
print("nply 5 cases 174 errors 8")
print("nply 6 cases 204 errors 5")
print("nply 7 cases 154 errors 10")
print("nply 8 cases 59 errors 0")
print("nply 9 cases 15 errors 0")
print()
7. Increasing the hidden layer size gives better results, but still some errors. Possibly more runs or tweaking learning rate and so on might reduce errors to zero. I'ld posit that the non-linearities are relatively non-trivial, even for tic-tac-toe, if they need more hidden layer width to resolve.
# 18 x 18 x 1 still a few errors
print("Results, one hidden layer of 18, 2x9 inputs")
print("===========================================")
print("nply 1 cases 3 errors 0")
print("nply 2 cases 12 errors 0")
print("nply 3 cases 38 errors 0")
print("nply 4 cases 108 errors 0")
print("nply 5 cases 174 errors 0")
print("nply 6 cases 204 errors 2")
print("nply 7 cases 154 errors 1")
print("nply 8 cases 59 errors 0")
print("nply 9 cases 15 errors 0")
print()
8. Doubling again the hidden layer size, but still some errors.
# 18 x 36 x 1 still a few errors
print("Results, one hidden layer of 36, 2x9 inputs")
print("===========================================")
print("nply 1 cases 3 errors 0")
print("nply 2 cases 12 errors 0")
print("nply 3 cases 38 errors 0")
print("nply 4 cases 108 errors 0")
print("nply 5 cases 174 errors 1")
print("nply 6 cases 204 errors 2")
print("nply 7 cases 154 errors 0")
print("nply 8 cases 59 errors 0")
print("nply 9 cases 15 errors 0")
9. Adding another hidden layer (8 neurons) and errors still there.
# still some errors with an added hidden layer
print("Results, two hidden layers of 18 x 8, 2x9 inputs")
print("======================================")
print("nply 1 cases 3 errors 0")
print("nply 2 cases 12 errors 0")
print("nply 3 cases 38 errors 0")
print("nply 4 cases 108 errors 0")
print("nply 5 cases 174 errors 0")
print("nply 6 cases 204 errors 2")
print("nply 7 cases 154 errors 0")
print("nply 8 cases 59 errors 0")
print("nply 9 cases 15 errors 0")
print()
10. Create non-linear inputs (NNUE style) and try that ....
Probably won't bother. If tac-tac-toe has non-trivial non-linearities, then the extension to the idea that a linear polynomial operating on (undefined, unknown) non-linear inputs could be created to solve the vastly more complex game of chess doesn't have much going for it.
Ply six example input data with game result.
Code: Select all
O X O X O X . . . , -1
O X O X O . X . . , -1
O X O X O . . X . , -1
O X O X O . . . X , -1
O X O X X O . . . , -1
O X O X . O X . . , -1
O X O X . O . X . , -1
O X O X . O . . X , 0
O X O X X . O . . , 1
O X O X . X O . . , -1
O X O X . . O . X , -1
O X O X X . . O . , 0
O X O X . X . O . , -1
O X O X . . X O . , -1
O X O X . . . O X , 0
O X O X X . . . O , -1
O X O X . . X . O , -1
O X O X . . . X O , -1
O X O O X . X . . , 0
O X O O X . . X . , 1
O X O O X . . . X , -1
O X O . X . O X . , 1
O X O . X . O . X , -1
O X O . X . X O . , 0
O X O O . . X X . , 1
O X O O . . X . X , 0
O X O . O . X X . , -1
O X O . O . X . X , 0
O X O . . O X X . , -1
O X O . . . X O X , 0
O X O . . . X X O , -1
O X X O O X . . . , -1
O X X O O . X . . , -1
O X X O O . . X . , -1
O X X O O . . . X , -1
O X X O X O . . . , -1
O X X O . O X . . , -1
O X X O . O . X . , -1
O X X O . O . . X , -1
O X X O X . . O . , -1
O X X O . X . O . , -1
O X X O . . X O . , -1
O X X O . . . O X , -1
O X X O X . . . O , -1
O X X O . X . . O , -1
O X X O . . X . O , -1
O X X O . . . X O , -1
O X . O X O X . . , 1
O X . O X O . X . , 1
O X . O X O . . X , -1
O X . O X X . O . , -1
O X . O X . X O . , 0
O X . O X . . O X , -1
O X . O X X . . O , -1
O X . O X . X . O , 1
O X . O X . . X O , 1
O X . O O X X . . , -1
O X . O O X . X . , -1
O X . O O X . . X , -1
O X . O . X X O . , 0
O X . O . X . O X , -1
O X . O . X X . O , -1
O X . O . X . X O , -1
O X . O O . X X . , -1
O X . O O . X . X , -1
O X . O . O X X . , -1
O X . O . O X . X , -1
O X . O . . X O X , 0
O X . O . . X X O , -1
O X . O O . . X X , -1
O X . O . O . X X , -1
O X X X O O . . . , -1
O X X . O O X . . , -1
O X X . O O . X . , -1
O X X . O O . . X , -1
O X X . O X O . . , -1
O X X . O . O X . , -1
O X X . O . O . X , -1
O X X X O . . O . , -1
O X X . O X . O . , -1
O X X . O . X O . , -1
O X X . O . . O X , 0
O X . X O O . X . , -1
O X . X O O . . X , 0
O X . . O X O X . , -1
O X . . O X O . X , -1
O X . . O X X O . , -1
O X . . O X . O X , 0
O X . . O O X X . , -1
O X . . O O X . X , -1
O X . . O . X O X , 0
O X . . O O . X X , -1
O X X . X O O . . , -1
O X X . . O O X . , -1
O X X . . O O . X , -1
O X X X . O . O . , -1
O X X . X O . O . , -1
O X X . . O X O . , -1
O X X . . O . O X , -1
O X X X . O . . O , -1
O X X . X O . . O , 1
O X X . . O X . O , -1
O X . X X O . O . , -1
O X . X . O . O X , 0
O X . X X O . . O , -1
O X . X . O X . O , -1
O X . . X O O X . , 1
O X . . X O O . X , -1
O X . . X O X O . , 0
O X . . X O . O X , 0
O X . . X O X . O , -1
O X . . . O X O X , 0
O X X . X . O O . , -1
O X X . . X O O . , -1
O X X . . . O O X , -1
O X X . X . O . O , -1
O X X . . X O . O , -1
O X . . X X O O . , -1
O X . . X . O O X , -1
O X . . X X O . O , -1
O X . . . X O O X , -1
O X X . X . . O O , -1
O X X . . . X O O , -1
O X . . X . X O O , 0
O O X O X X . . . , -1
O O X O X . X . . , 1
O O X O X . . X . , -1
O O X O X . . . X , -1
O O X . X O X . . , 1
O O X . X O . X . , 0
O O X . X O . . X , 0
O O X . X X O . . , -1
O O X . X . O . X , -1
O O X . X X . O . , 1
O O X . X . X O . , 1
O O X . X . . O X , 1
O O X . X . X . O , 1
O O X O . X X . . , 1
O O X O . X . X . , -1
O O X O . X . . X , 1
O O X . O X X . . , -1
O O X . O X . X . , -1
O O X . O X . . X , 1
O O X . . X O . X , 1
O O X . . X X O . , -1
O O X . . X . O X , 1
O O X O . . X . X , 1
O O X . O . X X . , -1
O O X . O . X . X , -1
O O X . . O X X . , 1
O O X . . O X . X , 1
O O X . . . X O X , -1
O O X O . . . X X , -1
O O X . O . . X X , 1
O O X . . O . X X , 0
O . X O X O . X . , -1
O . X O X O . . X , -1
O . X O X X . O . , -1
O . X O X . . O X , -1
O . X O O X . X . , -1
O . X O O X . . X , 1
O . X O . X . O X , 1
O . X O O . . X X , -1
O . X O . O . X X , -1
O . X . O X O . X , 1
O . X . O X X O . , -1
O . X . O X . O X , 1
O . X . O O X . X , -1
O . X . O O . X X , -1
O . X . X O O . X , -1
O . X . X O X O . , 1
O . X . X O . O X , 0
O . X . . O X O X , -1
O . X . X X O O . , -1
O O . O X X . X . , -1
O O . O X X . . X , -1
O O . . X X . O X , -1
O O . . X O . X X , -1
O O . O . X . X X , -1
O O . . O X . X X , -1
X O X O O X . . . , -1
X O X O O . X . . , -1
X O X O O . . X . , -1
X O X O O . . . X , -1
X O X O X O . . . , 1
X O X O . O X . . , -1
X O X O . O . X . , -1
X O X O X . . O . , 1
X O X O . X . O . , -1
X O X O . . . O X , -1
X O . O X O . X . , 0
X O . O X O . . X , 1
X O . O O X . X . , 0
X O . O O X . . X , -1
X O . O . X . O X , -1
X O . X O O X . . , 1
X O . X O O . X . , 0
X O . X O O . . X , -1
X O . . O O X X . , -1
X O . . O O X . X , -1
X O . X X O . O . , 1
X O . X . O X O . , 1
X O . . X O X O . , 1
. O . X O O X X . , 1