This is my code. I am learning this through the microsoft C# for absolute beginners book. I am on chapter 8 on the final soccer program and have no errors. The only problem I have is when I run it. I get $exception {Index was outside the bounds of the Array} on line of code that is stared. I have been trying to figure this out for the past few hours and have no idea on how to fix it.

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

namespace FinalSoccerGame
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            setupPlayers();
            setupOpp();
            SetupGoalies();

        }//end constructor

        //constants for players
        private int GOALIE = 0;
        private int FULLBACK = 1;
        private int HALFBACK = 2;
        private int WING = 3;
        private int CENTER = 4;
        private int SHOT = 5;

        //array for player names
        private string[] playerName = {
            "Goalie",
                "Fullback",
                "Halfback",
                "Wing",
                "Center",
                "Shot",
        };
        //primary game variables
        private int playerScore = 0;
        private int oppScore = 0;
        private int timeLeft = 600;
        private int currentPlayer;
        private int nextPlayer;

        //data structure for likelihood of shot
        private double[,] shotChance =
        {
            {-1, .8, .6, .4, .1, .01},
            {.8, -1, .8, .6, .4, .02},
            {.8, .8, -1, .8, .6, .03},
            {.8, .8, .8, -1, .8, .04},
            {.8, .8, .8, .8, -1, .2},
            {.8, .8, .8, .8, .8, -1}
        };
        private PictureBox[] picPlay = new PictureBox[5];

        private void setupPlayers()
        {
            //setting up my own picture boxes
            int x;
            int y;
            //step through the players
            for (int i = 0; i < 6; i++)
            {

                //standard control setup
                picPlay[i] = new PictureBox();
                picPlay[i].Size = new Size(25, 25);

                //start all players in the center of the field
                //on the x (horizontal) axis
                x = (int)((pnlField.Width - picPlay[i].Width) / 2);

                if (i> GOALIE)
                {
                    //move all players but goalie to a Y value
                    //related to their position (center close to opp),
                    //fullback close to own goal
                    y = (int)(pnlField.Height / i);
                    picPlay[i].Location = new Point(x, y);
                }//end if
                //set up the image to the yellow no ball player
                picPlay[i].Image = myPics.Images[2];
                picPlay[i].SizeMode = PictureBoxSizeMode.StretchImage;

                //use the tag field to store the player number
                picPlay[i].Tag = i.ToString();

                //register the event listener
                picPlay[i].Click += new EventHandler(clickPlayer);

                //add the player to the panel
                pnlField.Controls.Add(picPlay[i]);
            }//end for loop
        }//end setupPlayers
        private void setupOpp()
        {
            //set up opponents
            int x;
            int y;

            for (int i=1; i < 5; i++)
            {
                picPlay[i] = new PictureBox();
                **picPlay[i].Size = new Size(25, 25);**
                x = (int)((this.Width - picPlay[i].Width) / 2);
                y = (int)(pnlField.Height / i - 30);
                picPlay[i].Location = new Point(x, y);
                picPlay[i].Image = myPics.Images[0];
                picPlay[i].SizeMode = PictureBoxSizeMode.StretchImage;
                pnlField.Controls.Add(picPlay[i]);
            }//end for loop
        }//end setupOpp

        private void SetupGoalies()
        {
            //place goalies more carefully
            int x;
            int y;

            x = (int)((pnlField.Width - picPlay[GOALIE].Width) / 2);
            y = pnlField.Height - picPlay[GOALIE].Height - 20;
            picPlay[GOALIE].Location = new Point(x, y);
            picPlay[SHOT].Location = new Point(x, 0);
            picPlay[GOALIE].Image = myPics.Images[5];
            picPlay[SHOT].Image = myPics.Images[4];
        }//end setupGoalies

        private void clickPlayer(Object sender, EventArgs e)
        {
            //happens whenever you click a player
            Random roller = new Random();
            double toSucceed;
            double myRoll;

            //figure out which player was clicked
            PictureBox thePic = (PictureBox)sender;
            int playerNumber = Convert.ToInt32(thePic.Tag);
            nextPlayer = playerNumber;

            //figure out how likely success is
            toSucceed = shotChance[currentPlayer, nextPlayer];

            //roll a random double
            myRoll = roller.NextDouble();

            //Announce what's going on
            string message = "From: " + playerName[currentPlayer];
            message += " to: " + playerName[nextPlayer] + " ";
            message += toSucceed.ToString();
            lblAnnounce.Text = message;

            //look for success
            if (myRoll < toSucceed)
            {
                goodShot();
            }
            else
            {
                badShot();
            }//end 'pass succeeds' if

        }//end clickPlayer

        public void goodShot()
        {
            //if the shot succeeded

            //check to see if it's a shot on goal
            if (nextPlayer == SHOT)
            {
                playerScore++;
                updateScore();
                MessageBox.Show("Goooooooooaaaaaalllll!!!!!");
                setPlayer(HALFBACK);
            } else
            {
                lblAnnounce.Text = playerName[nextPlayer] + " now has ball";
                setPlayer(nextPlayer);
            }//end 'scored a goal' if
        }//end goodShot

        public void badShot()
        {
            Random roller = new Random();
            double toSucceed;
            int playerNumber;

            lblAnnounce.Text = "Opponent gets ball...";
            //check for opponent goal
            toSucceed = roller.NextDouble();
            //change the following value to alter game difficulty
            if (toSucceed < .05)
            {
                oppScore++;
                updateScore();
                MessageBox.Show("Opponent Scores!!");
                setPlayer(HALFBACK);
            }
            else
            {
                playerNumber = roller.Next(5);
                lblAnnounce.Text += "recovered by " + playerName[playerNumber];
                setPlayer(playerNumber);
            }//end opponent scores if

        }//end badShot
        public void setPlayer(int playerNumber)
        {
            //given a player number, shows that player as having the ball,
            //all others not having the ball
            //set up the current player variable
            currentPlayer = playerNumber;
            //show no player with ball
            for (int i = 0; i < 5; i++)
            {
                picPlay[i].BorderStyle = BorderStyle.None;
                picPlay[i].Image = myPics.Images[2];
            } // end for loop
              //reset goalie image
            picPlay[GOALIE].Image = myPics.Images[5];
            //show current player holding ball
            picPlay[playerNumber].BorderStyle = BorderStyle.FixedSingle;
            picPlay[playerNumber].Image = myPics.Images[3];
        } // end setPlayer

        private void timer1_Tick(object sender, EventArgs e)
        {
            updateTime();
            movePlayers();
            moveOpp();

        }//end timerTick

        private void updateTime()
        {
            //calculate time left
            timeLeft--;
            if (timeLeft <= 0)
            {
                timer1.Enabled = false;
                DialogResult playAgain = MessageBox.Show("Game Over. Play Again?", "Soccer", MessageBoxButtons.YesNo);
                if (playAgain == DialogResult.Yes)
                {
                    //start over
                    playerScore = 0;
                    oppScore = 0;
                    timeLeft = 600;
                    currentPlayer = FULLBACK;
                    updateScore();
                    timer1.Enabled = true;
                }
                else
                {
                    //end game
                    Application.Exit();
                }//end playAgain if
            }
            else
            {
                double totalSeconds = timeLeft / 10;
                int minutes = (int)(totalSeconds / 60);
                int seconds = (int)(totalSeconds % 60);
                string timeString = minutes.ToString() + ": " + seconds.ToString();
                lblTime.Text = timeString;
            }//end if

        }//end updateTime

        private void movePlayers()
        {
            //move players
            int motion;
            Random roller = new Random();
            for (int i = 1; i < 5; i++)
            {
                motion = roller.Next(11) - 5;
                picPlay[i].Left += motion;
                motion = roller.Next(11) - 5;
                picPlay[i].Top += motion;
                //check for boundaries
                if (picPlay[i].Left < 0)
                {
                    picPlay[i].Left = 0;
                }
                else if (picPlay[i].Left + picPlay[i].Width > pnlField.Width)
                {
                    picPlay[i].Left = pnlField.Width - picPlay[i].Width;
                }
                else if (picPlay[i].Top < 0)
                {
                    picPlay[i].Top = 0;
                }
                else if (picPlay[i].Top + picPlay[i].Height > pnlField.Height)
                {
                    picPlay[i].Top = pnlField.Height - picPlay[i].Height;
                } // end if
            } // end for loop
        } // end movePlayers

        private void moveOpp()
        {
            //move opponents
            int motion;
            Random roller = new Random();

            for (int i = 1; i < 5; i++)
            {
                motion = roller.Next(11) - 5;
                picPlay[i].Left = +motion;
                motion = roller.Next(11) - 5;
                picPlay[i].Top += motion;

                //check for boundaries
                if (picPlay[i].Left < 0)
                {
                    picPlay[i].Left = 0;
                }
                else if (picPlay[i].Left + picPlay[i].Width > pnlField.Width)
                {
                    picPlay[i].Left = pnlField.Width - picPlay[i].Width;
                }
                else if (picPlay[i].Top < 0)
                {
                    picPlay[i].Top = 0;
                }
                else if (picPlay[i].Top + picPlay[i].Height > pnlField.Height)
                {
                    picPlay[i].Top = pnlField.Height - picPlay[i].Height;
                } // end if
            } // end for loop
        } // end moveOpp
        private void updateScore()
        {
            lblPlScore.Text = "Player: " + playerScore.ToString();
            lblOppScore.Text = " Opp: " + oppScore.ToString();
        }//end updateScore
    }
}

