C#中的Bingo算法

本文关键字:算法 Bingo 中的 | 更新日期: 2023-09-27 18:25:17

我正在尝试创建一张宾果游戏卡,它应该按照以下规则设置:

  • 宾果卡将有9列3行
  • 每个必须有5个数字
  • 一行中每个oter后面不能有超过2个空块
  • 一行中不能有两个以上的数字

到目前为止,我已经成功地创建了一张包含9列3行的卡片,并用唯一的随机数填充卡片,但我不知道如何实现第三和第四规则。

最后,宾果游戏卡应该看起来像这样:

1     EMPTY   18     EMPTY   12     EMPTY     40    EMPTY 32
EMPTY 2       EMPTY  EMPTY   67     33        EMPTY 44    EMPTY
90    EMPTY   79     EMPTY   38     EMPTY     55    EMPTY 71

在我的算法中,我不知道如何放置EMPTY块,避免重复两次以上

我的卡片生成器功能是:

public GameCard GetCard()
    {
        //This is the list of all numbers between 1 and 99
        var availableNumbers = Enumerable.Range(CARD_NUM_MIN, CARD_NUM_MAX).ToList();
        var card = new GameCard();
        //looping for 9 columns
        for (var col = 0; col < CARD_COL_COUNT; col++)
        {
            var cardColumn = new CardColumn();
            //looping for 3 rows in each column
            for (var row = 0; row < CARD_ROW_COUNT; row++)
            {
                var cardRow = new NumberBlock();
                //getting a random number from availableNumbers and removing that number from list to avoid duplicate numbers.
                var rand = RandomNumberGenerator.Instance.Next(availableNumbers.Count - 1);
                cardRow.Value = availableNumbers[rand];
                availableNumbers.RemoveAt(rand);
                //I believe somewhere here I should check if there will be more than 5 numbers in a row, or should randomly generate empty blocks? Can't really figure out...
                cardColumn.Rows.Add(cardRow);
            }
            card.Columns.Add(cardColumn);
        }
        return card;
    }

游戏卡等级:

public class GameCard
{
    public string CardId { get; set; }
    public List<CardColumn> Columns { get; set; }
    public GameCard()
    {
        Columns = new List<CardColumn>();
    }
}

CardColumn类

public class CardColumn
{
    public int Count { get; set; }
    public List<NumberBlock> Rows { get; set; }
    public CardColumn()
    {
        Rows = new List<NumberBlock>();
    }
}

NumberBlock类

public class NumberBlock
{
    public int Value { get; set; }
    public bool IsBlank { get; set; }
    public NumberBlock()
    {
        IsBlank = false;
    }
}

C#中的Bingo算法

