Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

C# C# Objects Loops and Final Touches Playing the Game

Help in the challange of letting the user input the tower coordinates

Hi, this is the complete code:

using System;

namespace TreehouseDefense
{
    class Game
    {
        public static void Main()
        {
            Map map = new Map(8, 5);
            try
            {


//we declare an array of MapLocations(map locations points) that will represent our path going down the middle of the map.

//we pass to the Path constrcutor an array of type MapLocation(in order to create a path object we need to pass it) that contains mapLocation points and we test we get the proper location at the specifed index.
                Path path = new Path(
                    new[] {
                        new MapLocation(0,2,map),
                        new MapLocation(1,2,map),
                        new MapLocation(2,2,map),
                        new MapLocation(3,2,map),
                        new MapLocation(4,2,map),
                        new MapLocation(5,2,map),
                        new MapLocation(6,2,map),
                        new MapLocation(7,2,map)
                    }
                );


                //we create an array of invaders and passing in 4 Invader Object which needs a path so we pass in the path as well(the path is a MapLocation object)
                Invader[] invaders = 
                {
                    new Invader(path),
                    new Invader(path),
                    new Invader(path),
                    new Invader(path),
                    new Invader(path),

                };


                Level level1 = new Level(invaders);

                Console.WriteLine("Welcome to the tower defense game :], Where would u like to place your towers?");
                Console.WriteLine("Enter the X,Y coordinatyes (0-7) (0-4): ");
                var entryXY = Console.ReadLine();
                var coords = entryXY.Split(',');
                int towerOneX = int.Parse(coords[0]);
                int towerOneY = int.Parse(coords[1]);

                MapLocation towerLocation = new MapLocation(towerOneX, towerOneY, map);

                Tower tower = new Tower(towerLocation);


                //we set the tower property on the level.
                level1.Towers = tower


                bool playerWon =  level1.Play();
                if(playerWon)
                {
                    Console.WriteLine("You Won the game :]");
                }
                else
                {
                    Console.WriteLine("You lost :[");
                }

            // Important RULE : more specific exception types need to be placed before the more general exception types >> thats why we catch the specific outOfBounfsException first and then the more general ones.
            }
            catch(outOfBoundsException ex)
            {
                Console.WriteLine(ex.Message);

            }

            catch(treehouseDefenseException)
            {
                Console.WriteLine("Unhandled treehouseDefenseException");

            }


            catch(Exception ex)
            {
                Console.WriteLine("Unhandled System.Exception: " + ex);


            }


        }
    }
}

I saw Steven's answer which was :

Console.WriteLine("Welcome to the tower defense game :], Where would u like to place your towers?");
                Console.WriteLine("Enter the X,Y coordinatyes (0-7) (0-4): ");

                var entryXY = Console.ReadLine();//we input the coordinates
                                // i kinda didnt understand this line but i as far as i knowwe created an array called coords >> what this line doex? especially the Split() method 
                var coords = entryXY.Split(',');
                                //we parse the element that we got from the user from index 0 in the coords array and assign a variable to it.
                int towerOneX = int.Parse(coords[0]);
                                 //same here
                int towerOneY = int.Parse(coords[1]);

                                 //then i created a map location object(which take x,y and a map)
                MapLocation towerLocation = new MapLocation(towerOneX, towerOneY, map);

                                //and assigned   it to create a new tower.
                Tower tower = new Tower(towerLocation);

i know there are erros but i dont really know where.. I got this error while trying to complie: Enter the X,Y coordinatyes (0-7) (0-4):
0,3
Unhandled System.Exception: System.NullReferenceException: Object reference not set to an instance of an object
at TreehouseDefense.Level.Play () <0x40d3b650 + 0x0007f> in <filename unknown>:0
at TreehouseDefense.Game.Main () <0x40d36d50 + 0x0081f> in <filename unknown>:0

Steven Parker

it will be much appreciated if u could look at the code and help me.

Steven Parker
Steven Parker
220,415 Points

One thing caught my eye on first glance:

                level1.Towers = tower      // <-- missing semicolon (;)

If that doesn't fix it, can you post a link to a snapshot?

7 Answers

Steven Parker
Steven Parker
220,415 Points

On closer inspection in the snapshot, there was more to that line than a missing semicolon. The "Towers" array in the level had not been initialized. So expanding that line:

                level1.Towers = new Tower[]{tower};  // create array with the new tower in it

