我正在尝试在Asp.net 2.0(VB)中创建一个典型的Housie/Bingo游戏票证但是,没有成功票证包含3行9列。总共27个街区,必须只有15个街区才能填满这27个街区。每一列包含的值,如第1列应该在1-10之间,第2列必须有11-20之间的随机值。每一列填多少块并不重要1是必须的,单列不能为空,9列必须全部填写,有的3块全部填写,有的1块15块全部填写。随机数…
这里的人是典型的豪斯票规格请帮我弄一张这样的票我已经试过了,但是没有成功,我得到了整列空白和验证列..在系统上承受额外的负载。请给我找个办法。

最佳答案

你需要确定性算法
首先重新定义您的需求:
每列至少应有一个数字,因此任何列都不应完全为空
第一列的数字应该是1..10,第二列的数字应该是11..20,第三列的数字应该是21..30,依此类推,第九列的数字应该是81..90
只需要15个号码就能填好票
附加要求:每行应有5个数字
我就是这样做的:
首先选择9个随机数(以满足第一个要求)
1..10-此范围内的一个随机数
11..20-此范围内的一个随机数
...
81..90-此范围内的一个随机数
准备一个编号为1..90的数组(selectNums),并删除步骤1中选择的所有内容
循环
selectNums数组中获取随机数
将它添加到您的票据中,并将其从selectNumsaray中移除
如果选定的数字填充三个列,则从selectNums数组中删除该范围内的所有数字。
回到循环中的步骤1
此算法将在循环中精确地执行9个步骤+6个步骤,因此它是确定性的,对处理器利用率更有利。它也会在你的票上每栏最多填上三个数字,不少于一个(如果我理解你的要求,因为你的英文太差)。
当你选择随机数时,你总是选择一个介于0和selectNums数组长度之间的数字,这将给你在数组中的位置,你必须从中获取一个数字。
创建实际票据的附加功能
上面的步骤将使你得到一个点,你将得到15个数字,最多3个从相同的10个数字范围。好的。你现在要做的就是创建你的票。
定义3个变量:row1Countrow2Countrow3Count并将它们全部设置为0。
从完全填充的列(全部三个数字)开始填充票据:
获取第一个完整的列并将其填充到票据中,同时将所有三个变量递增一。
selectNums数组中删除这些数字。
回到步骤2.1。
用两个数字填写票子:
得到前两个数字列。用三种可能的排列方式(1&2、2&3、1&3)填写。使用第一个置换填充第一对,使用第二个置换填充第二对,依此类推。不要忘记增加相应的行计数器变量。
selectNums数组中删除这两个数字
回到步骤3.1。
用单个数字列(只有一个数字的列)填充票据:
selectNums数组中获取第一个数字,并将其放在计数最小的行中,然后放在该行的票据上。当至少有两行具有相同的计数时,可以通过随机选择一行或选择第一行(最快)来选择所需的行。
selectNums数组中删除数字
回到4.1。
这一部分将使您得到一个完整的票证,所有列至少有一个数字,所有行总共正好包含5个数字。
如果不允许较小的数字位于较大的数字之下,则始终可以向该过程添加一个附加步骤,并重新排序该过程中包含多个数字的列中的数字。
最后一次观察
通过使用数组和计数器简化了此解决方案。当然,您可以创建一个功能丰富的完整对象模型,并为您提供所需的所有信息。例如,您可以拥有Ticket和TicketColumn类:

public class TicketColumn
{
    public int Count { get; }
    public int? FirstRowValue { get; set; }
    public int? SecondRowValue { get; set; }
    public int? ThirdRowValue { get; set; }

    ...
    public void Reorder() { ... }
}

public class Ticket
{
    public TicketColumn[] Columns

    public int FirstRowCount { get; private set; }
    public int SecondRowCount { get; private set; }
    public int ThirdRowCount { get; private set; }

    ...
}

或者类似的东西这只是一个想法,整个程序将更好地以面向对象的方式。

10-04 22:36