如何进步我的五骰子游戏

时间:2015-10-18 09:00:46

标签: c# arrays loops dice

我正在学习编程,特别是从C#开始,我一直在尝试骰子游戏,以便更熟悉并提高自己。我现在正试图在Windows窗体中创建一个基本游戏,其中两个玩家掷5个骰子并记录他们的分数。

规则:

  • 从5个骰子开始

  • 如果出现1或4,则玩家没有得分,并且这些骰子被移除。否则将所有骰子添加到总计

  • 继续骰子,直到没有骰子

到目前为止,我有一个Image数组,它存储我资源中的所有骰子图像和一个掷骰子的按钮。我需要帮助的具体是能够移除惩罚骰子(将特定的骰子设置为空白)并允许玩家继续滚动剩余的骰子,直到没有留下。

目前我不确定我可以在哪里进一步开展这项活动,也许我咬的比我能咀嚼更多。我很喜欢编码,任何帮助都会非常感激。

这是界面的图像:

enter image description here

enter image description here

public partial class Form1 : Form
{

    Image[] diceImages;
    int[] dice;
    int[] diceResults;
    Random random;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        diceImages = new Image[7];
        diceImages[0] = Properties.Resources.blank;
        diceImages[1] = Properties.Resources.one;
        diceImages[2] = Properties.Resources.two;
        diceImages[3] = Properties.Resources.three;
        diceImages[4] = Properties.Resources.four;
        diceImages[5] = Properties.Resources.five;
        diceImages[6] = Properties.Resources.six;

        dice = new int[5] { 0, 0, 0, 0, 0 };

        random = new Random();

        diceResults = new int[6] { 0, 0, 0, 0, 0, 0 };

    }

    private void btn_rollDice_Click(object sender, EventArgs e)
    {
        RollDice();

        GetResults();

        ResetResults();
    }

    private void RollDice()
    { 
        for (int i = 0; i < dice.Length; i++)
        {
            dice[i] = random.Next(1, 7);

            switch (dice[i])
            { 
                case 1:
                    diceResults[0]++;
                    break;
                case 2:
                    diceResults[1]++;
                    break;
                case 3:
                    diceResults[2]++;
                    break;
                case 4:
                    diceResults[3]++;
                    break;
                case 5:
                    diceResults[4]++;
                    break;
                case 6:
                    diceResults[5]++;
                    break;

            }

        }

        lbl_dice1.Image = diceImages[dice[0]];
        lbl_dice2.Image = diceImages[dice[1]];
        lbl_dice3.Image = diceImages[dice[2]];
        lbl_dice4.Image = diceImages[dice[3]];
        lbl_dice5.Image = diceImages[dice[4]];
    }

    private void GetResults()
    {
        bool oneRoll = false, fourRoll = false;

        for (int i = 0; i < diceResults.Length; i++)
        {
            if (diceResults[i] == 1 && diceResults[i] == 4)
            {
                oneRoll = true;
                fourRoll = true;
            }
        }
    }

    private void ResetResults()
    {

    }

}

1 个答案:

答案 0 :(得分:1)

您发布的代码至少有一些不符合您描述的奇怪内容:

  • 当滚动给定的骰子值时,代码只是增加数组中的元素(diceResults)(即元素对应于die ,不是游戏中的死亡顺序)。根据您的描述,我希望代码只需模具值添加到单个和变量中。
  • 在您的GetResults()方法中,您的代码会将diceResults中的各个元素值与值25进行比较。换句话说,对于每个可能的芯片值,如果该值出现两次或五次,则设置两个标志。有许多原因这很奇怪,但最大,最明显的原因是单个变量(即元素diceResults[i]永远不会同时具有两个不同的值。即该数组元素永远不会同时为25,因为if语句需要。

鉴于这些问题,我更倾向于关注原始规范,而不是过多地信任代码,试图理解代码的预期行为实际上是什么。 :)

似乎基本问题是如何最好地从游戏中消除死亡。使用列表跟踪骰子的建议(在上面的评论中)肯定是可行的。在该方法中,人们将遍历列表以设置每个元素,如果给定元素的滚动始终为14,则在继续之前删除该元素。

完成此操作后,可以再次遍历列表以使用&#34;空白&#34;设置模具值图像。超出列表长度的任何骰子的图像。

但是有一种更简单的方法,并且基于你的陈述&#34;将该特定的一个设置为空白&#34; ,这似乎意味着每个空白模具应该出现在同一个它被滚动的位置,似乎更简单的方式可能比你更好。

具体来说,滚动骰子后,只需扫描dice数组并将所有14值重置为0,然后使用此0价值作为特殊的&#34;哨兵&#34;值表示骰子现在是空白的。

请注意,无论您执行此操作(使用列表,还是仅将值设置为0),还有一个问题是是否向用户显示实际的14卷,或立即将这些卷设置为空白模具。我会假设前者,但以其他方式实现它将非常容易。 (一如既往,优秀代码的开头是一个很好的规范......现在,你的规范在细节上有点亮,因此模糊不清)。

采用这种方法,您的代码可能看起来更像这样:

public partial class Form1 : Form
{
    #region Declaration
    Image[] diceImages;
    Label[] labels;
    int[] dice;
    int diceTotal;
    bool checkOnesAndFours;
    Random random;
    #endregion

