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

Samuel Savaria
4,809 PointsGeometry calculator
I did the Geometry Calculator from C# Objects. I am mostly looking for feedback on how to keep my code dry, and how to make it more readable.
2 Answers

Allan Clark
10,810 PointsNow I am not sure what the instructions for the calculator are specifically but i have a few pointers just based on what you have.
First, try to keep you Main() method to a minimum. if there is more than trivial logic it should be in its own method at the very least (better if its in another class I dont like having other methods on the Main.cs to keep the whole file as minimal as possible).
Secondly, this is a very procedural approach, the classes you have are static helper classes that handle the computations and the main method handles the interaction with the user. Try to think about the objects involved, namely triangles, circles, and rectangles (being squares are rectangles you can use some inheritance magic here). Try creating classes that model objects using the properties as the dimensions and the methods to do all the computations.
Lastly, 'while(true)' is valid but bad form, you will be able to find better ways to control the logic flow (ones that don't have inherent risks of an infinite loop : ) ). Console.ReadLine() should wait for input anyway so they may not be needed.

Allan Clark
10,810 PointsOne class per file is pretty standard. But the only file you have with multiple classes is the Exception.cs. This would be better in two separate files (BattleshipException.cs and OutOfBoundsException.cs) with those files inside a folder called 'Exceptions'. Like i said it is ok here on this small app but when you get to more complex applications you could have a ton of custom exceptions and if they were all on one file and you could have to scroll through hundreds of lines of code to find what you are looking for. This is especially important when you are working with a team and other people will be developing on the same project.
The data model being a little lacking is causing you to have to resort to a procedural thinking for some of the concepts. (for example about half of MapLocation should be in a new Map class) Yes a .cs Class file will generally have a constructor, Variables (for object state), and Methods (for object behavior). 'Object behavior' is the key here. Methods that are just related to the object is too broad, methods represent what an object does, or has done to it.
A good example of this is the Ship class and the Fire() method. While yes Fire() is related to a ship object, but if you think about the physical battleship board game, the ship really isn't the one doing the firing action (the player does).
And take all this just as pointers, it will become more clear as you get more experience with it and see more existing code.
Allan Clark
10,810 PointsAllan Clark
10,810 PointsOh and if you want bonus style points to try using TryParse() methods instead of plain ole Parse().
Samuel Savaria
4,809 PointsSamuel Savaria
4,809 PointsIn my next post I was about to ask if, ideally, all user inputs should be in main and the actual coding in classes. That answers my question perfectly. One thing tho, can you use System.Console.ReadLine() in a static class? The majority of my code in pretty much every of my projects were taking the input of the user, and that's prevented me from keeping my code dry. If I could assign the value of X to the result of getNumber, I will save a ridiculous amount of space.
Thanks for the .TryParse method, will certainly try it out!
Now, the other big question. I mostly used while(true) in user inputs and for loops, because it allows me to repeat the loop without passing an invalid input or to run the same i value again. Do you know how I can get around that?
Thanks a lot, my objective for after the C# Intermediate course was to keep my code as dry as possible. This is bringing me a lot closer to it.
Allan Clark
10,810 PointsAllan Clark
10,810 PointsYes you can certainly use System.Console.ReadLine() in a static class, as it is a static method.
I threw together a 'GeometryCalculator' class to give more of an OO approach. Forewarning there may be some more advanced stuff than where you are in the Treehouse courses, feel free to throw out any questions you have about it. And by no means am I saying this is the best or most efficient way to do it but this will show a more OO way of thinking about the solution.
The idea of this class is to encapsulate the functionality of the calculator itself. This class assumes there are Triangle, Cirlcle, Rectangle, and Square classes that inherit from a base Shape class.
With this new class you're Main method will go down to 2 lines.
Allan Clark
10,810 PointsAllan Clark
10,810 PointsSamuel Savaria
4,809 PointsSamuel Savaria
4,809 PointsI don't think I had any problem with OOP, I was simply trying to solidify what was being passed over quickly in the course. I understand that ideally, the main() would only call other classes and never run any of the code itself. But a lot was unclear after the course and I wanted to make sure I understood and knew how to use everything before moving on. My objective for next course is to keep code learned in the first 2 courses 100% dry.
Allan Clark
10,810 PointsAllan Clark
10,810 PointsWell, for an OO approach your code is conspicuously missing instantiating those objects using the 'new' keyword, and relies heavily on Static methods on Static classes (which more procedural than OO). If you have questions about topics that may be unclear, this forum is great for asking specific questions. If you post code and ask for improvements you may get an answer back that does not answer your specific questions and may lead to more confusion.
I am glad I was able to clear up a few things for you! Please post any other questions or issues you run into as you move through the course.
Samuel Savaria
4,809 PointsSamuel Savaria
4,809 Pointshttps://w.trhou.se/httav2ykva
This is my "big" project that I hope uses a more OO approach. It's very, very, very messy, maybe 80%+ of the code is in the Main() method. I was planning on drying it up a bit but I injured my arm recently and didn't feel like having to write too much code, so I just wrote on top of the existing mess :P
Also, ignore that pointless AI class with only a RNG, I started to code it before my injury and had trouble calling in the ships array from the Main(), then I just didn't care enough to look it up. Bad coding practice, but I went from 5h+ of coding per day to 20-30 minutes, so I didn't feel like trying owt fancy.
Allan Clark
10,810 PointsAllan Clark
10,810 PointsI am sorry to hear that and wish you a speedy recovery! Life > code haha
Anyway as for the code, this is definitely heading in the right direction. The Objects you have are modeled well and encapsulate the functionality pretty well. Couple pointers:
I would start with dealing with the structure fist. Create a Program.cs that contains only the Program class and Main() method. Look at what is in your Main() method as a large group of properties and methods that need to be sorted into categories.
Have your Game.cs/class as the engine of the game. It should have stuff like Players (also another object id suggest), a Map (same thing here), etc.
Samuel Savaria
4,809 PointsSamuel Savaria
4,809 PointsI will apply all of your suggestions on my next project for sure :) I'd like to add that isTouching was originally a bool, but because ships couldn't be on top of each other I applied lazy design and changed it to an int.
Also, you say there should be 1 class per file, but is it a personal preference? In my opinion, it makes a lot more sense to have the class constructor (Ship, MapLocation) and then any methods related to it (Fire, GetLocation, OnMap, etc..). That way, files act as a sort of category and makes searching for methods a lot easier.