Dani AI

Generated

The exception is almost always an indexing mismatch: your code defines six player roles (GOALIE through SHOT) but the picPlay array and several loops use different bounds. That means at runtime the code tries to read or write picPlay[5] while the array only allows 0..4, so the CLR throws "Index was outside the bounds of the Array." was on the right track calling out the array-size mismatch, and ' question about the line number is exactly what helps pinpoint which access is out of range.

Concrete, safe fixes:

  • Make the number of PictureBoxes and your loops come from one source of truth. For example, use a single constant (e.g. NUM_PLAYERS = 6) and create picPlay with that length, or use new PictureBox[6] if you need indexes 0..5. Then loop with i < picPlay.Length instead of hard-coded 5 or 6.
  • Ensure initialization order: every picPlay[index] must be instantiated before any method (like SetupGoalies) references it. If a method accesses picPlay[GOALIE] or picPlay[SHOT] before those elements exist you will get the same exception.
  • Add simple guards while debugging: check if (index < 0 || index >= picPlay.Length) before using it, or inspect the stack trace / set a breakpoint where the exception is thrown.

Other problems to watch for (noticed in the thread):

  • moveOpp appears to assign Left = +motion instead of adding the motion; use += to move relative to current position.
  • Creating Random repeatedly can produce poor randomness; instantiate one Random at class level and reuse it.
  • You reuse picPlay for both “your” players and opponents — that can overwrite elements. Consider separate arrays for opponents, or carefully manage indices so you don't accidentally reassign or add the same PictureBox twice.

