Simple (to some) Dice game

• (2 Pages)
• 1
• 2

15 Replies - 1346 Views - Last Post: 08 November 2013 - 06:59 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=333507&amp;s=46f74141c4f613f39a8eb78684c5aaea&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

#1 kevinerikwhite

Reputation: 0
• Posts: 15
• Joined: 07-November 13

Simple (to some) Dice game

Posted 07 November 2013 - 12:28 PM

I am extremely new in c# and coding in general so need massive help with just the basics.

Here are my rules:

Two players each roll a pair of dice until one player wins. Each time they roll is called a 'battle.' First to win 5 battles wins the game. The winner of a battle is determined by these rules:

1. Doubles always wins over non-doubles. E.g., 1-1 wins over 6-5.

2. Higher doubles wins over lower doubles. E.g., 4-4 wins over 3-3.

3. If both players roll non-doubles, then the higher total roll wins. E.g., 5-4 (9) wins over 5-3 (8).

4. If the players roll the same, no one wins that battle.

Here is my dice class
```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dice1
{
class PairOfDice
{
private int die1, die2;
private Random random1;

public PairOfDice()
{
random1 = new Random();
}

public int Die1
{
get
{ return die1; }
set
{ die1 = value; }
}

public int Die2
{
get
{ return die2; }
set
{ die2 = value; }
}

public int SumOfFaces()
{
return die1 + die2;
}

public void Roll()
{
die1 = random1.Next(1, 7);
die2 = random1.Next(1, 7);
}

public bool isDoubles()
{
return(die1==die2);
}
}
```

and here is my form 1 that I'm just getting started on but do not know where to go

```using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using dice1;

namespace DiceBattleKevin
{
public partial class Form1 : Form
{
private PairOfDice pair1 = new PairOfDice();
private PairOfDice pair2 = new PairOfDice();
bool P1_doubles;
bool P2_doubles;
int P1_sum;
int P2_sum;

public Form1()
{
InitializeComponent();
P1_doubles = pair1.isDoubles();
P2_doubles = pair2.isDoubles();
P1_sum = pair1.SumOfFaces();
P2_sum = pair2.SumOfFaces();
}

private void RollButton_Click(object sender, EventArgs e)
{
//Roll the dice

//When button is clicked, number shows up in for die1 and die2

//Show the value of dice
//disable the roll button

if(P1_doubles)
{ if(P2_doubles)
//both doubles

}
else if (P2_doubles)
{ //p2 wins

}
else
{ //neither are double
//check sum

}

}

private bool BattleOver()
{

}

private void DeclareWinner()
{
//Declare winner
}

private void ShowScores()
{
//Set the label of P1's score to his score
//Set the label of p2's score to his score
}

private void NewGameButton_Click(object sender, EventArgs e)
{

}

}
}

```

I am really lost at the simplest part on how to get the dice to roll when I click the roll dice button. This is so new to me and I have been staring at this for hours so please help me on any of the parts. Thanks!

Is This A Good Question/Topic? 0

Replies To: Simple (to some) Dice game

#2 Robin19

Reputation: 272
• Posts: 552
• Joined: 07-July 10

Re: Simple (to some) Dice game

Posted 07 November 2013 - 12:41 PM

I would try pair1.Roll();

You have the steps broken down in the comments. Just follow the steps you wrote. Take your time and only worry about each one by itself. I would make each a different method to call. This takes all logic out of the event handler.
```private void Battle()
{
DisableRollButton();
RollAllDice();
DisplayDiceValues();
CalculateWinner();
DisplayScores();
BattleOver();
}

private void RollButton_Click(object sender, EventArgs e)
{
Battle();
}
```

#3 kevinerikwhite

Reputation: 0
• Posts: 15
• Joined: 07-November 13

Re: Simple (to some) Dice game

Posted 07 November 2013 - 12:50 PM

Believe it or not, that helps so much....This is just so new to me and my mind is racing. Thank you

#4 optix212

Reputation: 30
• Posts: 540
• Joined: 10-October 09

Re: Simple (to some) Dice game

Posted 07 November 2013 - 01:00 PM

I wouldn't make 2 dice in the Dice class. I would create, instead, a singular Die class and create two objects out of it. Then I would implement a Roll() method in my die class that returns a Random number between 1-6. Then, you can check it in a another method.

```//Somewhere above rolling the die. Probably global.
Die die1 = new Die();
Die die2 = new Die();

int firstDie = die1.Roll();
int secondsDie = die2.Roll();
if(firstDie == secondDie)
{
MessageBox.Show("You rolled a double!");
winCount++;
}

```

This post has been edited by optix212: 07 November 2013 - 01:01 PM

#5 kevinerikwhite

Reputation: 0
• Posts: 15
• Joined: 07-November 13

Re: Simple (to some) Dice game

Posted 07 November 2013 - 01:06 PM

This helps so if I make a...

private void DisplayDiceValues()
{
//What do I put here to get my p1d1label, p1d2label, p2d1label and p2d2label to all show their respective dice? How do I write what die1 or die 2 are in here?
}

