C#中的Bingo算法 [英] Bingo Algorithm in C#
问题描述
我正在尝试创建应按照以下规则设置的宾果卡:
I'm trying to create a bingo card which should be set up with the following rules:
- 宾果卡将有9列和3行
- 每行行必须有5个数字
- 每行之后不能有超过2个空块在另一行中
- 在同一行中最多只能有2个数字
- Bingo card will have 9 columns and 3 rows
- Each row must have 5 numbers
- There can't be more than 2 empty blocks following each oter in a single row
- There can't be more than 2 numbers following each other in a single row
到目前为止,我已经设法创建了一个包含9列和3行的卡片,并在卡片中填充了唯一的随机数,但是我不知道如何实现第3和第4条规则。
So far I've managed to create a card that contains 9 columns and 3 rows and filled the card with unique random numbers but I can't figure out how to achieve 3rd and 4th rules.
最后,宾果卡应该看起来像这样:
In the end, a bingo card should look similar to this:
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
在我的算法中,我不知道如何放置空块并避免重复将它们重复两次以上
In my algorithm I don't know how to put EMPTY blocks and avoid repeating them more than twice
我的卡生成器功能是:
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类:
GameCard class:
public class GameCard
{
public string CardId { get; set; }
public List<CardColumn> Columns { get; set; }
public GameCard()
{
Columns = new List<CardColumn>();
}
}
CardColumn类
CardColumn class
public class CardColumn
{
public int Count { get; set; }
public List<NumberBlock> Rows { get; set; }
public CardColumn()
{
Rows = new List<NumberBlock>();
}
}
NumberBlock类
NumberBlock class
public class NumberBlock
{
public int Value { get; set; }
public bool IsBlank { get; set; }
public NumberBlock()
{
IsBlank = false;
}
}
推荐答案
第一个做一些研究-有45种可能的行类型
First do some research - there are 45 possible types of row
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脚本是:
The LinqPad script I used to generate this list is:
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种可能性之一,最后用数字填充该行。
You could proceed from there - First generate 15 different random numbers from your list, then for each row, randomly choose one of the 25 possibilities, and finally fill the row with numbers.
最好逐行而不是按列进行操作,因为所有您的规则适用于行。如果您确实需要在列中添加内容,请在末尾将其切换。
Far better to do this by row, rather than column, because all your rules apply to rows. If you really need things in columns, switch them round at the end.
这篇关于C#中的Bingo算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!