7 Replies - 2697 Views - Last Post: 15 October 2012 - 10:50 AM Rate Topic: -----

#1 psnyder  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 11-October 12

C# Farkle Game Problem - School Project - Code and Example Included

Posted 11 October 2012 - 10:29 PM

All,

This is my first time posting here so I hope that I get the posting procedures correct. I am currently taking a C# programming class and our teacher has assigned us a project that entails us designing a C# Farkle Game. If you haven't played Farkle before (which I haven't prior to taking this class) all you really need to know is it's basically like Yahtzee. You roll six dice and try to get the most points out of the dice you hold, then roll again but minus the dice you've already held aside... if that makes sense. Well, I have to create a form that controls the Farkle board then create another class that can ONLY be for code whos' sole purpose is to calculate the score of the held dice. However, the kicker is that I can't use any code that represents picture boxes, labels, text boxes, etc. Just old school c++ style code (i.e. arrays, ints, doubles, etc.).

Using the code below, my problem is that after the user rolls the dice and holds whatever dice/he she wants, I need a way to pass the dice that was held to the other class for calculating the best score. I can figure that out, however I can't figure out how to pass which dice was held to the other class. Since I can't use images, pictureboxes, etc. in the other class per my professor, my plan is as follows (starting after the 'Roll Dice' button has been clicked and the user checks which dice he/she wants to hold THEN clicks the 'Roll Dice' Button again):

