C# 以随机生成的方式从列表中排除数字



我正在制作一个井字游戏,我正在使它变得无与伦比 但首先我必须让计算机知道规则。

我被困在一个步骤=>轮到计算机并且我们刚刚开始游戏时,所以没有获胜的情况,所以由计算机生成一个随机数,这将是计算机的选择(他标记X或O的块( 所以我需要它来生成一个从 1 到 9 的数字,但要排除已经使用的块(数字(。

我尝试通过制作一个列表并在每次人类玩家使用块时添加一个数字来做到这一点,但我找不到一种方法来使用这些列表中的数字作为随机选择计算机的排除。

这是我尝试过的,并提前感谢:

//random
List<int> cas = new List<int>();
if (c1 == true)
{
cas.Add(1);
}
if (c2 == true)
{
cas.Add(2);
}
if (c3 == true)
{
cas.Add(3);
}
if (c4 == true)
{
cas.Add(4);
}
if (c5 == true)
{
cas.Add(5);
}
if (c6 == true)
{
cas.Add(6);
}
if (c7 == true)
{
cas.Add(7);
}
if (c8 == true)
{
cas.Add(8);
}
if (c9 == true)
{
cas.Add(9);
}

for (int i = 0; i < cas.Count; i++)
{
random_except_list(cas[]);
}
public static int random_except_list(int[] x)
{
Random r = new Random();
int result = r.Next(1, 9 - );
for (int i = 0; i < x.Length; i++)
{
if (result < x[i])
return result;
result++;
}
return result;
}

让我们有可能的地方使用:

List<int> possible = Enumerable.Range(1,9).ToList(); // create a list and add 1-9

和使用过的场所:

List<int> used = new List<int>();
Random rnd = new Random();

现在,每次我们在列表计数为索引的范围内生成一个随机数possible并将其从那里删除并将其移动到已使用:

int index = rnd.Next(0, possible.Count);
used.Add(possible[index]);
possible.RemoveAt(index); 

对于用户来说,它足以检查它是否存在于使用中,因此可接受的数字应该是:

!used.Any(x=> x== NumberUserHaveChosen)

所以第一次随机数可以是0-8(尽可能。计数==9(并以随机索引从中获取。 第二次随机数可以是 0-7(尽可能。计数==8(并以随机索引从中获取。 等等...而possible.Count != 0

在这种情况下,无需多次生成随机数,最终它不会存在于我们使用的列表中。

几年前,我正在研究一种数独算法,我试图实现的是在尽可能短的时间内生成一个有效的已解决数独表,我得出的结论是,我应该替换算法,每次生成一个数字时,我都必须检查一些列表以确保之前没有生成该数字, 随着数字数量的增加,这些比较将变得越来越多。例如,当只剩下数字 4 时,我应该生成随机数,直到得到 4。所以我使用了这种方法,结果是惊人的。

我认为你应该做这样的事情:

public static int random_except_list(List<int> x)
{
Random r = new Random();
int result = 0;
while (true)
{
result = r.Next(1, 10);
if (!x.Contains(result))
return result;                
}
}

只是尝试使用您编写的内容(或多或少(,但更改方法以采用您正在构建的List<int>,我会像这样使用 LINQ 编写该方法(除了我会创建一个静态Random变量并在调用之间保留它(:

public static int random_except_list(List<int> x) => Enumerable.Range(1, 9).Where(n => !x.Contains(n)).ToList()[new Random().Next(0, 9 - x.Count)];

但是,您可以使用过程代码以更明确的方式实现相同的想法:

public static int random_except_list_explicit(List<int> x) {
// First, generate a list of possible answers by skipping the except positions in x
var possibles = new List<int>();
for (int i = 1; i <= 9; i++)
if (!x.Contains(i))
possibles.Add(i);
// now pick a random member of the possible answers and return it
return possibles[new Random().Next(0, possibles.Count)];
}

我认为最好使用左边的位置。因此,用户或计算机从所有空缺职位中进行选择:

using System;
using System.Collections.Generic;
class app
{
public static int random_except_list(List<int> openPositions)
{
Random r = new Random();
int index = r.Next(openPositions.Count - 1);
int result = openPositions[index];
openPositions.RemoveAt(index);
return result;
}
static void Main()
{
List<int> openPositions = new List<int>();
for (int i = 1; i < 10; i++)
{
openPositions.Add(i);
}
bool turn = false;
while (openPositions.Count > 0)
{
foreach (int value in openPositions)
{
Console.Write(value + " ");
}
Console.WriteLine();
if (!turn)
{
while (true)
{
Console.WriteLine("Choose your Position");
ConsoleKeyInfo key = Console.ReadKey();
int num = (int)key.KeyChar - 48;
if (openPositions.Contains(num))
{
openPositions.Remove(num);
Console.WriteLine();
break;
}
else Console.Write(" is not Valid: ");
}
}
else
{
int compPos = random_except_list(openPositions);
Console.WriteLine("Computer choose: " + compPos);
}
turn = !turn;
}
Console.WriteLine("No positions left");
Console.ReadKey();
}
}

最新更新