#6 optix212

Reputation: 30
• Posts: 540
• Joined: 10-October 09

Re: Simple (to some) Dice game

Posted 07 November 2013 - 01:13 PM

Well, you would need 4 die objects in total. Unless you wanted to extend your class hierarchy and create a Player class. This shouldn't be needed for such a small project, though.

If I were to create this, though, I would implement a Player class as well. The Player class would hold two die() objects called die1 and die2 and a winCount integer. I would then implement a method called PlayerRoll(int dice) that would return the roll value of each dice. Then on my main form, I would have 2 Player objects that I could call their PlayerRoll() function with a button.

If I wanted to display their values, I would probably set up some global integers, lets call them p1d1Value, p1d2Value, p2d1Value, p2d2Value, on my main form to store their values every time I rolled. Then, sometime after the roll, set these integers to the roll values, and then call your DisplayDiceValues() method.

it could look something like:
```DisplayDiceValue()
{
p1d1Label.Text = p1d1Value;
//etc...
}

```

Note that the player class is not actually needed, but if you're new to programming it's always best to create a class for anything that would be an object in the real world.. I.E a human(or player), a die, etc..

This post has been edited by optix212: 07 November 2013 - 01:18 PM

#7 Rhino1111

• D.I.C Regular

Reputation: 107
• Posts: 259
• Joined: 28-August 13

Re: Simple (to some) Dice game

Posted 07 November 2013 - 01:35 PM

optix212, on 07 November 2013 - 01:00 PM, said:

```if(firstDie == secondDie)
{
MessageBox.Show("You rolled a double!");
winCount++;
}

```

This assumes rolling a double is an instant win, when in-fact it is possible for the other player to roll a higher double the same 'battle'. You would need to check your opponent hasn't rolled higher doubles before incrementing the winCount and stating that the player has won.

#8 optix212

Reputation: 30
• Posts: 540
• Joined: 10-October 09

Re: Simple (to some) Dice game

Posted 07 November 2013 - 02:31 PM

Well, it was just an example. I didn't feel like writing all of the logic for winning.

Also, I just realized...

If he is using only one Random object, wouldn't all the rolls be on the same seed, thus producing the same output?

I don't have much experience with the Random class, but I believe that is how it works. I just tried it with the way I had envisioned it, and all of my die are producing the same output.. Here is my die class:
```namespace DiceGame
{
class Die
{
Random myRandom = new Random();
public int Roll()
{
return myRandom.Next(1, 6);
}
}
}

```

Player:
```class Player
{
public int winCount = 0;
public int die1Value = 0;
public int die2Value = 0;
Die die1 = new Die();
Die die2 = new Die();

public int RollDie1()
{
return die1.Roll();
}

public int RollDie2()
{
return die2.Roll();
}

public bool hitDouble()
{
return die1Value == die2Value;
}

}

```

Then Form1:
```public partial class Form1 : Form
{
int p1d1Value;
int p1d2Value;
int p2d1Value;
int p2d2Value;

Player player1;
Player player2;

public Form1()
{
InitializeComponent();
player1 = new Player();
player2 = new Player();
}

private void btnRoll_Click(object sender, EventArgs e)
{
p1d1Value = player1.RollDie1();
p1d2Value = player1.RollDie2();
p2d1Value = player2.RollDie1();
p2d2Value = player2.RollDie2();
HandleLabels();

}

private void HandleLabels()
{
p1d1Label.Text = p1d1Value.ToString();
p1d2Label.Text = p1d2Value.ToString();
p2d1Label.Text = p2d2Value.ToString();
p2d2Label.Text = p2d2Value.ToString();
}
}

```

I don't know how I could produce another Random on a different seed?

This post has been edited by optix212: 07 November 2013 - 02:37 PM

#9 astonecipher

• Senior Systems Engineer

Reputation: 2481
• Posts: 9,958
• Joined: 03-December 12

Re: Simple (to some) Dice game

Posted 07 November 2013 - 02:34 PM

Each call to Random would produce a new number, that number may be the same, but it is a different call.

#10 Rhino1111

• D.I.C Regular

Reputation: 107
• Posts: 259
• Joined: 28-August 13

Re: Simple (to some) Dice game

Posted 07 November 2013 - 02:51 PM

astonecipher, on 07 November 2013 - 02:34 PM, said:

Each call to Random would produce a new number, that number may be the same, but it is a different call.

I believe he meant to say was... since he's creating 2 random's at a near identical time, that these randoms will be using the same seed and produce parallel output (i,e the same sequences), and he is correct.

```private PairOfDice pair1 = new PairOfDice();
private PairOfDice pair2 = new PairOfDice();

```

Right here he's instantiating 2 instances of 'PairOfDice' at a pretty much identical time.
and it's constructor....

```public PairOfDice()
{
random1 = new Random();
}

```

This is why MSDN recommends only using a single Random instance for number generation. The nanoseconds difference between instantiating these 2 different objects doesn't affect its seed value. You'll either need to create some kind of delay between instantiating these 2 classes, or use a single global random.

