简体   繁体   English

在宾果游戏中跟踪选定的数字

[英]Keeping track of selected numbers in Bingo

I have to create a class that keeps tracks of numbers that were already selected in the process of generating a board and selecting numbers during the game.我必须创建一个类来跟踪在游戏中生成棋盘和选择数字的过程中已经选择的数字。

The 3 classes I need:我需要的 3 个类:

1) A "reset" class that initalizses the class once the card is filled with numbers, so that the array can be used again to keep track of the numbers selected during the game 1) 一个“重置”类,一旦卡上填满数字就会初始化该类,以便可以再次使用该数组来跟踪游戏中选择的数字

2) A "isNumberUsed" class that is given the random integer and checks whether the random number is in the numbersList array or not 2) 给定随机整数并检查随机数是否在 numbersList 数组中的“isNumberUsed”类

3) A "setUsedNumber" class that adds the unique random number generated to the numbersList array. 3) 一个“setUsedNumber”类,将生成的唯一随机数添加到 numbersList 数组。

I have been working on this and would love any feedback.我一直在研究这个,希望得到任何反馈。 Thank you!谢谢!

public class SelectedNumbersListType
{
    private int[] numbersList;
    private int position;

    public SelectedNumbersListType()
    {
        numbersList = new int[76];
        position = 0;


    }
    public void reset()
    {
        // position = numbersList[0];
        // position++;
        for (position = 0; position < numbersList.Length; position++)
        {
            numbersList[position] = 0;

            if (position == numbersList.Length)
            {
                position = numbersList[0];
            }
        }
       // reset();
        }
    public bool isNumberUsed(int rn)
    {
        position = numbersList[0];
        position++;
        if (numbersList[position] == rn)
        {

            return true;
        }
        return false;
    }

    public bool setUsedNumber(int rn)
    {

        if (numbersList.Contains(rn))
        {
            Array.Resize(ref numbersList, numbersList.Length+1);
            numbersList[numbersList.Length + 1] = rn;

        }
        return false;
    }

}   

} }

I think it makes sense to step back here and start from the beginning.我认为退一步从头开始是有意义的。 As @ThomasWeller points out, object-oriented analysis starts with identifying the nouns in your problem space, and then the verbs that act upon those nouns.正如@ThomasWeller 指出的那样,面向对象的分析从识别问题空间中的名词开始,然后识别作用于这些名词的动词。

When I look at your bingo problem, I only see one noun, the BingoGame .当我查看您的宾果游戏问题时,我只看到一个名词BingoGame So, I'm going to have a class BingoGame .所以,我将有一个class BingoGame From the caller's point of view, there are two main actions (verbs) that act upon that noun: DrawNumber and RestartGame .从调用者的角度来看,有两个主要的动作(动词)作用于该名词: DrawNumberRestartGame In addition, I think it's useful to be able to get the list of numbers drawn in the game, both in draw order and in sorted order.此外,我认为能够以绘制顺序和排序顺序获取游戏中绘制的数字列表很有用。 As a result, I see two more verbs GetDrawnNumbers and GetDrawnNumbersSorted .结果,我看到了另外两个动词GetDrawnNumbersGetDrawnNumbersSorted

In C-family languages, it always makes more sense to start counting at 0 rather than at 1. So, I'm going to work with numbers in the range 0-74, not 1-75.在 C 系列语言中,从 0 开始计数总是比从 1 开始更有意义。因此,我将使用 0-74 范围内的数字,而不是 1-75。 Whenever I display a number, I'll prepend it with the appropriate letter (one of B, I, N, G, or O) and add one.每当我显示一个数字时,我都会在它前面加上适当的字母(B、I、N、G 或 O 之一)并添加一个。 So, I created a private function to do this: GetBingoNumberFromNumber .因此,我创建了一个私有函数来执行此操作: GetBingoNumberFromNumber

In order to draw a number, I need a source of random-ness.为了绘制一个数字,我需要一个随机源。 The framework provides one (System.Random) - it's not the best random number generator (don't use it to start a casino), but it's good enough here.该框架提供了一个 (System.Random)——它不是最好的随机数生成器(不要用它来开赌场),但在这里已经足够了。

