我有一个项目列表,该列表由玩家在几个输入字段中输入的内容确定,但是出于这个示例的原因,我们假设它包含“ a”,“ b”,“ c”,“ d”和“ e”。然后将它们分类到字典中,并以数字列表作为值(不重要)。然后,我使用两个不同的随机变量(i和j)对字典进行随机化,以便从字典中获取两个对象并将它们显示在屏幕上,以便玩家可以按下各种关联的按钮。一直持续到转过x圈。 主要问题,我遇到的问题是防止半重复出现,例如“ a b”和“ b a”。
我尝试将随机对及其半重复插入到另一个字典中,然后使用while循环语句来防止该字典中的任何对出现。不幸的是,这没有用。
下面是我的代码。
public void Start() {
finalList = new Dictionary<string, int>();
for (index = 0; index < allNumbers; index++)
{
finalList.Add(itemList[index], valueList[index]);
Debug.Log(finalList[index.ToString()]);
}
}
public void Update() {
choose();
}
public void choose() {
duplicates = new Dictionary<string, string>();
duplicates.Clear();
while (rounds < insertNum) {
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
while (j == i || (duplicates.ContainsKey(key) || duplicates.ContainsKey(reverseKey))) {
i = UnityEngine.Random.Range(0, allNumbers - 1);
j = UnityEngine.Random.Range(0, allNumbers - 1);
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
Debug.Log("(new keys " + key + ", " + reverseKey + ")");
//break;
} while (j == i || (duplicates.ContainsKey(key) && duplicates.ContainsKey(reverseKey)))
{
i = UnityEngine.Random.Range(0, allNumbers - 1);
j = UnityEngine.Random.Range(0, allNumbers - 1);
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
Debug.Log("(new keys " + key + ", " + reverseKey + ")");
}while (j == i && (duplicates.ContainsKey(key) || dupes.ContainsKey(reverseKey))) {
i = UnityEngine.Random.Range(0, allNumbers - 1);
j = UnityEngine.Random.Range(0, allNumbers - 1);
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
Debug.Log("(new keys " + key + ", " + reverseKey + ")");
}
while (j == i && (duplicates.ContainsKey(key) && duplicates.ContainsKey(reverseKey))) {
i = UnityEngine.Random.Range(0, allNumbers - 1);
j = UnityEngine.Random.Range(0, allNumbers - 1);
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
Debug.Log("(new keys " + key + ", " + reverseKey + ")");
}
duplicates.Add(key, "1"); // the one is just a filler variable
duplicates.Add(reverseKey, "1");
if (buttonOneBool) { //this is in another script, ignore
finalList[itemList[i].ToString()] = valueList[i] += 2;
finalList[itemList[j].ToString()] = valueList[j] -= 2;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonTwoBool) {
finalList[itemList[i].ToString()] = valueList[i] -= 2;
finalList[itemList[j].ToString()] = valueList[j] += 2;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonThreeBool) {
finalList[itemList[i].ToString()] = valueList[i] -= 1;
finalList[itemList[j].ToString()] = valueList[j] -= 1;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonFourBool) {
finalList[itemList[i].ToString()] = valueList[i] += 1;
finalList[itemList[j].ToString()] = valueList[j] += 1;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
}
break;
}
答案 0 :(得分:0)
解决此问题的最简单方法是保证i < j
。当选择一个新的i和j时:
i = UnityEngine.Random.Range(min, max);
j = UnityEngine.Random.Range(min, max);
相反,这样做:
i = UnityEngine.Random.Range(min, max - 1);
j = UnityEngine.Random.Range(i + 1, max);
这样做排除了选择前一种情况的“镜像”的可能性,并且避免了“ i == j”的情况。
进行这些修改后,您的choice()函数应如下所示:
public void choose()
{
duplicates = new HashSet<string>();
while (rounds < insertNum)
{
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
while (duplicates.Contains(key))
{
i = UnityEngine.Random.Range(0, allNumbers - 2);
j = UnityEngine.Random.Range(i + 1, allNumbers - 1);
key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
}
duplicates.Add(key); // the one is just a filler variable
if (buttonOneBool) { //bool definitions are in another script, ignore
finalList[itemList[i].ToString()] = valueList[i] += 2;
finalList[itemList[j].ToString()] = valueList[j] -= 2;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonTwoBool) {
finalList[itemList[i].ToString()] = valueList[i] -= 2;
finalList[itemList[j].ToString()] = valueList[j] += 2;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonThreeBool) {
finalList[itemList[i].ToString()] = valueList[i] -= 1;
finalList[itemList[j].ToString()] = valueList[j] -= 1;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
} else if (buttonFourBool) {
finalList[itemList[i].ToString()] = valueList[i] += 1;
finalList[itemList[j].ToString()] = valueList[j] += 1;
i = UnityEngine.Random.Range(0, n - 1);
j = UnityEngine.Random.Range(0, n - 1);
}
break;
}
}
答案 1 :(得分:0)
您可以使用以下代码将两个随机索引添加到列表中。该代码使用整数作为列表类型,并且可以使用任何类型。
List<int> randomList = itemList.Select((x, i) => new { index = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.index).ToList();
然后,列表中的两个随机索引是randomList [0]和randomList [1]。该代码为列表的每个索引i分配一个随机数。要从列表中获得两个项目,请使用itemList [randomList [0]]和itemList [randomList [1]]。该代码假定原始列表ItemList []中至少有两个项目。
如果原始列表重复,则需要使用Distinct(),如下面的代码所示
List<int> distinctList = itemList.Distinct().ToList();
List<int> randomList = distinctList.Select((x, i) => new { index = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.index).ToList();