Introduction
When I play darts with my friends at home we have a laptop with us to hold scores and statistics. We used Excel to do the job, but I was encouraged to build a more sophisticated solution. So, I came up with the idea to click on a dartboard picture to calculate the scores thrown and the statistics. So this article shows the usercontrol and the delegates/events I used.
Using the code
There are 2 interesting parts in this challenge:
- How to determine the score based on a click somewhere on the dartboard;
- Using delegates and events;
For the first part I used the middle of the bull (that is the middle of the picture) as my base point (0,0). Since I know the X and Y coordinate I can calculate the degrees by using the atan()
function.
double dblHoekInRadians = System.Math.Atan2( posY , posX );
double dblHoekInGraden = dblHoekInRadians * 180 / System.Math.PI;
When I know the degrees I know which number was clicked. The dartboard has 20 slices of equal size. So, each slice is of 360 / 20 = 18 degrees. Remember, the middle is my base, so number 13 is between 9 and 27 degrees and number 4 is between 27 and 45.
The next thing to do is to check which ring was clicked (bull, triple, double or else just single). I calculated the distince from the base (0,0) to the clicked X,Y coordinate. Now, the Pythagoras guy is entering our life!
double dblLengte = System.Math.Sqrt( posX * posX + posY * posY );
int intLengte = (int)System.Math.Floor( dblLengte );
Well, this was the hard part.
The next thing is to develop some events to be raised. I chose to have 4 events: NoScoreThrown
, SingleScoreThrown
, DoubleScoreThrown
and TripleScoreThrown
. I declared them like this:
public event NoScoreThrownEventHandler NoScoreThrown ;
protected virtual void OnNoScoreThrown( DartbordEventArgs e )
{
if( NoScoreThrown != null )
{
NoScoreThrown( this, e );
}
}
For these events I used 4 delegates:
public delegate void NoScoreThrownEventHandler( object sender ,
DartbordEventArgs e );
public delegate void SingleThrownEventHandler( object sender ,
DartbordEventArgs e );
public delegate void DoubleThrownEventHandler( object sender ,
DartbordEventArgs e );
public delegate void TripleThrownEventHandler( object sender ,
DartbordEventArgs e );
I also defined my own EventArgs
with specific data about the scores and throws.
public class DartbordEventArgs : EventArgs
{
private readonly int mintScore ;
private readonly string mstrScore ;
private readonly int mintThrow ;
public DartbordEventArgs( int Score , string ScoreText , int Throw )
{
this.mintScore = Score ;
this.mstrScore = ScoreText ;
this.mintThrow = Throw ;
}
#region Properties
public int Score
{
get
{
return mintScore;
}
}
public string ScoreText
{
get
{
return mstrScore;
}
}
public int Throw
{
get
{
return mintThrow;
}
}
#endregion
}
Based on the score thrown I raise the right event. I used a class variable (boolean
) to know whether I hit a single, double, triple or noscore.
DartbordEventArgs dea = new DartbordEventArgs( mintScore ,
mstrScoreText , mintThrow );
if( mIsTriple ) OnTripleThrown( dea );
if( mIsDouble ) OnDoubleThrown( dea );
if( mIsSingle ) OnSingleThrown( dea );
if( mIsNoScore ) OnNoScoreThrown( dea );
That's basically it. Have fun!