EDIT:
@

optix212, on 07 November 2013 - 02:31 PM, said:

I don't know how I could produce another Random on a different seed?

You could also pass an integer value to the Random's constructor, which specifies its seed value, but that also wouldn't be the best approach here because it would produce identical games. The default constructor uses your system clock to seed.

This post has been edited by Rhino1111: 07 November 2013 - 03:10 PM

#11 astonecipher

• Senior Systems Engineer

Reputation: 2481
• Posts: 9,958
• Joined: 03-December 12

Re: Simple (to some) Dice game

Posted 07 November 2013 - 02:55 PM

Okay. I understand what he was saying now.

#12 kevinerikwhite

Reputation: 0
• Posts: 15
• Joined: 07-November 13

Re: Simple (to some) Dice game

Posted 07 November 2013 - 04:18 PM

This is great, thank you.

Do any of you know how to add 1 if someone wins and what the code would be?

#13 optix212

Reputation: 30
• Posts: 540
• Joined: 10-October 09

Re: Simple (to some) Dice game

Posted 07 November 2013 - 04:57 PM

I ended using Thread.Sleep() to set a difference in the clock before each Random call.

```private void btnRoll_Click(object sender, EventArgs e)
{
p1d1Value = player1.die1.myRandom1.Next(1, 6);
p1d2Value = player1.die1.myRandom1.Next(1, 6);
p2d1Value = player1.die1.myRandom1.Next(1, 6);
p2d2Value = player1.die1.myRandom1.Next(1, 6);
if (Player1Double() || Player2Double())
{
HandleDoubles();
}
else
{
HandleScores();
}

HandleLabels();

}

```

Also, as you can see, MSDN said it was better to use the same instance of random each time. So, I ended up just using player1.die1.myRandom1.Next(1,6). Now I see it would've probably been a bit less code if I had just put the random object in the player class and not have a die object at all.

I ended up getting the entire program figured out.

Since it is against the rules to post the entire code for you, I will end up making a tutorial on it when I get the time.

I may end up putting a betting system in as well.. Because that just seems like it would be fun xP

This post has been edited by optix212: 07 November 2013 - 05:01 PM

#14 Curtis Rutland

• （╯°□°）╯︵ (~ .o.)~

Reputation: 5102
• Posts: 9,283
• Joined: 08-June 10

Re: Simple (to some) Dice game

Posted 07 November 2013 - 06:13 PM

Quote

If he is using only one Random object, wouldn't all the rolls be on the same seed, thus producing the same output?

You misunderstand how Random works. Easy mistake, it takes reading and practice (and making your own mistakes) to learn.

Random is a pseudo-random number generator class. It takes a single seed, which is by default set from the system clock. It can use that seed to produce an arbitrary-length list of integers that is about as random as computers can be. Given the same seed, Random will always produce the same sequence of numbers. Given a different seed, a different sequence will be produced. (Side note for anyone not familiar: research "true random vs. pseudo-random" for a real explanation of the topic. Also, from here on out, "random" means "pseudo-random")

Because it can produce an arbitrary amount of random numbers, there's very little good reason to ever instantiate more than one Random class in your program (a multi-threaded application is a great example where you might want more than one instance of Random, but my point is you should start from a default of using one and need to justify why you'd need more).

If you choose to use more than one random, now that's where it gets a bit tricky (and I noticed that you encountered this in your post). Remember, the Random class's default constructor uses the system clock to derive its seed. Modern processors can handle many many cycles per millisecond. These two facts mean that it's quite possible to create several Random instances that get the same seed. That means identical results from different objects.

So, because there's no need to use multiple Randoms, and significant chance for error if used, it's almost always best to use one instance of Random per application.

I usually suggest (in a single threaded app) creating a private static Random instance in your application's root class (whether that's your Program class in a Console/WinForms, App.xaml.cs in WPF, etc...and make public static utility methods like GetRandomInt, and access them statically from Program or App or whatever. Use one Random generator for your entire application. Of course, all this is unnecessary for small or simple applications, but it can make bugs in big applications less likely.

#15 Curtis Rutland

• （╯°□°）╯︵ (~ .o.)~

Reputation: 5102
• Posts: 9,283
• Joined: 08-June 10

Re: Simple (to some) Dice game

Posted 07 November 2013 - 06:30 PM

Another side note. Here's a neat little extension method I've used for Random, with an example of how to use it:

```public static class Extensions
{
public static IEnumerable<int> GetRandomInts(this Random random, int inclusiveFrom, int exclusiveTo)
{
while (true)
{
yield return random.Next(inclusiveFrom, exclusiveTo);
}
}
}

class Program
{
static Random rand = new Random();

static void Main(string[] args)
{
int max = 10;
Console.WriteLine("Making {0} random ints.", max);
foreach (int randomInt in rand.GetRandomInts(0, 100).Take(10))
{
Console.Write("{0,-3}", randomInt);
}
Console.WriteLine("{0}{0}Press Any Key to Exit.", Environment.NewLine);