Hi guys, if anyone can help me with the basic C# programming concepts, please send me an email at <email snipped> and I can email you my project for you to see what the problem is with it.

It is almost complete but it keeps throwing an exception and I do not know how to fix it. I am trying to create a blackjack game.

Looking forward to the email response.

Wesley

Edited 7 Years Ago by Nick Evan: snipped email

At least post the section of the code you are having trouble with. People like to keep stuff in the forum so everyone can learn (among other reasons).

Hi,

In order to see the problem, you need the whole project but here it is anyway:

private card GetCardFromDeck()
        {
            //This method is meant to draw a random card
            //lets hope it works
            Random r = new Random();
            card c;
            if (playingDeck.Count <= 2)
            {
                //add a new deck to the table
                NewDeck();
            }
            // get a random number from the possible.
            int randomNumber = r.Next(1,playingDeck.Count); (This is the line that is causing the problem)
            //which card did we choose?
            c = (card)playingDeck[randomNumber];
            //take the card out of the deck
            playingDeck.RemoveAt(randomNumber);

            return c;
        }

It throws an ArguementOutOfRangeException.

Line 13 : playingDeck.Count must be smaller than 1
jonsca is right, if you post code and point the error the chance is greater you will get some help...

What type of collection is playingDeck and how many objects are in it when thew exception occurs? If the collection is empty then count will return 0 which will throw an OutOfBoundsException because the second parameter must be equal to or larger than the first in the Random.Next() method call.

Add a breakpoint and check the value of playingDeck.Count at the point of the exception. If it is returning zero then you need to check the method that adds cards to the deck.

