Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

C#

Eric Smailys
Eric Smailys
1,667 Points

Trying to test my Tower Location input, and can't figure out how to retrieve the coordinates of my Tower.

After coding the user input for where to place the towers (I hardcoded 2 towers in the level) in Game.cs, I wanted to just print out the coordinates of the towers to make sure I was storing the data correctly, but now I'm completely stuck trying to figure out how to get that info back.

I've tried a few different things, and I think what I need to do is actually define a method in Tower.cs that returns it's location, then call that Method in Game.cs after having the user put in the tower coordinates. But the only time I was able to successfully compile, I just got output like "Tower 1 is at TreehouseDefense.MapLocation".

Here's the body of my Tower class, followed by the body of Game.cs:

Tower.cs

namespace TreehouseDefense { class Tower { private const int _range = 1; private const int _power = 1; private readonly MapLocation _location;

public Tower(MapLocation location)
{
  _location = location;    
}
  public void FireOnInvaders(Invader[] invaders)
  {        
    foreach(Invader invader in invaders)
    {
      if(invader.IsActive && _location.InRangeOf(invader.Location,_range))
      {
        invader.DecreaseHealth(_power);
        break;
      }
    }
  }

public MapLocation TowerLoc()
{
  return _location;
}

}

}

Game.cs

using System;

namespace TreehouseDefense { class Game { public static void Main() { Map map = new Map(8,5); try { 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) } );

        Invader[] invaders = 
        {
          new Invader(path),
          new Invader(path),
          new Invader(path),
          new Invader(path)
        };

        Level level = new Level(invaders);

        Console.WriteLine("Welcome to Level 1 - defend your Tower!");
        Console.WriteLine("You will place two towers in a map 8 spaces long and 5 spaces tall");
        Console.WriteLine("Towers cannot be placed on the path, which runs down the middle length-wise");

        int _towerCount = 1;
        level.Towers = new Tower[2];
        while(_towerCount <= 2)
        {
          Console.Write("Enter the X Coordinate for Tower #"+ _towerCount + ": ");
          string _towerX = Console.ReadLine();
          int x = Int32.Parse(_towerX);
          Console.Write("Enter the Y Coordinate for Tower #"+ _towerCount + ": ");
          string _towerY = Console.ReadLine();
          int y = Int32.Parse(_towerY);
          try
          {
            MapLocation towerLoc = new MapLocation(x,y,map);
            Tower tower = new Tower(towerLoc);
            level.Towers[_towerCount - 1] = tower;
          }
          catch(OutOfBoundsException ex)
          {
            Console.WriteLine(ex.Message);
            continue;
          }
          _towerCount++;
        }

        Console.WriteLine("Tower 1 is at " + level.Towers[0].TowerLoc());
        Console.WriteLine("Tower 2 is at " + level.Towers[1].TowerLoc());

      }
      catch(TreehouseDefenseException)
      {
        Console.WriteLine("Unhandled TreehouseDefenseException");
      }
      catch(Exception ex)
      {
        Console.WriteLine("Unhandled Exception" + ex);
      }
    }
}

}

Eric Smailys
Eric Smailys
1,667 Points

Okay I also have no idea what's going on with the formatting of my code examples above, and I can't seem to make it any better.

Related, I decided to see what happened if I printed out the result of the GetLocationAt method from Path.cs, which as far as I can tell is written exactly as the videos demonstrated:

public MapLocation GetLocationAt(int pathStep)
{
  return (pathStep < _path.Length) ? _path[pathStep] : null;
}

But when I instatiate the path in Game.cs, again exactly as per the videos, and do this:

Console.WriteLine(path.GetLocationAt(3));

I just get this output:

TreehouseDefense.MapLocation

I'm guessing it's because the MapLocation class as defined is not a printable value (it's two coordinates and the map itself), but nothing I've tried to limit the output to just the X and Y variables defined in the MapLocation has compiled successfully.

1 Answer

Samuel Ferree
Samuel Ferree
31,722 Points

Your code is technically working. The function that you defined is in fact returning the Tower's location.

However, You aren't seeing the output you expect, because a tower's location is an object that is an instance of class MapLocation.

When C# is told to append an object to a string, it implicitly calls that objects ToString() method. Since MapLocation doesn't have a ToString() method defined, it calls the default Object ToString() method, which simply returns the name of the class.

You have two choices, you can override the ToString() method of MapLocation, so that it returns text that shows the coordinates of the map location. Something like this:

public class MapLocation
{
  public override string ToString()
  {
    return this.X + ", " + this.Y
  }
}

Or you can, using the properties of the MapLocation object, append the actual x and y coordinates of the location.

TL;DR: You're adding MapLocation's to the end of Strings. only Strings can be added to Strings. You didn't tell C# how to convert a MapLocation to a String, so it's just adding the name of the class, which happens to be "TreehouseDefense.MapLocation"