C#中的宾果算法

时间:2015-12-01 16:38:42

标签: c# algorithm

我正在尝试制作一张应使用以下规则设置的宾果卡:

  • 宾果卡将有9列和3行
  • 每个必须有5个数字
  • 单行中每个oter后面的空格不能超过2个
  • 单行中不能超过2个数字

到目前为止,我已经成功创建了一个包含9列和3行的卡片,并用唯一的随机数填充了卡片,但我无法弄清楚如何实现第3和第4规则。

最后,宾果卡看起来应该与此类似:

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;
    }

GameCard课程:

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;
    }
}

1 个答案:

答案 0 :(得分:4)

首先做一些研究 - 有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种可能中的一种,最后用数字填充该行。

最好通过行而不是列来执行此操作,因为所有规则都适用于行。如果你真的需要列中的东西,最后将它们转换成圆形。