Use the for loop(s) and if/else statements to go through and find out which dice was (or wasn't held). If the dice wasn't held, then go ahead and randomize the dice. If the dice was held, then somehow store the value of the dice in temp_array. My thought process in doing this was since the imageList1 stores all the dice*.png images (i.e. index 0 = 1, index 1 = 2, etc.) then I could somehow store the index of the dice in the temp_array and pass the temp_array to the other class for review and ultimately scoring. However, I can't get the pogram to read the index and respective dice face correctly. If I go in and click 'Roll Dice' the first time to randomize the dice, hold my dice, then click the array again, the value of index that pops up in label1 (which is just there to test what is being passed to my other class) isn't correct. I need to find out a way to store the face of the dice being held in an array so I can use it later in my other class. I can't figure out what I am doing wrong!! I go through each iteration on a piece of paper and everything seems to add up correctly. Any help is greatly appreciated. The code for the form is below. Also, an image is attached as well of what the form looks like after I select which dice to hold and click 'Roll Dice'. Please keep in mind that my professor put something in my code that I didn't take out before this post that sets the label1 label to all zeros initially so you are going to have to disregard the first six zeros. Sorry. However, as you can see, 2 and 3 are not the dice that I held.

Thanks in advance for your help!!! There are several events below but the 'Roll Dice' click event is the one (I think) is causing the problem.

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

namespace HonorsPracticeFarkle
{ 
    
    public partial class Form1 : Form
    {
        
        ImageList imageList1 = new ImageList();
        private Random m_rand = new Random();
        private int[] i_array = new int[6] { 0, 1, 2, 3, 4, 5 };
        private int counter = 0;
        private FrmRegistration theApp;
        private PictureBox[] pic_array = new PictureBox[6];
        private CheckBox[] chbx_array = new CheckBox[6];
        private int[] diceHeld_array = new int[6];

        public Form1(FrmRegistration frm)
        {
            InitializeComponent();
            theApp = frm;
            imageList1.ImageSize = new Size(50, 50);

            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die1.png"));
            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die2.png"));
            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die3.png"));
            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die4.png"));
            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die5.png"));
            imageList1.Images.Add(Image.FromFile(@"..\..\Dice Image Files\die6.png"));

            

            pic_array[0] = picDice1;
            pic_array[1] = picDice2;
            pic_array[2] = picDice3;
            pic_array[3] = picDice4;
            pic_array[4] = picDice5;
            pic_array[5] = picDice6;

            chbx_array[0] = chbxDie1;
            chbx_array[1] = chbxDie2;
            chbx_array[2] = chbxDie3;
            chbx_array[3] = chbxDie4;
            chbx_array[4] = chbxDie5;
            chbx_array[5] = chbxDie6;

            
            for (int i = 0; i < pic_array.Length; i++)
            {
                
                pic_array[i].Image = imageList1.Images[i];
            }
        }
              

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnRollDice_Click(object sender, EventArgs e)
        {
            int[] temp_array = new int[6];
            int index = 0;

            if (counter >= 1 && (chbxDie1.Checked == false && chbxDie2.Checked == false && chbxDie3.Checked == false
                && chbxDie4.Checked == false && chbxDie5.Checked == false && chbxDie6.Checked == false))
            {
                MessageBox.Show("You must select a die or dice to proceed!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


            else
            {

                for (int i = 0; i < pic_array.Length; i++)
                {
                    if (chbx_array[i].Checked == false)
                    {
                        index = m_rand.Next(0, 5);
                        pic_array[i].Image = imageList1.Images[index];
                        pic_array[i].Image.Tag = index;
                    }
                    else
                    {
                        for (int j = 0; j < pic_array.Length; j++)
                            if (pic_array[i].Image.Tag == imageList1.Images[j].Tag)
                                index = j + 1;
                                
                        temp_array[i] = index;
                        

                    }
                }

                for (int i = 0; i < temp_array.Length; i++)
                    label1.Text += temp_array[i].ToString();
                
            }            
                        
            counter++;

            lblMessageToCurrent.Text = "Pick which dice to hold";
        }

        private void btnReplay_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < pic_array.Length; i++)
            {
                pic_array[i].Image = imageList1.Images[i];
            }

            lblGameScore1Output.Text = "0";
            lblGameScore2Output.Text = "0";
            lblRollScore1Output.Text = "0";
            lblRollScore2Output.Text = "0";
            lblTurnScore1Output.Text = "0";
            lblTurnScore2Output.Text = "0";

            btnRollDice.Enabled = false;
            btnNextPlayer.Enabled = false;
            btnReplay.Enabled = false;
            btnGameOver.Enabled = false;

            for (int i = 0; i < chbx_array.Length; i++)
                chbx_array[i].Checked = false;

            lblMessageToCurrent.Text = "Guess Numbers To Play";

        }

        private void btnGameOver_Click(object sender, EventArgs e)
        {
            lblMessageToCurrent.Text = "***GAME OVER***\nPlease Press 'Replay' or 'Close'!";

            btnRollDice.Enabled = false;
            btnNextPlayer.Enabled = false;


        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            theApp.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lblMessageToCurrent.Text = theApp.getOutput();
        }

    }
}


Attached File(s)



Is This A Good Question/Topic? 0
  • +

Replies To: C# Farkle Game Problem - School Project - Code and Example Included

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6052
  • View blog
  • Posts: 23,487
  • Joined: 23-August 08

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 12 October 2012 - 03:04 AM

Your teacher is right; you wouldn't want your scoring class to have anything to do with the graphical representation of the object. So I would say you need a container to hold six objects, each of which represents the value of the die and whether or not it was held.
Was This Post Helpful? 0
  • +
  • -

#3 psnyder  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 11-October 12

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 12 October 2012 - 08:08 AM

View PostJackOfAllTrades, on 12 October 2012 - 03:04 AM, said:

Your teacher is right; you wouldn't want your scoring class to have anything to do with the graphical representation of the object. So I would say you need a container to hold six objects, each of which represents the value of the die and whether or not it was held.



Sorry for my following ignorant post as I'm new to C#. My thought process was to use four seperate arrays.
1. imageList1 (which I guess isn't necessarily an array) - that holds the images of the dice. These images can be randomized or not randomized from this list.
2. pic_array - a PictureBox array that holds the dice that are randomized or not from imgageList1.
3. chbx_array - a CheckBox array that holds the checkboxes and can be run through to see which dice was held (or not held).
4. temp_array - holds the value of the dice that has been held by the player.

When the user clicks on Roll Dice, I figured that there had to be a way to run through, via for loops, and figure out which dice was held by looking at the check boxes. When the loops finds a check box that is checked it takes the value of the dice that is in the picturebox above and stores it in temp_array. The way that it knows which dice that is temp_array is because at some point, the dice image that is transferred to the PictureBox is from a specific index of imageList1. There has to be a way to store the index that was sent to the pictureBox array into temp_array so temp_array and ulimately be passed to the class that calculate the score. However, the code that I have written doesn't store the indexes properly.

You had mentioned storing the objects in a container. My ignorance somes with the question: is that not what I'm doing with the arrays? Or is there an actual container class that I use to make this all happen.

Sorry for being a n00b. I hope that nobody feels that I'm trying to get them to do my homework. I've just hit this brick wall with trying to get the dice values of the dice the player held in something that can be passed to the scoring class. Once that happens, I'm confident I can move forward with coding the scoring myself. This project is due Sunday so this website is my last resort to try to get this figured out as I've been working on this same issue for at least a week. So hopefully you can understand my frustration.

Thank you very much for trying to help me.
Was This Post Helpful? 0
  • +
  • -

#4 Robin19  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 271
  • View blog
  • Posts: 550
  • Joined: 07-July 10

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 12 October 2012 - 09:36 AM

I don't like parallel arrays. I have the following rule. If I think of a parallel array, I then think how a collection of a Class would do better.

Break the project down. Don't worry about making 6 different random dice rolls. Think about making 1 random dice roll. Create a new class (why not call it 'Die') that contains the information. Then create a new custom user control to display the Die class. The user control should just be an interaction between the Die class and the user. btnRollDice_Click simply calls DieUserControl.Roll(). DieUserControl.Roll() will call Die.Roll if it's checkbox is not checked. If it is checked, nothing changes. Form1 doesn't need to always know what the values are, it can simply ask when it needs them. It can then pass those values to the ResultsChecker. Once you've got 1 DieUserControl working on Form1, it should be easy to just add as many more as you like. Form1 can hold a variable (built during the constructor) that has a List or Array of those controls.

At least, that's how I'd tackle it. I'd love to give you more, but it is important for you to work some of this out on your own. Don't worry about failing, bad code won't kill someone at this point. Failing now is simply gives you more knowledge of how to do this later.
Was This Post Helpful? 1
  • +
  • -

#5 psnyder  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 11-October 12

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 12 October 2012 - 12:37 PM

View PostRobin19, on 12 October 2012 - 09:36 AM, said:

I don't like parallel arrays. I have the following rule. If I think of a parallel array, I then think how a collection of a Class would do better.

Break the project down. Don't worry about making 6 different random dice rolls. Think about making 1 random dice roll. Create a new class (why not call it 'Die') that contains the information. Then create a new custom user control to display the Die class. The user control should just be an interaction between the Die class and the user. btnRollDice_Click simply calls DieUserControl.Roll(). DieUserControl.Roll() will call Die.Roll if it's checkbox is not checked. If it is checked, nothing changes. Form1 doesn't need to always know what the values are, it can simply ask when it needs them. It can then pass those values to the ResultsChecker. Once you've got 1 DieUserControl working on Form1, it should be easy to just add as many more as you like. Form1 can hold a variable (built during the constructor) that has a List or Array of those controls.

At least, that's how I'd tackle it. I'd love to give you more, but it is important for you to work some of this out on your own. Don't worry about failing, bad code won't kill someone at this point. Failing now is simply gives you more knowledge of how to do this later.


If you don't mind, I just want to clarify what you are saying to make sure I'm on the same page.

I currently have the 'Roll Dice' button as the way for the user to roll the dice. So once the user rolls the dice, the program calls the other class's function called, using your example, Die.Roll(). This function then rolls that one dice then control gets transferred back to Form1 to continue on with the program or any other events that take place. I think I get what you are saying there, but eventually I still need to pass the value of the dice that is being shown in the PictureBox to the scoring class where I go through which dice was held and calculate the best possible score. Therein is my problem. I can't get it to passt the face value of the dice to the fuction that scores. It would seem, and I'm probably wrong and need to be slapped and corrected, that I still run into the same issue regardless of whether or not I use the parallel array or the class you had mentioned above. And just on a side note, I don't like using parallel arrays either. The code that was there was my professor working to figure out what I was doing wrong or how to pass the face values of the dice to the fuction that scores points and she couldn't figure it out either. Which, when all the dust settles, didn't leave me with much hope of figuring it out which is ultimately why I'm here after a week and a half of frustration.

Again, that you VERY much for your help. I know my e-mails are long winded but I'm so far in this project that it's hard to explain via posts without someone actually seeing what my program is doing.
Was This Post Helpful? 0
  • +
  • -

#6 Robin19  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 271
  • View blog
  • Posts: 550
  • Joined: 07-July 10

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 15 October 2012 - 09:54 AM

Not quite. Form1 will call (DieUserControl).Roll(). From1 shouldn't care what happens to the die or the picturebox (both of which are private fields of DieUserControl). The basic idea is to separate concern. The Die class handles what the value is. The DieUserControl handles displaying and interfacing with the Die class. Form1 handles user input and holds a variable number of DieUserControls.

Notice how clean and sparce Form1 can be:
public partial Form1 : Form
{
   // create and add to this list in the constructor
   private List<DieUserControl> AllDice;
   // Event handler can call this method
   private void RollDice()
   {
      foreach(DieUserControl duc in AllDice)
         duc.Roll();
   }

   private int AllDiceValue
   {
      get
      {
         int value = 0;
         foreach(DieUserControl duc in AllDice)
            value += duc.Value;
         return value;
      }
   }
}


DiceUserControl can do the gui lifting:
public class DieUserControl : UserControl
{
   private Die Die;
   public int Value
   {
      get { return Die.Value; }
   }
   
   public DieUserControl()
   {
      Die = new Die();
      Roll(); // optional
   }

   public void Roll()
   {
      Die.Roll();
      picDie.Image = // base image on Die.Value.  There are multiple ways to calculate this from here.
   }
}


And the Die class can do the logic. It is completely seperated from any GUI ideas so it can be reused in a WPF or even a console project.
public class Die
{
   static Random _random;
   static Random MyRandom
   {
      get
      {
         if (_random == null)
            _random = new Random();
         return _random;
      }
   }

   public int Value { get; set; }

   public void Roll()
   {
      Value = MyRandom.Next(1, 7);
   }
}


One reason to use this method is to facilitate change. It won't take much work to play the game with 8 dice or make them 10 sided dice.
Was This Post Helpful? 0
  • +
  • -

#7 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2251
  • View blog
  • Posts: 9,435
  • Joined: 29-May 08

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 15 October 2012 - 10:44 AM

Hint. Look in the VB.Net Challenge Section, there was challenge that involved a die.
Was This Post Helpful? 0
  • +
  • -

#8 psnyder  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 11-October 12

Re: C# Farkle Game Problem - School Project - Code and Example Included

Posted 15 October 2012 - 10:50 AM

Quote

name='Robin19' date='15 October 2012 - 09:54 AM' timestamp='1350320091' post='1723921']
Not quite. Form1 will call (DieUserControl).Roll(). From1 shouldn't care what happens to the die or the picturebox (both of which are private fields of DieUserControl). The basic idea is to separate concern. The Die class handles what the value is. The DieUserControl handles displaying and interfacing with the Die class. Form1 handles user input and holds a variable number of DieUserControls.



Thank you very much for your help. I got it figured out the other day and apparently the array that I used couldn't compare index values to the list. For some reason, the comparison had to happen between two arrays. Is it because two different collections can't work together and have to be the same type of collection??? Don't understand but will have to play with that later to see what comes out of it.

Either way, thank you very much for your time. I'm glad I have a place to go to ask questions when I have struggled for a week and can't figure something out. It's nice to get hints but not the exact answer as I like solving it on my own and learning this stuff.

Have a good one.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1