If you start with the center, the rest is simple, and the "AI" wouldn't even have to be aware of the entire board at any moment.
So, if you start like this:
The player "should" do this (though my idea works no matter where they play):
Your strategy is to find the last empty slot of the array, using rotations to convert as you need.
if you number the board like this:
Code:
[1 2 3
4 5 6
7 8 9]
if player plays at 1, you find the last empty slot on [1 2 3], or if player plays at 3, find the last empty slot at [3 6 9], if 9, then [9 8 7], if 7, [7 4 1].
If 1 and 3 are filled out on [1 2 3], then you would find the last empty, which is 2. The rest of the arrays work the same, but perhaps some math would help with this. Building a function that checks of +3, -3, +1, -1 are valid for any array, wouldn't be too difficult to create.
It's going to tie after 2 moves I think, so can probably just randomly play after that. You don't need to solve the entire game tree as long as you know when a tie is guaranteed.
I haven't put much thought outside of playing the center first. Well.. haven't put a lot of thought into this at all, but this is how I'd start.