Finally, ’s diagnostic MessageBox technique is useful: check the values of SHOT, GOALIE, picPlay.Length and the exact index when the exception occurs. That will immediately confirm whether it’s a bounds mismatch or an uninitialized element.

Recommended Answers

All 6 Replies

On what line is the exception thrown? The error states you are using an index greater than what is possible.

line 109 (still quite new to all of this code)

It looks like your array is 5 in size. So you can put 0 to 4 in the reference and 5 is too much. Fix or cheat? Create a six element array?
I can't guess where you are in learning to code but my view is to understand arrays better. If it's a one off piece of code you are not submitting to review, just make it work.

After line 126, add the following (for troubleshooting purposes):

string msg = string.Empty;
msg += "x: " + x.ToString() + System.Environment.NewLine;
msg += "y: " + y.ToString() + System.Environment.NewLine;
msg += "SHOT: " + SHOT.ToString() + System.Environment.NewLine;
msg += "GOALIE: " + GOALIE.ToString() + System.Environment.NewLine;
msg += "picPlay Length is " + picPlay.Length  + " -- Index numbers are 0 to " + (picPlay.Length - 1) + System.Environment.NewLine;

MessageBox.Show(msg, "Values");

What is the value of "SHOT"? Where is this value set?

Also, line 67 you have for (int i = 0; i < 6; i++) which should be i < 5.

How do you have "myPics" defined?

Fixed it thanks for your input. I retyped it out into a new project and it worked.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.