我创建了一个tic tac toe程序,它允许玩家通过选择绳索选择二维阵列中的移动,然后计算机移动。
该程序有效,但计算机的移动是顺序的,而不是随机的,并且将始终选择阵列中的下一个可用空间。现在我已经开始运行游戏,我希望将程序改进为三个难度级别:
Easy =通过计算机随机生成的移动 中=由计算机随机生成的移动,用于检查阻止播放器和完整线路 硬=每次通过递归选择最佳移动
如何让计算机随机选择阵列中的一组线?
(我目前基本的计算机循环移动)
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
答案 0 :(得分:2)
创建Random
类的新实例,并使用Next()
方法创建表示坐标的两个随机数。
以下是代码:
var r = new Random();
var randomX = r.Next(3);
var randomY = r.Next(3);
<强>更新强>
以下是该方法的外观:
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';
}
我发现导致StackOverflowException
的问题。这是一个相当微妙的结论,但结论是,当重试生成随机坐标时,应使用相同的Random
实例,而不是创建新实例。
这是因为Random
并不真正生成真正的随机数。创建new Random()
实例时,将使用基于当前时间的种子值对其进行初始化。
如果使用相同的种子值创建多个Random
实例,它们将创建相同的随机数流。
在我们的示例中,如果我们需要生成新的随机坐标,则会创建一个新的Random实例而不指定种子,因此种子使用当前时间。由于随机实例创建速度极快,种子值相同,因此随机值相同,导致无限递归。
我已经重写了重用random
实例的方法,这导致后续调用Next(3)
产生的值不是我们现有的值。
答案 1 :(得分:0)
由于计算机无法选择所有字段,因此您需要一个两步过程
答案 2 :(得分:0)
保留一个自由坐标列表,无论何时任何一个玩家选择坐标或AI从列表中删除它。根据列表中的项目数进行随机化,因此如果列表中有5个条目生成1到5之间的随机数,请从列表中选择坐标。
或者更简单地跟踪自由坐标的数量,例如你有5个自由坐标产生数字1-5并且只是在板上迭代以到达第5个位置