I also need a way to retain what numbers have been drawn (both for display, and to reject any duplicate numbers in a game).我还需要一种方法来保留已绘制的数字(既用于显示,也用于拒绝游戏中的任何重复数字)。 I'll keep track of these in a List<int> .我将在List<int>跟踪这些。 Finally, I need to know what the letters are in "BINGO", so I'll keept an array of those letters (I could have treated the string "BINGO" as an array of characters, but I thought an array of characters was more obvious. As a result, my class starts with:最后,我需要知道“BINGO”中的字母是什么,所以我将保留这些字母的数组(我可以将字符串“BINGO”视为字符数组,但我认为字符数组更很明显。因此,我的课程开始于:

 public class BingoGame
 {
     private readonly List<int> _drawnNumbers = new List<int>();
     private readonly Random _random = new Random();
     //the indexes for this array are (naturally) 0 through 4
     private static readonly char[] BingoChars = {'B', 'I', 'N', 'G', 'O'};
 }

Now I need to add functionality.现在我需要添加功能。 Starting the game simply means taking previously drawn numbers and putting them back in the drum.开始游戏只是意味着将以前抽取的数字放回鼓中。 In our case, it means clearing the list of previously drawn numbers:在我们的例子中,这意味着清除先前抽取的数字列表:

 public void StartGame()
 {
     _drawnNumbers.Clear();
 }

To draw a number, we'll rely on Random.Next , pulling numbers between 0 and 74. However, we need to take care of the case where a duplicate number is pulled during single game.为了绘制一个数字,我们将依赖Random.Next ,在 0 到 74 之间提取数字。但是,我们需要注意在单局游戏中提取重复数字的情况。 If that happens, we'll throw away the newly drawn number and get another one.如果发生这种情况,我们将丢弃新抽取的号码并获得另一个号码。 We'll look in the list of previously drawn numbers to decide if a number has been previously drawn:我们将查看之前抽取的数字列表,以确定之前是否抽取了一个数字:

 public string DrawNumber()
 {
     int nextNum;
     do
     {
         nextNum = _random.Next(0, 75); //this will return a number between 0 & 74

     } while (_drawnNumbers.Contains(nextNum));
     _drawnNumbers.Add(nextNum);
     return GetBingoNumberFromNumber(nextNum);
 }

Here's the first time we've had to translate one of our 0-74 numbers to something that makes sense in Bingo.这是我们第一次必须将我们的 0-74 数字中的一个转换为在宾果游戏中有意义的东西。 Let's do that function:让我们做这个功能:

 private string GetBingoNumberFromNumber(int num)
 {
     //this will result in a number in the 0-4 range
     var bingoIndex = num / 15;
     return $"{BingoChars[bingoIndex]}-{num + 1}";
 }

It's important to understand integer division when reading that function.在阅读该函数时理解整数除法很重要。 Dividing any integer between 0 and 14 by the integer 15 will yield zero.将 0 到 14 之间的任何整数除以整数 15 将产生零。 Similarly, any number between 15 and 29 when divided by 15 will yield 1. And so on.同样,15 到 29 之间的任何数除以 15 都会得到 1。依此类推。

Finally, we need to get the "numbers" for the current game.最后,我们需要获取当前游戏的“数字”。 We'll just return the list of drawn numbers, transformed using GetBingoNumberFromNumber .我们将只返回使用GetBingoNumberFromNumber转换的抽取数字列表。 The easiest way to transform a collection is to use LINQ, so:转换集合的最简单方法是使用 LINQ,因此:

 public IEnumerable<string> GetDrawnNumbers()
 {
     return from num in _drawnNumbers
         select GetBingoNumberFromNumber(num);
 }

And, LINQ is good at sorting, so we'll just return the sorted list in nearly the same way:并且,LINQ 擅长排序,所以我们将以几乎相同的方式返回排序后的列表:

 public IEnumerable<string> GetDrawnNumbersSorted()
 {
     return from num in _drawnNumbers
         orderby num
         select GetBingoNumberFromNumber(num);
 }

To test this, I threw together a simple WinForms app with two buttons ( StartGameBtn and DrawNumberBtn ) and two skinny listboxes ( NumbersList and SortedList ).为了测试这一点,我将一个简单的 WinForms 应用程序放在一起,其中包含两个按钮( StartGameBtnDrawNumberBtn )和两个瘦列表框( NumbersListSortedList )。 After wiring up the Click handlers, it looked like:连接Click处理程序后,它看起来像:

public partial class Form1 : Form
{
    private readonly BingoGame _game = new BingoGame();
    public Form1()
    {
        InitializeComponent();
        _game.StartGame();
    }

    private void StartGameBtn_Click(object sender, EventArgs e)
    {
        _game.StartGame();
        NumbersList.Items.Clear();
        SortedList.Items.Clear();
    }

    private void DrawNumberBtn_Click(object sender, EventArgs e)
    {
        _game.DrawNumber();
        SetListboxItems(NumbersList, _game.GetDrawnNumbers());
        SetListboxItems(SortedList, _game.GetDrawnNumbersSorted());
    }

    private void SetListboxItems(ListBox listbox, IEnumerable<string> numbers)
    {
        listbox.Items.Clear();
        foreach (var item in numbers)
        {
            listbox.Items.Add(item);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM