我正在学习编程,特别是从C#开始,我一直在尝试骰子游戏,以便更熟悉并提高自己。我现在正试图在Windows窗体中创建一个基本游戏,其中两个玩家掷5个骰子并记录他们的分数。
规则:
从5个骰子开始
如果出现1或4,则玩家没有得分,并且这些骰子被移除。否则将所有骰子添加到总计
继续骰子,直到没有骰子
到目前为止,我有一个Image数组,它存储我资源中的所有骰子图像和一个掷骰子的按钮。我需要帮助的具体是能够移除惩罚骰子(将特定的骰子设置为空白)并允许玩家继续滚动剩余的骰子,直到没有留下。
目前我不确定我可以在哪里进一步开展这项活动,也许我咬的比我能咀嚼更多。我很喜欢编码,任何帮助都会非常感激。
这是界面的图像:
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()
{
}
}
答案 0 :(得分:1)
您发布的代码至少有一些不符合您描述的奇怪内容:
diceResults
)(即元素对应于die 值,不是游戏中的死亡顺序)。根据您的描述,我希望代码只需将模具值添加到单个和变量中。GetResults()
方法中,您的代码会将diceResults
中的各个元素值与值2
和5
进行比较。换句话说,对于每个可能的芯片值,如果该值出现两次或五次,则设置两个标志。有许多原因这很奇怪,但最大,最明显的原因是单个变量(即元素diceResults[i]
)永远不会同时具有两个不同的值。即该数组元素永远不会同时为2
和5
,因为if
语句需要。鉴于这些问题,我更倾向于关注原始规范,而不是过多地信任代码,试图理解代码的预期行为实际上是什么。 :)
似乎基本问题是如何最好地从游戏中消除死亡。使用列表跟踪骰子的建议(在上面的评论中)肯定是可行的。在该方法中,人们将遍历列表以设置每个元素,如果给定元素的滚动始终为1
或4
,则在继续之前删除该元素。
完成此操作后,可以再次遍历列表以使用&#34;空白&#34;设置模具值图像。超出列表长度的任何骰子的图像。
但是有一种更简单的方法,并且基于你的陈述&#34;将该特定的一个设置为空白&#34; ,这似乎意味着每个空白模具应该出现在同一个它被滚动的位置,似乎更简单的方式可能比你更好。
具体来说,滚动骰子后,只需扫描dice
数组并将所有1
和4
值重置为0
,然后使用此0
价值作为特殊的&#34;哨兵&#34;值表示骰子现在是空白的。
请注意,无论您执行此操作(使用列表,还是仅将值设置为0
),还有一个问题是是否向用户显示实际的1
和4
卷,或立即将这些卷设置为空白模具。我会假设前者,但以其他方式实现它将非常容易。 (一如既往,优秀代码的开头是一个很好的规范......现在,你的规范在细节上有点亮,因此模糊不清)。
采用这种方法,您的代码可能看起来更像这样:
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
}
注意:当1
或4
出现时,我不清楚你的意思。根据你的字面意思,我理解这意味着,如果任何骰子在掷骰上显示1
或4
,那么 none 骰子计数该卷。上面的代码是在考虑到这种理解的情况下实现的。
我觉得你可能反而意味着只有显示1
或4
的骰子不计入掷骰子,并且该骰子的其他骰子仍被包含在内。改变上述内容以适应替代规范并不难。
注意:您还会注意到我已经对技术上不需要的代码进行了其他更改,以便解决当前的问题。我在代码本身中添加了注释,试图解释我为什么要进行这些更改,以及为什么我觉得他们使代码更好。
只是为了笑容,这里有一个使用列表的版本:
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上发布另一个问题,询问每个问题)。