Steven Parker Hi, thanks for ur answer its working! however i need ur help to shine some light about the code :]: I can create more towers by just creating another Tower object and pass a towerLoaction to it? this is the script:

        //we create an array of Towers and pass in 3 Tower objects which needs a MapLocation object.
             Console.WriteLine("Welcome to the tower defense game :], Where would u like to place your towers?");
                Console.WriteLine("Enter the X,Y coordinatyes (0-7) (0-4): ");

                //entryXY will hold user input.
                var entryXY = Console.ReadLine();
                //how excatly Split() works? >> we Split lets say (2,3) into an array that seprate to 2  3 ?
                var coords = entryXY.Split(',');
                //after that we parse the element in index 0 in coords which is 2 to be an int 
                int towerOneX = int.Parse(coords[0]);
                // we do the same for index 1 for 3?
                int towerOneY = int.Parse(coords[1]);

                MapLocation towerLocation = new MapLocation(towerOneX, towerOneY, map);

                Tower tower = new Tower(towerLocation);
                Tower tower2 = new Tower(towerLocation);
                Tower tower3 = new Tower(towerLocation);
                Level level1 = new Level(invaders);
                level1.Towers = new Tower[]{tower, tower2, tower3};

can u further explain about the Split() method? i understand that it seperate the input into an array automatically with a comma between both of them.

another thing, in the first example i only created 1 tower so i tried to create 3 towers and pass set them into the Towers property.

the input Im entering rn its like say 3,1,4,2,6,3 and 0,1 and the game is running even though i didnt i only set the Towers property to hold 3 objetcs of Tower and i passed into the console 4 objetcs.

current snapshot: https://w.trhou.se/84cb0ewkvy

thanks in advance!!

Steven Parker
Steven Parker
220,415 Points

You're right about the comma, but you're only converting the first 2 numbers. If you enter more, you'll need to process coords[2] and coords[3] .. etc.

It might be even nicer to ask for one set at a time in a loop.

Steven Parker dosent working, still same error.

https://w.trhou.se/xus4m7c9pe

Steven Parker i entered more than one point and it didn’t crashed how you can explain it?

can i gjve an example with the for loop? u mean : for(int i=0; i< coords.Length(); i++) { int x= int .Parse(coords[i]); int y= int.Parse(coords[i]); } is it what u meant?

Steven Parker
Steven Parker
220,415 Points

The coordinates are in pairs, and Length is a property not a method, so:

for (int i=0; i<coords.Length; i+=2) {  // 2 at a time
  int x = int.Parse(coords[i]);
  int y = int.Parse(coords[i+1]);
}

My other suggestion was to ask for one pair at a time, but that would be a bit more work.

Steven Parker

its supposed to be like this:

       //we create an array of Towers and pass in 3 Tower objects which needs a MapLocation object.
      Console.WriteLine("Welcome to the tower defense game :], Where would u like to place your towers?");
       Console.WriteLine("Enter the X,Y coordinatyes (0-7) (0-4): ");

       var entryXY = Console.ReadLine();
       var coords = entryXY.Split(',');

        for (int i=0; i<coords.Length; i+=2)
        {  // 2 at a time
          int x = int.Parse(coords[i]);
          int y = int.Parse(coords[i+1]);
          MapLocation towerLocation = new MapLocation(x, y, map);
          Tower tower = new Tower(towerLocation);
          Level level1 = new Level(invaders);
          level1.Towers = new Tower[]{tower};
        }      

it supoosed to be like this?, it should be in the for loop? because if so i will create a new Tower object each time. it dosen't run current snap: https://w.trhou.se/6jvbusrl9n

Steven Parker
Steven Parker
220,415 Points

You still need to put all the towers into the array. So if you were going to have 3 towers:

        Level level1 = new Level(invaders);     // create level before loop
        level1.Towers = new Tower[3];           // leave space for 3 towers

        for (int i=0; i<coords.Length; i+=2) {  // 2 at a time
          int x = int.Parse(coords[i]);
          int y = int.Parse(coords[i+1]);
          MapLocation towerLocation = new MapLocation(x, y, map);
          Tower tower = new Tower(towerLocation);
          level1.Towers[i/2] = tower;           // save this tower
        }

Steven Parker why u divide the i by 2(i/2)? and in the for loop why i add 2 to the i every time?

thanks for the answer

Steven Parker
Steven Parker
220,415 Points

Based on your earlier questions, it looked like you were expecting to get all the tower coordinates at once, with commas in between, like "2,1,3,2,4,3". So having the loop increment by two will handle a pair of coordinates (not just one) in each pass.

Then dividing by two gives you each individual "Towers" index.

Steven Parker another question i have is why we add to the y i+1 every time? it’s because we increment in the for loop the i by 2 and then , first we parse the x coordinate which is i, and to get the y coordinate i need to add 1 because it’s the second i? it’s kinda hard to understand it with words can u tell me if my example is correct? : if let’s say my coordinates are (0,3) (2,1) and (4,3) , i parse the the first coordinated , i have x and y and map, i create a map location, then in the last line i divide the Towes by two because i need to get get 0,3 which this coordinate is a tower at index 0?

i hope u understand my questions

Steven Parker
Steven Parker
220,415 Points

That's right, the y index is always 1 more than the x, and the Towers index is always half of the x index. This table may help make it clear:

coords[] for x coords[] for y Towers[]
0 1 0
2 3 1
4 5 2