Something is wrong with the way I am calculating the 'best move'. My plan was to have every winning option score a number of points equal to the number of free spaces on the board.
So let's say it finds a spot where it can win with 3 empty spaces on the board. This spot has a score of 3. In reality the numbers end up much much larger due to the recursion as it finds multiple winning options from the same initial move.
I tried to have an opponent winning make a negative score, as in you don't want to go there. But this ended up with the effect of 'the opponent can win here so I better not block his win'. Stupid...
Tried changing this to increasing the number but then that doesn't work as well as I had hoped either.
Going to get rid of the how many spaces left option and instead will take into account the number of recursive calls to get to this point. I think I'm going to try put the negative thing back in and then have it decide which to choose based on the number furthest from zero (absolute value).
Also had some trouble with stack overflows so have had to limit the number of recursions. At the moment 7 steps in seems enough. Bear in mind that for every step it create another 7 boards. So this gets quite big quite fast.
tl:dr: I have no idea what I am doing at this point and am trying random things until I get something about right.