独特的 90 球宾果卡 C#

Unique 90-ball Bingo cards C#

提问人:AmmarSecurity 提问时间:10/8/2023 最后编辑:Zohar PeledAmmarSecurity 更新时间:10/17/2023 访问量:94

问:

我需要生成宾果卡系统。
每张牌有 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

例如:

enter image description here

我写了这段代码:

  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;


        }

但是表格中总是有重复的

C# asp.net JSON ASP.NET-MVC .NET-CORE

评论

0赞 Astrid E. 10/9/2023
对于表格中总是有重复部分,您可能需要阅读哈希集Add() 方法特别方便。
0赞 AmmarSecurity 10/9/2023
你能给我代码如何使用它吗?
0赞 Zohar Peled 10/9/2023
“每行有 5 个数字和 4 个空白点”——我认为这些空白点也应该随机分布在行上?
0赞 Zohar Peled 10/15/2023
我很抱歉你没有回复评论。我发现这个问题是一个很好的编程练习。
0赞 AmmarSecurity 10/15/2023
@ZoharPeled对不起,这是随机的

答:

0赞 Zohar Peled 10/17/2023 #1

所以基本上,你有一个 9 * 9 的矩阵,每行有 4 个随机空白,每列包含 1 到 9、10 到 19、20 到 29 等之间的随机数,随机排序,并拆分为三个 3 行表。

我是这样做的:

  1. 创建一个方法,该方法将根据列索引返回每列中所有可能的数字。

  2. 创建一个将返回 9 行的方法,每行包含一个包含 9 个布尔值的数组 - 5 个 true 和 4 个 false,随机排序。

  3. 创建一个采用 3 行的方法,并基于它们和在第一种方法中构建的列从它们构建一个表。

  4. 创建一个方法,该方法将通过迭代行来构建一张卡片,并每次向上述方法发送 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 上的现场演示