I have created a tic tac toe program that works in that it allows a player to select a move in a 2d array by selecting the cords, then the computer makes a move.
The program works, but the computer's move is sequential rather then random and will always select the next available space in the array. Now that I have the game working, I want to improve the program into three levels of difficulty:
Easy = Randomly generated move by computer Medium = Randomly generated move by computer that checks to block player and complete line Hard = Selection of optimal move every time through recursion
How I can get the computer to randomly select a set of cords in my array?
(My current basic for loop for computers move)
static void Computermove(char[,] gamegrid, char fin)
{
Console.WriteLine("\nComputer's turn");
Console.ReadKey();
int x = 0;
int y = 0;
for (x = 0; x < 2; x++)
{
for (y = 0; y < 2; y++)
if (gamegrid[x, y] == ' ') break;
if (gamegrid[x, y] == ' ') break;
}
if (x * y == 9)
{
fin = 'X';
}
else
gamegrid[x, y] = 'O';
} // End Computermove
Create a new instance of the Random
class and use the Next()
method to create the two random numbers representing the coordinates.
Here's the code:
var r = new Random();
var randomX = r.Next(3);
var randomY = r.Next(3);
Update:
Here's how the method could look like:
static void Computermove(char[,] gamegrid, char fin)
{
if (!ContainsEmptyCells(gamegrid))
{
// table is full; probably nobody won
return;
}
bool goodRandomCoordinateFound = false;
int row = 0, column = 0;
var random = new Random();
while (!goodRandomCoordinateFound)
{
row = random.Next(3);
column = random.Next(3);
if(gamegrid[row, column] == ' ')
goodRandomCoordinateFound = true;
}
gamegrid[row, column] = 'O';
}
I found the problem that was causing the StackOverflowException
. It is a pretty subtle one, but the conclusion is that when retrying to generate random coordinates, the same instance of Random
should be used, instead of creating a new one.
This is because Random
does not really generate truly random numbers. When a new Random()
instance is created, it is initialized with a seed value that is based on the current time.
If you create multiple instances of Random
with the same seed value, they will create the same random numbers stream.
In our example, in case we needed new random coordinates to be generated, a new instance of Random was created without specifying a seed, so the seed was using the current time. Due to the fact that the random instances were created extremely quickly, the seed value was the same, therefore the random values were the same, causing infinite recursion.
I've rewritten the method to reuse the random
instance, which causes subsequent calls to Next(3)
to yield other values than the ones we currently have.