首先做一些研究-有45种可能的行类型

  91=Number Number Empty  Number Number Empty  Number Empty  Empty  
 107=Number Number Empty  Number Empty  Number Number Empty  Empty  
 109=Number Empty  Number Number Empty  Number Number Empty  Empty  
 155=Number Number Empty  Number Number Empty  Empty  Number Empty  
 171=Number Number Empty  Number Empty  Number Empty  Number Empty  
 173=Number Empty  Number Number Empty  Number Empty  Number Empty  
 179=Number Number Empty  Empty  Number Number Empty  Number Empty  
 181=Number Empty  Number Empty  Number Number Empty  Number Empty  
 182=Empty  Number Number Empty  Number Number Empty  Number Empty  
 203=Number Number Empty  Number Empty  Empty  Number Number Empty  
 205=Number Empty  Number Number Empty  Empty  Number Number Empty  
 211=Number Number Empty  Empty  Number Empty  Number Number Empty  
 213=Number Empty  Number Empty  Number Empty  Number Number Empty  
 214=Empty  Number Number Empty  Number Empty  Number Number Empty  
 217=Number Empty  Empty  Number Number Empty  Number Number Empty  
 218=Empty  Number Empty  Number Number Empty  Number Number Empty  
 299=Number Number Empty  Number Empty  Number Empty  Empty  Number 
 301=Number Empty  Number Number Empty  Number Empty  Empty  Number 
 307=Number Number Empty  Empty  Number Number Empty  Empty  Number 
 309=Number Empty  Number Empty  Number Number Empty  Empty  Number 
 310=Empty  Number Number Empty  Number Number Empty  Empty  Number 
 331=Number Number Empty  Number Empty  Empty  Number Empty  Number 
 333=Number Empty  Number Number Empty  Empty  Number Empty  Number 
 339=Number Number Empty  Empty  Number Empty  Number Empty  Number 
 341=Number Empty  Number Empty  Number Empty  Number Empty  Number 
 342=Empty  Number Number Empty  Number Empty  Number Empty  Number 
 345=Number Empty  Empty  Number Number Empty  Number Empty  Number 
 346=Empty  Number Empty  Number Number Empty  Number Empty  Number 
 357=Number Empty  Number Empty  Empty  Number Number Empty  Number 
 358=Empty  Number Number Empty  Empty  Number Number Empty  Number 
 361=Number Empty  Empty  Number Empty  Number Number Empty  Number 
 362=Empty  Number Empty  Number Empty  Number Number Empty  Number 
 364=Empty  Empty  Number Number Empty  Number Number Empty  Number 
 403=Number Number Empty  Empty  Number Empty  Empty  Number Number 
 405=Number Empty  Number Empty  Number Empty  Empty  Number Number 
 406=Empty  Number Number Empty  Number Empty  Empty  Number Number 
 409=Number Empty  Empty  Number Number Empty  Empty  Number Number 
 410=Empty  Number Empty  Number Number Empty  Empty  Number Number 
 421=Number Empty  Number Empty  Empty  Number Empty  Number Number 
 422=Empty  Number Number Empty  Empty  Number Empty  Number Number 
 425=Number Empty  Empty  Number Empty  Number Empty  Number Number 
 426=Empty  Number Empty  Number Empty  Number Empty  Number Number 
 428=Empty  Empty  Number Number Empty  Number Empty  Number Number 
 434=Empty  Number Empty  Empty  Number Number Empty  Number Number 
 436=Empty  Empty  Number Empty  Number Number Empty  Number Number 

我用来生成这个列表的LinqPad脚本是:

List<bool []> permutations = new List<bool []>();
void Main()
{
    // Generate all possible permutations of 9 items
    // 511 is 9 1-bits
    for(uint n = 0; n < 512; n++) {
        bool [] p = perm(n);
        if(valid(p)) {
            permutations.Add(p);
            Console.Write("     {0}=", n);
            for(int i = 0; i < 9; i++)
                Console.Write(p[i] ? "Number " : "Empty  ");
            Console.WriteLine();
        }
    }
}
// Convert a number into a bit pattern (array of 9 bools)
// Representing number (true) or gap (false)
bool [] perm(uint n) {
    bool [] result = new bool[9];
    uint m = 1;
    for(int i = 0; i < 9; m <<= 1, i++)
        result[i] = (n & m) != 0;
    return result;
}
// See if a bit pattern satisfies the rules
bool valid(bool [] p) {
    int repeat = 0;     // Number of trues (numbers) or falses (gaps)
    int count = 0;      // Number of trues (numbers)
    bool last = false;
    for(int n = 0; n < 9; n++) {
        bool current = p[n];
        if(current == last) {
            // This is the same as the last one (i.e. both numbers or both gaps)
            if(++repeat > 2)
                return false; // May not have more than 2 of the same together
        } else {
            repeat = 1;
        }
        if(current)
            count++;
        last = current;
    }
    return count == 5;
}

你可以从那里开始——首先从你的列表中生成15个不同的随机数字,然后对每一行,从25种可能性中随机选择一种,最后用数字填充这一行。

按行而不是按列执行要好得多,因为所有规则都适用于行。如果你真的需要列中的东西,那么在最后把它们切换过来。