C#实现唯一90球Bingo卡片生成遇数字重复问题求助
解决90球Bingo卡片重复数字问题
问题根源分析
你的代码出现重复数字主要有以下几个关键问题:
- 判断逻辑错误:生成列数字时,你用了
!usedNumbers.Contains(num) || !usedNumbersByColumn[col].Contains(num)的或逻辑,这意味着只要数字不在全局已用列表或者不在列已用列表中就会被添加,实际需要的是同时不在两个列表,应该用&&。 - Random范围错误:
Random.Next(start, end)是左闭右开区间,比如第9列的范围是80-90,Next(80,90)只会生成80-89,永远到不了90,需要改成Next(start, end + 1)。 - 列数字生成逻辑冗余:每个列最多在单张卡片里出现3个数字(3行),没必要生成10个,应该先获取该列所有未被全局使用的数字,再随机挑选3个。
修正后的完整代码
public class BingoCardGenerator { public static List<int[][]> GenerateBingoCards() { // 定义各列数字范围,注意第9列是80-90 int[][] columnRanges = new int[][] { new int[] { 1, 9 }, new int[] { 10, 19 }, new int[] { 20, 29 }, new int[] { 30, 39 }, new int[] { 40, 49 }, new int[] { 50, 59 }, new int[] { 60, 69 }, new int[] { 70, 79 }, new int[] { 80, 90 } }; Random random = new Random(); List<int[][]> cards = new List<int[][]>(); List<int> globalUsedNumbers = new List<int>(); // 生成6张卡片 for (int cardIndex = 0; cardIndex < 6; cardIndex++) { int[,] card = new int[3, 9]; // 处理每一列,为每列选3个未被全局使用的数字 for (int col = 0; col < 9; col++) { int[] range = columnRanges[col]; int start = range[0]; int end = range[1]; // 获取该列所有未被全局使用的数字 List<int> availableNumbers = new List<int>(); for (int num = start; num <= end; num++) { if (!globalUsedNumbers.Contains(num)) { availableNumbers.Add(num); } } // 随机打乱可用数字,取前3个 availableNumbers = availableNumbers.OrderBy(x => random.Next()).ToList(); for (int row = 0; row < 3; row++) { if (row < availableNumbers.Count) { card[row, col] = availableNumbers[row]; } else { // 理论上不会走到这里,因为每列可用数字足够(比如第1列有9个,远大于3) card[row, col] = 0; } } } // 处理每行:将4个位置置为0(确保每行5个数字) for (int row = 0; row < 3; row++) { // 收集当前行有数字的列索引 List<int> nonZeroColumns = new List<int>(); for (int col = 0; col < 9; col++) { if (card[row, col] != 0) { nonZeroColumns.Add(col); } } // 随机选4个列置为0 nonZeroColumns = nonZeroColumns.OrderBy(x => random.Next()).Take(4).ToList(); foreach (int col in nonZeroColumns) { card[row, col] = 0; } } // 将当前卡片的数字加入全局已用列表 for (int row = 0; row < 3; row++) { for (int col = 0; col < 9; col++) { int num = card[row, col]; if (num != 0 && !globalUsedNumbers.Contains(num)) { globalUsedNumbers.Add(num); } } } // 将二维数组转换为锯齿数组 int[][] cardArray = new int[3][]; for (int row = 0; row < 3; row++) { cardArray[row] = new int[9]; for (int col = 0; col < 9; col++) { cardArray[row][col] = card[row, col]; } } cards.Add(cardArray); } return cards; } }
关键改进点
- 修正重复判断逻辑:严格确保每个数字既不在全局已用列表,也不会在单张卡片内重复。
- 修复Random范围:正确覆盖所有列的数字区间,包括第9列的90。
- 优化列数字选择:先获取该列所有可用数字,打乱后取前3个,避免无效循环。
- 更可靠的置0逻辑:先收集当前行有数字的列,再随机选4个置0,避免重复选到已为0的列。
内容的提问来源于stack exchange,提问作者AmmarSecurity
相关产品推荐
相关产品推荐

