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# C# Objects Loops and Final Touches While Loops

Possible Solution for Tower on Path check?

Hi,

I spent a good 2 hours trying to come up with the "best" answer. I'll start with what I did and then what I wanted but couldn't figure out how to do it.

What I did: 1) Went to Path.cs and created the following method:

        public bool OnPath(MapLocation location) 
        {
            for (int i = 0; i < _path.Length; i++) 
            {
                 if (location.X == _path[i].X && location.Y == _path[i].Y)
                 {
                    return true;
                 }
            }
            return false;
        }

2) Went to Exceptions.cs and added the following Exception class:

    class InvalidTowerException : TreehouseDefenseException
    {
        public InvalidTowerException()
        {
        }

        public InvalidTowerException(string message) : base(message)
        {
        }
    }

3) Went to Tower.cs and constructed my Tower as follows:

namespace TreehouseDefense
{
    class Tower
    {
        private readonly MapLocation _location;

        public Tower(MapLocation location, Path path)
        {
            if (path.OnPath(location))
            {
                throw new InvalidTowerException("Towers cannot be place on the path!");
            }
            else
            {
                _location = location;
            } 

        }
    }
}

4)In Game.cs I added in a new Tower object and called added a catch item:

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)
                    }
                );
                Tower tower = new Tower(new MapLocation(6,2,map), path);
            }
            catch(InvalidTowerException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch(OutOfBoundsException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch(TreehouseDefenseException)
            {
                Console.WriteLine("Unhandled TreehouseDefenseException");
            }
            catch(Exception ex)
            {
                Console.WriteLine("Unhandled Exception: " + ex);
            }
        }
    }
}

This code successfully alerts me when a Tower was tried to be created on MapLocation on the path.

But, as I stated above, I have two questions.

1)Why can I not just compare MapLocation objects? I did this originally. The code compiled, but it would not throw the exception like I wanted it to. I figure, if the path is an array of MapLocation objects, I should be able to just compare each object in that array to my Tower's MapLocation field since they are the same type. If they are the same, then OnPath equals True.

        public bool OnPath(MapLocation location) 
        {
            for (int i = 0; i < _path.Length; i++) 
            {
                 if (location == _path[i])
                 {
                    return true;
                 }
            }
            return false;
        }

2)My mind can't escape that having path as an argument in the Tower constructor is not necessary. But I can't take my mind any further than that. Thoughts?

Thanks

1 Answer

Steven Parker
Steven Parker
229,732 Points

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types (such as the "MapLocation" object), == returns true if its two operands refer to the same object. So a default comparison of two different object that have the same values will return false. It's possible to override operators in C#, but that's not covered in this course.

If you want the Tower to handle the validity testing for the location, it needs access to the path. Passing the path to the constructor is one way to do this. Another way would be to have the path be globally accessible, then you could still use it in the constructor without needing to pass it as an argument.