索引超出范围....但它似乎并没有超出范围,那么发生了什么?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CardDealer
{
class Deck
{
string[] deck = new string[52];
string[] name = new string[13];
string[] suits = new string[4];
public Deck()
{
name[0] = "Ace ";
name[1] = "Two ";
name[2] = "Three ";
name[3] = "Four ";
name[4] = "Five ";
name[5] = "Six ";
name[6] = "Seven ";
name[7] = "Eight ";
name[8] = "Nine ";
name[9] = "Ten ";
name[10] = "Unterknave ";
name[11] = "Oberknave ";
name[12] = "King ";
suits[0] = "of Hearts";
suits[1] = "of Bells";
suits[2] = "of Acorns";
suits[4] = "of Leaves";
for (int i = 0; i < 13; i++)
{
deck[i] = name[i] + suits[0];
}
for (int i = 0; i < 13; i++)
{
deck[i + 13] = name[i] + suits[1];
}
for (int i = 0; i < 13; i++)
{
deck[i + 26] = name[i] + suits[2];
}
for (int i = 0; i < 13; i++)
{
deck[i + 39] = name[i] + suits[3];
}
}
Random rnd = new Random();
int cardsLeft = 52;
public void Shuffle()
{
string[] deck = new string[52];
for (int i = 0; i < 13; i++)
{
deck[i] = name[i] + suits[0];
}
for (int i = 0; i < 13; i++)
{
deck[i + 13] = name[i] + suits[1];
}
for (int i = 0; i < 13; i++)
{
deck[i + 26] = name[i] + suits[2];
}
for (int i = 0; i < 13; i++)
{
deck[i + 39] = name[i] + suits[3];
}

string[] myrandomarray = deck.OrderBy(x => rnd.Next()).ToArray();
deck = myrandomarray;
cardsLeft = 52;
}

public string Deal()
{
string deltCard = deck[0];
cardsLeft--;
string[] newDeck = new string[cardsLeft];
for (int i = 0; i < cardsLeft + 1; i++)
{
if (deck[i] != deltCard)
{
newDeck[0] = deck[i];
}
}
deck = newDeck;
return deltCard;


}

}
class play
{
static void Main()
{
Deck mydeck = new Deck();
Console.WriteLine(mydeck.Deal());

}
}

}

嘿伙计们,我的代码在这里遇到了麻烦。有两个类,一个构造一副牌,另一个玩它。当我执行此代码时,它会抛出一个错误(范围超出索引(但我只是没有看到它,就像我不知道它是如何超出范围一样,它向我展示了它超出范围的地方,但它似乎没有超出范围,所以发生了什么?

您缺少索引 3,而是有 4:

suits[0] = "of Hearts";
suits[1] = "of Bells";
suits[2] = "of Acorns";
suits[4] = "of Leaves";

将最后一行更改为:

suits[3] = "of Leaves";

不要显式放置索引:

string[] suits = new string[4];
...
suits[0] = "of Hearts";
suits[1] = "of Bells";
suits[2] = "of Acorns";
suits[4] = "of Leaves";  // <- it must be "3", not "4"

但使用初始值设定项

// create array with items mentioned
string[] suits = new string[] {
"of Hearts", 
"of Bells", 
"of Acorns", 
"of Leaves"
};

编译器为您完成日常工作。与namedeck相同:

// Let's get rid of trailing spaces
string[] name = new string[] {
"Ace", 
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Unterknave",
"Oberknave",
"King",
};
// as well as pesky "of": suit "Acorns" or "Clubs", not "of Acorns"
string[] suits = new string[] {
"Hearts",
"Bells",
"Acorns",
"Leaves",
};
string[] deck;
public Deck() {
// All combinations of name and suits (cartesian join)
// Avoid magic numbers like 13 (some games like preference has 8 cards in a suit)
deck = name
.SelectMany(n => suits.Select(s => $"{n} of {s}")) // <- space and "of" here
.ToArray();

suits[4] = "of Leaves";

应该是

suits[3] = "of Leaves";

虽然你已经对你的问题有了直接的答案,但我可以提供一些代码改进,让你的生活更轻松。

  • 每当使用 for 循环迭代数组时,首选i < array.Length而不是i < SomeHardCodedValue

  • 要填充甲板,请不要使用 4 个不同的循环,而是使用嵌套循环。

  • 洗牌
  • 时不要填充新的一副牌,相反,要么创建现有牌组的副本并洗牌,要么简单地洗牌现有牌组。

  • 当值是硬编码时,首选数组初始值设定项而不是循环。

将所有这些点组合到代码中,更好的版本如下所示:

class Deck
{
// The next two arrays are static since they are always the same,
// no point of making multiple copies of them for each instance of the class
private static string[] name = new string[] 
{
"Ace", "Two", "Three", "Four" /* more of the same here*/
};
private static string[] suits = new string[]
{
"Hearts", "Bells", "Acorns", "Leaves"
};
// all the fields used in this class
private string[] deck = new string[suits.Length * name.Length];
private int lastDelt = 0;
private Random rnd = new Random();
public Deck()
{
// see how simple the constructor is now
for(var i = 0 ; i < suits.Length; i++)
{
for(var j = 0; j < name.Length; j++)
{
// Calculate deck index using i and j
deck[(i+1) * j] = name[j] +" of "+ suits[i];
}
}
}
public void Shuffle()
{
// You might want to look into the Fisher-Yates shuffle instead, link below.
deck = deck.OrderBy(x => rnd.Next()).ToArray();
cardsLeft = deck.Length;
}
public string Deal()
{
if(lastDelt >= deck.Length)
{
throw new Exception("No cards left in the deck");
}
string deltCard = deck[lastDelt];
lastDelt++;
return deltCard;
}
}

当然,您可以将整个甲板放在单个硬编码静态数组中,然后在每个构造函数中使用它的副本。

指向 Fisher-Yates shuffle 算法的 c# 实现的链接,如承诺的那样。

相关内容

  • 没有找到相关文章

最新更新