英文:
My application on Windows Forms goes into break when I try to call these functions
问题
我有一个包含卡牌的文件,存储在我的电脑上。我想要做的是生成所有 54 张卡牌,并将其中 7 张分发给用户,以按钮的形式供他们玩这些卡牌,然后将另外的 7 张分发给计算机,而剩余的卡牌则存储在队列中,以供两者中的任何一个按下按钮时获取更多卡牌。但我遇到的问题是生成需要存储供用户获取的 7 个随机数。
以下是我参考的代码:
我相信代码的这一部分调用 SetButtonImage
来在加载时开始编译。
public FmClassic()
{
InitializeComponent();
SetButtonImage();
}
这是 SetButtonImage
从我的计算机中获取图像并调用另一个函数来生成随机数的部分。
private void SetButtonImage()
{
Stack<int> ShuffleOnTime = ShuffleOneTime();
string Cards = String.Join("\n", ShuffleOnTime);
button1.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(0, Cards.IndexOf(Environment.NewLine))}.png");
button2.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(1, Cards.IndexOf(Environment.NewLine))}.png");
button3.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(2, Cards.IndexOf(Environment.NewLine))}.png");
button4.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(3, Cards.IndexOf(Environment.NewLine))}.png");
button5.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(4, Cards.IndexOf(Environment.NewLine))}.png");
button6.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(5, Cards.IndexOf(Environment.NewLine))}.png");
button7.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(6, Cards.IndexOf(Environment.NewLine))}.png");
}
然后,这被调用以确保它们是随机的,并且不会使用哈希表两次调用,同时转换为字符串,这对于搜索文件时更好。
public Stack<int> ShuffleOneTime()
{
Random random = new Random();
Stack<int> generatednumbers = new Stack<int>();
Stack<int> randomNumbers = GenerateRandomNumber(random, generatednumbers);
return randomNumbers;
}
这有助于生成数字并将其返回给其他函数。
Stack<int> GenerateRandomNumber(Random random, Stack<int> generatednumbers)
{
int randomNumber;
do
{
randomNumber = random.Next(1, 54);
generatednumbers.Push(randomNumber);
if (generatednumbers.Count >= 2)
{
int Compare1 = generatednumbers.Pop();
int Compare2 = generatednumbers.Pop();
if (Compare1 == Compare2)
{
generatednumbers.Push(Compare1);
}
}
} while (generatednumbers.Count != 53);
return generatednumbers;
}
我尝试将其更改为字符串而不是整数,以帮助查找,但它不起作用。卡牌的文件名都是 1.jpg,2.jpg 等等,所以我不知道为什么会出现错误。一切都能编译通过,但然后我的屏幕会冻结 60 秒,然后出现以下错误:
Managed Debugging Assistant 'ContextSwitchDeadlock' : 'CLR 无法在 60 秒内从 COM 上下文 0xa73c68 切换到 COM 上下文 0xa73bb0。'
英文:
I have files on my computer containing all cards within a deck. What I want to do is generate all 54 numbers and give 7 of them to the user in the form of buttons so they can play these cards, another 7 cards to the computer, and the remaining cards stored in a queue for either of them to press to get more if needed. But the error I am facing is generating the 7 random numbers that need to be stored for the user to get.
This is the code I am referring to:
I believe this part of the code calls the SetButtonImage to begin to compile on load.
public FmClassic()
{
InitializeComponent();
SetButtonImage();
}
This is SetButtonImage gathering the images from within my computer as well as calling another function to generate the random numbers.
private void SetButtonImage()
{
Stack<int> ShuffleOnTime = ShuffleOneTime();
string Cards = String.Join("\n", ShuffleOnTime);
button1.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(0, Cards.IndexOf(Environment.NewLine))}.png");
button2.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(1, Cards.IndexOf(Environment.NewLine))}.png");
button3.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(2, Cards.IndexOf(Environment.NewLine))}.png");
button4.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(3, Cards.IndexOf(Environment.NewLine))}.png");
button5.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(4, Cards.IndexOf(Environment.NewLine))}.png");
button6.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(5, Cards.IndexOf(Environment.NewLine))}.png");
button7.Image = Image.FromFile($"C:\\filepath\\{Cards.Substring(6, Cards.IndexOf(Environment.NewLine))}.png");
}
This is then called to ensure they are random and not called twice with the hash table as well as converting to a string which I think is better for when searching for files.
public Stack<int> ShuffleOneTime()
{
Random random = new Random();
Stack<int> generatednumbers = new Stack<int>();
Stack<int> randomNumbers = GenerateRandomNumber(random, generatednumbers);
return randomNumbers;
}
This helps generate the numbers and return it back to the other function.
Stack<int> GenerateRandomNumber(Random random, Stack<int> generatednumbers)
{
//Queue<int> Cards = new Queue<int>();
//Queue<string> realNumbers = new Queue<string>();
int randomNumber;
do
{
randomNumber = random.Next(1, 54);
generatednumbers.Push(randomNumber);
if (generatednumbers.Count >= 2)
{
int Compare1 = generatednumbers.Pop();
int Compare2 = generatednumbers.Pop();
if (Compare1 == Compare2)
{
generatednumbers.Push(Compare1);
}
}
} while (generatednumbers.Count != 53);
//string number = generatednumbers.ToString();
//realNumbers.Enqueue(number);
return generatednumbers;
}
I have tried making it a string rather than an integer to help find it but it won't work. The filenames for the cards are all 1.jpg, 2.jpg etc so I don't know why there is an error. Everything compiles but then my screen freezes for 60 seconds and them inputs this error:
Managed Debugging Assistant 'ContextSwitchDeadlock' : 'The CLR has been unable to transition from COM context 0xa73c68 to COM context 0xa73bb0 for 60 seconds.
答案1
得分: 1
Create a method that generates shuffled numbers of a given range.
private readonly Random rnd = new Random();
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
private int[] GenerateShuffledNumbers(int start, int count)
{
var numbers = Enumerable.Range(start, count).ToArray();
for (int i = 0; i < numbers.Length; i++)
{
var j = i + (int)(rnd.NextDouble() * (numbers.Length - i));
(numbers[i], numbers[j]) = (numbers[j], numbers[i]);
}
return numbers;
}
在 SetButtonImage
方法中所需的全部内容如下:
private void SetButtonImage()
{
var dir = @"图片文件夹路径";
var buttons = new[]
{
button1, button2, button3, button4,
button5, button6, button7
};
var numbers = GenerateShuffledNumbers(1, 53);
for (int i = 0; i < buttons.Length; i++)
{
// jpg 或 png?添加正确的扩展名。
var imgFile = Path.Combine(dir, $"{numbers[i]}.jpg");
buttons[i].Image?.Dispose();
buttons[i].Image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgFile)), true, false);
}
}
请注意,numbers
数组包含所有 53 个数字,您可以取一个范围:
var someNumbers = numbers.Take(7);
... 也可以跳过一部分然后取:
// 取前 7 个...
var set1 = numbers.Take(7);
// 取接下来的 7 个...
var set2 = numbers.Skip(7).Take(7);
// 跳过前 14 个然后取剩下的...
var set3 = numbers.Skip(14);
所有这些返回 IEnumerable<int>
。如果需要,可以调用 .ToList()
或 .ToArray()
。
如果需要创建 Stack<int>
或 Queue<int>
,它们都有一个构造函数重载,接受 IEnumerable<T>
。
var stack = new Stack<int>(numbers);
var queue = new Queue<int>(numbers);
英文:
So, you have 53 images in some folder, and you want to shuffle and pick. You can simplify this task since the file names are the numbers range that you want to generate and shuffle.
Create a method that generates shuffled numbers of a given range.
private readonly Random rnd = new Random();
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
private int[] GenerateShuffledNumbers(int start, int count)
{
var numbers = Enumerable.Range(start, count).ToArray();
for (int i = 0; i < numbers.Length; i++)
{
var j = i + (int)(rnd.NextDouble() * (numbers.Length - i));
(numbers[i], numbers[j]) = (numbers[j], numbers[i]);
}
return numbers;
}
All what you need to have in the SetButtonImage
method is:
private void SetButtonImage()
{
var dir = @"The Images Directory Path";
var buttons = new[]
{
button1, button2, button3, button4,
button5, button6, button7
};
var numbers = GenerateShuffledNumbers(1, 53);
for (int i = 0; i < buttons.Length; i++)
{
// jpg or png? Append the right extension.
var imgFile = Path.Combine(dir, $"{numbers[i]}.jpg");
buttons[i].Image?.Dispose();
buttons[i].Image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgFile)), true, false);
}
}
Note, the numbers
array contains all the 53 numbers, you can take a range:
var someNumbers = numbers.Take(7);
... you can skip and take:
// Take the first 7...
var set1 = numbers.Take(7);
// Take the next 7...
var set2 = numbers.Skip(7).Take(7);
// Skip the first 14 and take the rest...
var set3 = numbers.Skip(14);
All of which return IEnumerable<int>
. Call .ToList()
or .ToArray()
if needed.
If you need to create a Stack<int>
or Queue<int>
, both have a constructor overload that takes IEnumerable<T>
.
var stack = new Stack<int>(numbers);
var queue = new Queue<int>(numbers);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论