4

Total noob here. This is my first c# attempt, its a console application that simulates a drinking game called 'Left Right Center'. In the console I receive the following:

CONSOLE

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
at LeftRightCenter.MainClass.Main (System.String[] args) [0x00038] in     /Users/apple/Projects/LearningC/LearningC/Main.cs:80 
[ERROR] FATAL UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object
 at LeftRightCenter.MainClass.Main (System.String[] args) [0x00038] in /Users/apple/Projects/LearningC/LearningC/Main.cs:80 

C#

    using System;

    namespace LeftRightCenter
    {
        class Player
        {
            //fields        
            private int _quarters = 4;

            public int Quarters {
                get{ return _quarters; }
                set{ _quarters += value; }
            }

            public Player (string name)
            {

            }   

        }
        class Dice
        {
            Random random = new Random();
            public int Roll ()
            {
                random = new Random ();
                int diceSide;
                diceSide = random.Next (0, 6);
                diceSide = (diceSide > 2) ? 3 : diceSide;
                return diceSide;            
            }
        }
        class MainClass
        {
            static int activePlayer = 0;
            static int theCup       = 0;

            static Player[] thePlayers = { 
                new Player ("Jessica"), 
                new Player ("Isaac"), 
                new Player ("Ed"), 
                new Player ("Bella"),
                new Player ("Elisa"),
                new Player ("Fake RedHead"),
                new Player ("Linda"),
                new Player ("MJ"),
                new Player ("Irene"),
                new Player("Devin")
            };

            static Dice[] theDice = new Dice[2];

            private static void MoveQuarter (int direction)
            {
                int numberOfPlayers = thePlayers.Length - 1;
                switch (direction) {
                case 0: 
                    thePlayers [activePlayer].Quarters = -1;
                    theCup++;
                    break;
                case 1:
                    thePlayers [activePlayer].Quarters = -1;
                    int leftPlayer = (activePlayer == 0) ? numberOfPlayers : activePlayer - 1;
                    thePlayers [leftPlayer].Quarters = +1;
                    break;
                case 2:
                    thePlayers [activePlayer].Quarters = -1;
                    int rightPlayer = (activePlayer == numberOfPlayers) ? 0 : activePlayer + 1;
                    thePlayers [rightPlayer].Quarters = +1;
                    break;                          
                }           
            }

            public static void Main (string[] args)
            {
                int cupEndPoint = thePlayers.Length * 4 - 1;
                while (theCup < cupEndPoint) {
                    foreach (Dice rattle in theDice) {
                        if (thePlayers [activePlayer].Quarters > 0) {
                            MoveQuarter (rattle.Roll ()); // this line seems to be the problem  
                        }                   
                    }
                    Console.WriteLine ("{0} Quarters In the Cup", theCup);
                }

            }
        }
    }

I have no idea what the problem is or why, and my googling have proven more use confusing than helpful.

For those who are curious, I have little experiment working now

http://pastebin.com/jxCCW2cd

Fresheyeball
  • 29,567
  • 20
  • 102
  • 164
  • 6
    That's where you fire up the debugger and start investigating. Place a breakpoint on the offending line, run to that point, and start checking what went wrong. Is `rattle` null? Does `rattle.Roll()` return null? Nothing wrong with being a noob, but StackOverflow is not a "find my bugs for me" site. – Seva Alekseyev Jun 15 '12 at 21:06
  • This appears to be a very awkward organization of C# code. (Either that or a very advanced organization beyond my understanding.) I'm having trouble following where these objects are created as they static for reasons I am not understanding. Try moving from using static initialization to within your Main method via the "new" keyword. – BlackVegetable Jun 15 '12 at 21:06
  • I assume you're using Visual Studio, yes? – kevin628 Jun 15 '12 at 21:08
  • @SevaAlekseyev I know what the stackoverflow is for. I have never used breakpoints, and did run with debugging. – Fresheyeball Jun 15 '12 at 21:22
  • @kevin628 I am in monoDevelop – Fresheyeball Jun 15 '12 at 21:22
  • So start using them. They're good for you. Tracing from the program beginning to the offending line works, too, but breakpoints are easier. – Seva Alekseyev Jun 15 '12 at 21:23
  • @BlackVegetable sorry for the awkwardness, like I said, first real OO ever. I set those to static because it would not allow me to reference them in Main otherwise. – Fresheyeball Jun 15 '12 at 21:24
  • All of your "MainClass" content should be moved to your "main" method. If you know how to open up a chat room in Stack Overflow, invite me to it and I can walk you through a more OO approach to this. – BlackVegetable Jun 15 '12 at 21:32
  • I have invited you too a room. – Fresheyeball Jun 15 '12 at 21:40
  • @BlackVegetable or you can reach me on skype at 'fresheyeball' – Fresheyeball Jun 15 '12 at 21:41

1 Answers1

8

This line

static Dice[] theDice = new Dice[2]; 

declares an array that allows the storage of 2 objects of the Dice class, but each value in this array is still null.

You need to create a Dice on each slot of the array before using it in the foreach loop inside the Main method.

theDice[0] = new Dice();
theDice[1] = new Dice();

if you stop the debugger on the line

 MoveQuarter (rattle.Roll ()); 

you will see that the rattle Dice is null.

EDIT: Looking at your code I have found a problematic situations In the Roll method, you recreate the Random generator and this is no good for randomness. (See the accepted answer in this question)
Last, theDice array could be created and initialized in the same way you already do for thePlayers array

static Dice[] theDice = new Dice[2] {new Dice(), new Dice()};

This is a complete revision of your Dice class

class Dice 
{
    private static Random random;
    public  Dice()
    {
           // create the static random generator only on the first instance
        if(random == null) random = new Random();
    }

    public int Roll () 
    { 
        int diceSide; 
        diceSide = random.Next (1, 7); 
        diceSide = (diceSide > 2) ? 3 : diceSide; 
        return diceSide;             
    } 
} 
Community
  • 1
  • 1
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Darn it! You beat me to that by like 7 miunutes! I actually fired up Visual Studio to debug this! Good for you and +1! – David Jun 15 '12 at 21:13
  • Sorry for the noobetry, but new Dice[2] creates only 2 slots? I thought it was zero based and would generate 3 slots. Anyway I put in `theDice[0] = new Dice();` and got `Unexpected symbol '0' in class, struct, or interface member declaration` – Fresheyeball Jun 15 '12 at 21:33
  • It is a sad thing about Java/C# IMO. When specifying a length, it is 1 based. When specifying an index, it is 0 based. – BlackVegetable Jun 15 '12 at 21:37
  • uhm, seems something wrong in code. You could also initialze the TWO slots [0] and [1] in the same way you already do for thePlayers – Steve Jun 15 '12 at 21:50
  • There was a bunch wrong. But like I said, first C# ever. Got it all working now. Thank you all for your help. – Fresheyeball Jun 17 '12 at 21:14
  • I noticed that you used the constructor to initialize `random`. I ended up doing so entirely outside an method. Is there a value to doing it in the constructor? Also why the `if(random == null)`? – Fresheyeball Jun 17 '12 at 22:13
  • the random var is declared as static. So, every Dice instance share the same variable. This is done to have a better randomness on the number generated. (See the refs on the code above). Of course the static instance of the class Random should be created somewhere. I have choosen to create it when the first instance of Dice will be created (random is null at this point), but you could ask the compiler to create for you using this declaration `static Random random = new Random();` – Steve Jun 17 '12 at 22:20
  • Interesting! Coming from JS the idea that a random can be a 'better' random number is new to me; but it makes sense! – Fresheyeball Jun 17 '12 at 23:50