    #region Initialiazation;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // Initializing an array this way eliminates the chance of having
        // a typo in the array index for the assignment.
        diceImages = new Image[]
        {
            Properties.Resources.blank,
            Properties.Resources.one,
            Properties.Resources.two,
            Properties.Resources.three,
            Properties.Resources.four,
            Properties.Resources.five,
            Properties.Resources.six
        };

        // Arrays are always initialized with the elements having their default
        // values, so there's no need to specify `0` values for `int` arrays explicitly
        dice = new int[5];

        random = new Random();

        diceTotal = 0;

        // For the purposes of setting the dice images, it will be helpful
        // to keep the control references in an array. This is both convenient
        // and, again, helps guard against typographical errors
        labels = new Label[]
        {
            lbl_dice1,
            lbl_dice2,
            lbl_dice3,
            lbl_dice4,
            lbl_dice5
        };
    }

    #endregion

    #region Private Methods

    private void btn_rollDice_Click(object sender, EventArgs e)
    {
        RollDice();
    }

    private void RollDice()
    {
        bool rolledOneOrFour = false;
        int rollTotal = 0;

        for (int i = 0; i < dice.Length; i++)
        {
            if (checkOnesAndFours)
            {
                // First, clear any 1 or 4 from the previous roll
                if (dice[i] == 1 || dice[i] == 4)
                {
                    dice[i] = 0;
                }

                // Then, ignore any blank die
                if (dice[i] == 0)
                {
                    continue;
                }
            }

            dice[i] = random.Next(1, 7);
            if (dice[i] == 1 || dice[i] == 4)
            {
                rolledOneOrFour = true;
            }
            rollTotal += dice[i];
        }

        if (!rolledOneOrFour)
        {
            diceTotal += rollTotal;
        }

        checkOnesAndFours = true;

        for (int i = 0; i < labels.Length; i++)
        {
            labels[i].Image = diceImages[dice[i]];
        }
    }

    #endregion
}

注意:当14出现时,我不清楚你的意思。根据你的字面意思,我理解这意味着,如果任何骰子在掷骰上显示14,那么 none 骰子计数该卷。上面的代码是在考虑到这种理解的情况下实现的。

我觉得你可能反而意味着只有显示14的骰子不计入掷骰子,并且该骰子的其他骰子仍被包含在内。改变上述内容以适应替代规范并不难。

注意:您还会注意到我已经对技术上不需要的代码进行了其他更改,以便解决当前的问题。我在代码本身中添加了注释,试图解释我为什么要进行这些更改,以及为什么我觉得他们使代码更好。


只是为了笑容,这里有一个使用列表的版本:

public partial class Form1 : Form
{
    #region Declaration
    Image[] diceImages;
    Label[] labels;
    List<int> dice;
    int diceTotal;
    bool checkOnesAndFours;
    Random random;
    #endregion

    #region Initialiazation;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // Initializing an array this way eliminates the chance of having
        // a typo in the array index for the assignment.
        diceImages = new Image[]
        {
            Properties.Resources.blank,
            Properties.Resources.one,
            Properties.Resources.two,
            Properties.Resources.three,
            Properties.Resources.four,
            Properties.Resources.five,
            Properties.Resources.six
        };

        // Lists must be initialized explicitly with their initial values, as by default
        // they are initially empty.
        dice = new List<int>(Enumerable.Repeat(0, 5));

        random = new Random();

        diceTotal = 0;

        // For the purposes of setting the dice images, it will be helpful
        // to keep the control references in an array. This is both convenient
        // and, again, helps guard against typographical errors
        labels = new Label[]
        {
            lbl_dice1,
            lbl_dice2,
            lbl_dice3,
            lbl_dice4,
            lbl_dice5
        };
    }

    #endregion

    #region Private Methods

    private void btn_rollDice_Click(object sender, EventArgs e)
    {
        RollDice();
    }

    private void RollDice()
    {
        bool rolledOneOrFour = false;
        int rollTotal = 0;

        for (int i = 0; i < dice.Count; i++)
        {
            // Clear any 1 or 4 from the previous roll
            if (checkOnesAndFours && (dice[i] == 1 || dice[i] == 4))
            {
                // Remove this die from play
                dice.RemoveAt(i);

                // The next list element to examine is now at the current i value
                // and the for loop is going to increment i when the continue
                // is executed, so decrement i in anticipation of that
                // so that the loop moves on to the correct next element
                i--;

                continue;
            }

            dice[i] = random.Next(1, 7);
            if (dice[i] == 1 || dice[i] == 4)
            {
                rolledOneOrFour = true;
            }
            rollTotal += dice[i];
        }

        if (!rolledOneOrFour)
        {
            diceTotal += rollTotal;
        }

        checkOnesAndFours = true;

        for (int i = 0; i < labels.Length; i++)
        {
            labels[i].Image = i < dice.Count ? diceImages[dice[i]] : diceImages[0];
        }
    }

    #endregion
}


最后,请注意,上述两个都没有解决代码中的其他几个问题:

  • 在游戏开始时初始化骰子标签。
  • 游戏结束后重置整个游戏(即不再有骰子)。

我将这两个项目作为练习留给读者(当然,如果您遇到这些特定问题的问题,您可能总是在Stack Overflow上发布另一个问题,询问每个问题)。