如何在二维数组中使用随机选择位置



我创建了一个井字游戏程序,它允许玩家通过选择绳索在2d阵列中选择移动,然后计算机进行移动。

该程序可以工作,但计算机的移动是顺序的,而不是随机的,并且将始终选择阵列中的下一个可用空间。现在我有了这个游戏,我想把程序提高到三个难度级别:

Easy=计算机随机生成的移动Medium=由计算机随机生成的移动,检查以阻挡玩家并完成线路Hard=每次通过递归选择最佳移动

如何让计算机在阵列中随机选择一组跳线?

(我当前基本的计算机循环移动)

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

创建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)的后续调用产生除当前值之外的其他值。

由于计算机无法选择所有字段,因此需要一个两步过程

  • 计算可用字段的数量(=:N)
  • 创建一个在0..N-1范围内的随机数
  • 使用此数字选择字段

当玩家或AI从列表中删除坐标时,保留一个自由坐标列表。根据列表中的项目数进行随机化,因此,如果列表中有5个条目,则会生成一个介于1和5之间的随机数,从列表中选择坐标。

或者更简单地跟踪自由坐标的数量,例如,你有5个自由坐标,生成一个数字1-5,然后在棋盘上迭代,得到第5个位置的

最新更新