It might be that when you have 1 item left, your generator is picking the index of 1 (since you don't allow for the 0th index at all for whatever reason). deck[1] doesn't exist anymore it's deck[0]. int randomNumber = r.Next([B]0[/B],playingDeck.Count);

I think I should email you two the projects so you can see exactly what is going on. I am still a beginner so dont really know what to do.

Well you can attested your project here,
When you giving reply, so in below you find a button(named Go Advanced)
, Click that button from there you can attested your project........

randomNumber could be equal to playingDeck.Count which will cause arraybound exception.

the Next() of Random goes from (inclusivelowerbound,exclusiveupperbound)

Hi Guys,

The file does not want to upload so here is the class:

/*
 * Filename:            Form1.cs
 * Author:              Wesley Chin
 * Created:             15/11/2009    
 * Operating system:    Windows XP Professional with Service Pack 3, Windows Vista Ultimate Edition
 *                      and Windows 7 Enterprise Edition
 * 
 * 
 * Description:         This program was written to play a fully functional Blackjack game according
 *                      to the specifications given.
 *                      This class contains all the components that were added to the form (GUI),
 *                      as well as their methods and events.
 */

// The namespaces that were needed
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;

// Declaring the scope of the form
namespace Blackjack
{
    /*
     * The class is defined as partial because this source file is not the entire class.
     * The frest of it is defined elsewhere. ie Form1.Designer.cs.
     */ 
    public partial class Form1 : Form
    {
        // Initializing all the variables that will be used 
        private ArrayList deck;
        private ArrayList playingDeck;
        private int dealerTotal;
        private int playerTotal;
        private string deckImage;
        // this is the face down card of the dealer
        private card holeCard;
        private PictureBox holeCardBox;
        private bool revealHoleCard = false;
        private bool revealedHoleCard = false;
        private bool thatsTheHoleCard = false;
        private ArrayList pictureBoxes = new ArrayList();
        private bool dealingCard = false;

        int numOfElevenAcesPlayer = 0;
        int numOfElevenAcesDealer = 0;

        int totalCardsOnPlayerSide = 0;
        int totalCardsOnDealerSide = 0;


        #region MyRegion
        // Constructor
        public Form1()
        {
            InitializeComponent();
            SetButtons(false);
            dealBtn.Enabled = false;
            CreateDeck();

        }
        #endregion

        // All the methods were declared private but it does not matter because there is only one class accessing these methods
        #region Methods

        private void CreateDeck()
        {
            //routine to create a deck of Card objects
            deck = new ArrayList();
            // get a reference to the current assembly
            Assembly a = Assembly.GetExecutingAssembly();

            // get a list of resource names from the manifest
            string[] resNames = a.GetManifestResourceNames();

            foreach (string s in resNames)
            {
                int i = 0;
                if (s.ToLower().Contains("-2-"))
                    i = 2;
                else if (s.ToLower().Contains("-3-"))
                    i = 3;
                else if (s.ToLower().Contains("-4-"))
                    i = 4;
                else if (s.ToLower().Contains("-5-"))
                    i = 5;
                else if (s.ToLower().Contains("-6-"))
                    i = 6;
                else if (s.ToLower().Contains("-7-"))
                    i = 7;
                else if (s.ToLower().Contains("-8-"))
                    i = 8;
                else if (s.ToLower().Contains("-9-"))
                    i = 9;
                else if (s.ToLower().Contains("-10-"))
                    i = 10;
                else if (s.ToLower().Contains("-j-"))
                    i = 10;
                else if (s.ToLower().Contains("-q-"))
                    i = 10;
                else if (s.ToLower().Contains("-k-"))
                    i = 10;
                else if (s.ToLower().Contains("-a-"))
                    i = 0;
                else if (s.ToLower().Contains("deckbackground"))
                {
                    deckImage = s;
                    continue;
                }
                else continue;
                deck.Add(new card(s, i));
            }
        }

        private void NewDeck()
        {
            //we dont want to recreate the deck everytime C:
            //also cloning stuff is cool
            playingDeck = (ArrayList)deck.Clone();
        }

        private void dealerAction()
        {
            //routine for the actions the dealer might make.
            // play untill its over
            while (true)
            {
                if (!revealHoleCard)
                {
                    revealHoleCard = true;
                    //reveal the hole card!
                    DealCard(true);
                }
                if ((dealerTotal > 21) & (numOfElevenAcesDealer > 0))
                {
                    dealerTotal -= 10;
                    numOfElevenAcesDealer--;
                    UpdateUI();
                }
                if (dealerTotal >= 17)
                {
                    //dealer stands
                    ComputeNextAction(true);
                    break;
                }
                else
                {
                    // dealer hits
                    DealCard(true);
                }
            }
        }

        private void ComputeNextAction(bool player)
        {
            //routine to compute what to do next
            if (player)
            {
                //dealer has finished his actions
                if (playerTotal > 21)
                    //player bust G_G
                    Defeat();
                else if ((dealerTotal <= 21) && (dealerTotal > playerTotal))
                    //you lose again
                    Defeat();
                else if (playerTotal == dealerTotal)
                    //its a tie (-_-)
                    Tie();
                else if ((dealerTotal > 21) || (playerTotal > dealerTotal))
                    //you win \\:D//
                    Victory();
            }
            else
            {
                //player just made an action
                if ((playerTotal > 21) & (numOfElevenAcesPlayer > 0))
                {
                    playerTotal -= 10;
                    numOfElevenAcesPlayer--;
                    UpdateUI();
                }
                if (playerTotal >= 21)
                {
                    dealerAction();
                }
                else
                {
                    SetButtons(true);
                }
            }
        }

        private void Victory()
        {
            //Yayz player wins!
            UpdateUI();
            dealBtn.Enabled = true;
            MessageBox.Show("You have beaten the dealer!", "Won", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void Defeat()
        {
            //D: dealer wins oh no!
            UpdateUI();
            dealBtn.Enabled = true;
            MessageBox.Show("You have lost to the dealer!", "Lost", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void Tie()
        {
            //the game is tied. meh
            UpdateUI();
            dealBtn.Enabled = true;
            MessageBox.Show("You have tied the dealer!", "Tie", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void ClearTable()
        {
            //routine to get rid of all the cards on the table
            totalCardsOnDealerSide = 0;
            totalCardsOnPlayerSide = 0;
            while (pictureBoxes.Count > 0)
            {
                PictureBox b = (PictureBox)pictureBoxes[0];
                Controls.Remove(b);
                pictureBoxes.RemoveAt(0);
            }
        }

        private void removeHoleCard()
        {
            //routine to remove the hole card after its been dealt
            Controls.Remove(holeCardBox);
        }

        private void NewGame()
        {
            //initialise values
            dealerTotal = 0;
            playerTotal = 0;
            UpdateUI();
            //initialise deck
            NewDeck();
            //clear any cards off the table
            ClearTable();
            //deal to the dealer
            DealCard(true);
            DealCard(true);
            //deal to the player
            DealCard(false);
            DealCard(false);
            //what do we do next?
            ComputeNextAction(false);
        }

        private void SetButtons(bool enabled)
        {
            hitBtn.Enabled = enabled;
            standBtn.Enabled = enabled;
        }

        private int CardValue(int TotalScore, int CardValue, bool player)
        {
            //routine to check what value the card should be if its an ace
            if (CardValue == 0)
            {
                //the cards an ace.
                if ((TotalScore + 11) > 21)
                {
                    CardValue = 1;
                }
                else
                {
                    CardValue = 11;
                    if (player)
                        //dealer has an ace
                        numOfElevenAcesDealer++;
                    else numOfElevenAcesPlayer++;
                }
            }
            return CardValue;
        }

        private void UpdateUI()
        {
            dealersTotal.Text = "Dealer Total: " + dealerTotal;
            playersTotal.Text = "Player Total: " + playerTotal;
        }

        private void DealCard(bool player)
        {
            //method to deal a card and remember the correct information
            card c = GetCardFromDeck();
            if (player)
            {
                //the dealer gets a card
                //if its the Hole Card save it as such
                if ((totalCardsOnDealerSide == 1) & !revealedHoleCard)
                {
                    holeCard = c;
                    //place a face down card on the table
                    card facedown = new card(deckImage, 0);
                    thatsTheHoleCard = true;
                    NewCardOnTable(player, facedown);
                }
                else if (revealHoleCard & !revealedHoleCard)
                {
                    //reveal the hole card
                    dealerTotal += CardValue(dealerTotal, holeCard.CardValue, player);
                    totalCardsOnDealerSide--;
                    removeHoleCard();
                    NewCardOnTable(player, holeCard);
                    revealedHoleCard = true;
                    UpdateUI();
                }
                else
                {
                    //just deal to the dealer
                    dealerTotal += CardValue(dealerTotal, c.CardValue, player);
                    NewCardOnTable(player, c);
                }
            }
            else
            {
                playerTotal += CardValue(playerTotal, c.CardValue, player);
                //we are dealing to the player
                NewCardOnTable(player, c);
            }
            UpdateUI();
            dealingCard = false;
        }

        private void NewCardOnTable(bool player, card c)
        {
            PictureBox pic = new PictureBox();
            try
            {
                System.Reflection.Assembly thisExe;
                thisExe = System.Reflection.Assembly.GetExecutingAssembly();
                System.IO.Stream file = thisExe.GetManifestResourceStream(c.Image);
                pic.Image = Image.FromStream(file);

            }
            catch (Exception exc)
            {
                playersTotal.Text = exc.Message;
            }
            if (player)
            {
                //we are dealing to the Dealer
                pic.Width = 104;
                pic.Height = 135;
                pic.Top = 39;
                pic.Left = 328 + (110 * totalCardsOnDealerSide++);
            }
            else
            {
                //we are dealing to the Player
                pic.Width = 104;
                pic.Height = 135;
                pic.Top = 364;
                pic.Left = 328 + (110 * totalCardsOnPlayerSide++);

            }
            pic.SizeMode = PictureBoxSizeMode.StretchImage;
            //add the picture to the thing
            Controls.Add(pic);
            //all cards are added to this so i can remove them after a hand is dealt
            //except the hole card
            if (!thatsTheHoleCard)
                pictureBoxes.Add(pic);
            else
            {
                holeCardBox = pic;
                thatsTheHoleCard = false;
            }
        }

        private card GetCardFromDeck()
        {
            //This method is meant to draw a random card
            //lets hope it works
            Random r = new Random();
            card c;
            if (playingDeck.Count <= 2)
            {
                //add a new deck to the table
                NewDeck();
            }
            // get a random number from the possible.
            int randomNumber = r.Next(1,playingDeck.Count);
            //which card did we choose?
            c = (card)playingDeck[randomNumber];
            //take the card out of the deck
            playingDeck.RemoveAt(randomNumber);

            return c;
        }
        #endregion
        
        // The game will exit when the Exit option is click in the Menustrip
        private void exitGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        // Using the timer control to set the time to the label created to display the current time.
        private void tmrClock_Tick(object sender, EventArgs e)
        {
            clockLbl.Text = DateTime.Now.ToLongTimeString();
        }

        private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewGame();
        }

        private void newGameBtn_Click(object sender, EventArgs e)
        {
            NewGame();
        }

        private void exitBtn_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void standBtn_Click(object sender, EventArgs e)
        {
            SetButtons(false);
            dealerAction();
        }

        private void hitBtn_Click(object sender, EventArgs e)
        {
            DealCard(false);
            SetButtons(false);
            ComputeNextAction(false);
        }

        private void dealBtn_Click(object sender, EventArgs e)
        {
            revealedHoleCard = false;
            revealHoleCard = false;
            dealBtn.Enabled = false;
            dealerTotal = 0;
            playerTotal = 0;
            //clear any cards off the table
            ClearTable();
            //deal to the dealer
            DealCard(true);
            DealCard(true);
            //deal to the player
            DealCard(false);
            DealCard(false);
            ComputeNextAction(false);            

        }
    }
}

The other class is the card.cs class which just has properties for the cards.

Can you run a couple of test for me:
insert a breakpoint at line 121 and check the contents of deck. Ensure that all the cards are there as expected. If that is not the case then create a breakpoint at line 84, check that all the expected resources are present and in the expected format.

If the Random.Next() method is throwing an OutOfBoundsException it seems likely that your array is not ebing correctly initialised and is returning a count of zero.

This article has been dead for over six months. Start a new discussion instead.