提问人:AmmarSecurity 提问时间:10/8/2023 最后编辑:Zohar PeledAmmarSecurity 更新时间:10/17/2023 访问量:94
独特的 90 球宾果卡 C#
Unique 90-ball Bingo cards C#
问:
我需要生成宾果卡系统。
每张牌有 6 张桌子,每张桌子有 15 个不同的数字
每个表由 3 行和 9 列组成。
每行有 5 个数字和 4 个空白点
列包含:
歌罗西书 1:1-9,歌罗西书 2:10-19,歌罗西书 3:20-29,歌罗西书 4:30-39,歌罗西书 5:40-49,歌罗西书 6:50-59,歌罗西书 7:60-69,歌罗西书 8:70-79,歌罗西书 9:80-90
例如:
我写了这段代码:
public BingoCardGenerator() {
public static List<int[][]> GenerateBingoCards()
{
List<int[]> columnRanges = new List<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> usedNumbers = new List<int>();
for (int cardIndex = 0; cardIndex < 6; cardIndex++)
{
int[,] card = new int[3, 9];
List<int>[] usedNumbersByColumn = new List<int>[9];
for (int i = 0; i < 9; i++)
{
usedNumbersByColumn[i] = new List<int>();
}
for (int col = 0; col <= 8; col++)
{
int[] columnRange = columnRanges[col];
int start = columnRange[0];
int end = columnRange[1];
List<int> columnNumbers = new List<int>();
while (columnNumbers.Count < 10)
{
int num = random.Next(start, end);
if (!usedNumbers.Contains(num) || !usedNumbersByColumn[col].Contains(num))
{
columnNumbers.Add(num);
usedNumbersByColumn[col].Add(num);
Console.WriteLine("Here = " + num);
}else
{
}
}
for (int row = 0; row < 3; row++)
{
if (columnNumbers.Count > 0)
{
card[row, col] = columnNumbers[0];
columnNumbers.RemoveAt(0);
}
else
{
card[row, col] = 0;
}
}
}
for (int row = 0; row < 3; row++)
{
for (int i = 0; i < 4; i++)
{
int zeroColumn;
do
{
zeroColumn = random.Next(0, 9);
} while (card[row, zeroColumn] == 0);
card[row, zeroColumn] = 0;
}
}
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 9; col++)
{
int num = card[row, col];
if (num != 0)
{
usedNumbers.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;
}
但是表格中总是有重复的
答:
0赞
Zohar Peled
10/17/2023
#1
所以基本上,你有一个 9 * 9 的矩阵,每行有 4 个随机空白,每列包含 1 到 9、10 到 19、20 到 29 等之间的随机数,随机排序,并拆分为三个 3 行表。
我是这样做的:
创建一个方法,该方法将根据列索引返回每列中所有可能的数字。
创建一个将返回 9 行的方法,每行包含一个包含 9 个布尔值的数组 - 5 个 true 和 4 个 false,随机排序。
创建一个采用 3 行的方法,并基于它们和在第一种方法中构建的列从它们构建一个表。
创建一个方法,该方法将通过迭代行来构建一张卡片,并每次向上述方法发送 3,返回一个可为 null 的二维数组数组 int - 因此返回类型为 .
int?[][,]
请务必还阅读代码中的注释。
static class BingoGenerator {
// Note: Hard coded constants can be changed or even taken from configuration (but will have to be replaced with static readonly fields for that),
// without breaking the functionality.
// Constants that depends on them (numberOfRows, numberOfColumns) mush be replaced with static readonly fields as well if you replace them.
// Random can be wrappend and injected using a static property (but then you'll have to check it's not null when calling CreateCard,
// and if it is, throw an InvalidOperationException with a proper message to indicate it.
private const int rowsPerTable = 3;
private const int tablesPerCard = 3;
private const int numberOfRows = tablesPerCard * rowsPerTable;
private const int blanksPerRow = 4;
private const int numbersPerRow = 5;
private const int numberOfColumns = blanksPerRow + numbersPerRow;
private static bool[] _rowTemplate = Enumerable
.Range(0, blanksPerRow)
.Select(_ => false)
.Concat(Enumerable.Range(0, numbersPerRow).Select(_ => true))
.ToArray();
private static Random _rnd = new();
public static int?[][,] CreateCard()
{
var columns = CreateColumns().ToArray();
var rows = CreateRows();
return CreateTables(columns, rows);
}
// see item #4
private static int?[][,] CreateTables(int[][] columns, IEnumerable<bool[]> rows)
{
var tables = new int?[tablesPerCard][,];
for(var i=0;i<tablesPerCard;i++)
{
tables[i] = CreateTable(i, columns, rows.Skip(i * tablesPerCard).Take(rowsPerTable));
}
return tables;
}
// see item #3
private static int?[,] CreateTable(int tableNumber, int[][] columns, IEnumerable<bool[]> rows)
{
var table = new int?[rowsPerTable, numberOfColumns];
var j=0;
foreach(var row in rows)
{
for(var i=0;i<numberOfColumns;i++)
{
table[j,i] = row[i] ? columns[i][j + (tableNumber * rowsPerTable)] : null;
}
j++;
}
return table;
}
// see item #2
private static IEnumerable<bool[]> CreateRows()
=> Enumerable
.Range(0, numberOfRows)
.Select(_ => _rowTemplate.OrderBy(r => _rnd.Next()).ToArray());
// see item #1
private static IEnumerable<int[]> CreateColumns()
=> Enumerable
.Range(0, numberOfColumns)
.Select(CreateColumn);
// see item #1
private static int[] CreateColumn(int columnIndex)
=> Enumerable
.Range(1 + (10 * columnIndex), numberOfRows)
.OrderBy(r => _rnd.Next())
.ToArray();
}
观看 .net fiddle 上的现场演示
评论
Add()
方法特别方便。