You could reduce that to very acceptable levels by creating a list of free coordinates and getting a random index in that collection. Conceptually:
#include <vector>
struct tictactoe_point
{
int x, y;
};
vector<tictactoe_point> legal_points;
tictactoe_point point;
for (point.x = 0; point.x < 3; point.x++)
{
for (point.y = 0; point.y < 3; point.y++)
{
if (game.isLegalMove(point.x, point.y))
{
legal_points.push_back(point);
}
}
}
point = legal_points[rand() % legal_points.size()];
game.makeMove(point.x, point.y, ai);
moveMade = true;
This solution is not optimal, but it's a significant improvement: now, the time it takes to make a move is fully predictable. This algorithm will complete with one single call to rand
.
The fact that you call srand
each time you pick a number makes the process even slower, but then again, the major problem is that your current solution has to try over and over again. It's not bounded: it may even never complete. Even if srand
is considerably slow, if you know that it'll run just one time, and not an indefinite number of times, it should be viable (though not optimal either).
There are many ways to improve on this:
- Keep a list of valid coordinates to play, and remove the coordinates when either the player or the AI plays it. This way you don't have to rebuild the list at every turn. It won't make a big difference for a tic-tac-toe game, but it would make a big difference if you had a larger board.
- Use the standard C++ random function. This isn't really an algorithm improvement, but
rand()
in C is pretty crappy (I know, I know, it's a long video, but this guy really really knows his stuff).