Apart from optimising your code, there are a couple of simple and generic (I mean valid for any MCTS) things that you can do to improve your bot:
- Smarter rollouts: If you have a winning move, play it. If you can prevent your opponent to play a winning move, do it
- Solver: when a game nears the end, while building the tree, you reach terminal nodes. If you have a win, it means the previous move was losing. If all possible moves lead to a loss, it means the previous move was winning. This way, you can back-propagate proven results and avoid exploring again solved nodes. This is quite effective: usually you can predict the result of a game 10 or more moves before the end. There are two useful papers to read: “Monte-Carlo Tree Search Solver” and “Score Bounded Monte-Carlo Tree Search”