• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help me plan my program structure?  RSS feed

 
Pete Givens
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy,

For my first attempt at writing a program that consists of more than one class, I am trying to build a Clash of Clans troop calculator. It will allow the user to configure an army composition and return the cost to train, the total damage per second, and the total training time. Cost and damage will vary based on the levels of each type of troop. Total troop capacity will depend on the number and level of the available army camps.

www.clashingtools.com is pretty similar to what I'm going for.

Eventually it will need a GUI, but I'm just trying to plan out the components right now. I started by writing a masterclass called Troop, and subclasses for each type of troop.

Troop class:



An example subclass:


I made each type of troop its own class because 1) the setElixirCost(), setDamagePerSecond(), and setHitPoints() methods will all use different values for each different troop type and 2) I thought building an Army of one of each object would be the easiest way. If there is a more efficient or better way to handle this, please let me know.

Now I'm trying to figure out the best way to build the Army class. It will basically just be a collection of Troop objects, with a few methods to return the total training time, total elixir cost, total hitpoints, and total damage per second. Should it be its own class? I thought about making it just an array of Troops, but it needs to have its own field for max housing space so the client can warn the user to stop adding troops when all army camps are full. Confused on where to go from here. Thanks in advance for any advice!
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

You are going about it the right way, writing the app before you draw the GUI. Only a few things to query which I can see at the moment.
Why is TRAINING_TIME static? Where do you assign it a value (otherwise it will be 0)? Do you want it as a constant? If so, it should be static final, and must have a value assigned, preferably where it is declared. Thet technique of trying to set static members of a class from methods in a subclass is doomed to failure. The values are bound statically at compile‑time and you may change the wrong values if you use an overridden method, whose actual type is chosen dynamically at runtime.
Why are you using set methods to alter the hits? Why don't you have a sufferHit method and recoverFromHit?
I am not sure about the multiple switch statements. There must be a better way to do that. Maybe an array of Damage objects, encapsulating all those values. Maybe a Map<Integer, Damages>. Maybe an enumerated type with LEVEL_1, LEVEL_2 etc in. Remember you can get the values of an enumerated type as an array with its values() method. To get the levels and indices the same in an array, create a dummy LEVEL_0 object to occupy the first position, and similarly if you use an array directly you would need Values(0, 0, 0) to occupy the level 0 position.
 
Pete Givens
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Welcome to the Ranch

Thanks Campbell!

Why is TRAINING_TIME static? Where do you assign it a value (otherwise it will be 0)? Do you want it as a constant? If so, it should be static final, and must have a value assigned, preferably where it is declared.

TRAINING_TIME and HOUSING_SPACE are assigned in the setTrainingTime() and setHousing() methods which are called in each subclass's constructors. I don't know why I made them static. I think I wrote them as final and then realized that I wouldn't be able to set them for each subclass. My thinking was that, unlike the damage per second, training cost, and total hitpoints, the amount of time that it takes to train a troop and the housing space they take up does not change depending on their level. So when I instantiate an object of type Barbarian, I can set their training time at 20 seconds and their housing space at one. No matter what level barbarian I have, these attributes will not change. But training times and housing space do vary for each subclass of Troop, so they can't be set in the main Troop class. I guess they just need to be normal private ints?

Why are you using set methods to alter the hits? Why don't you have a sufferHit method and recoverFromHit?

The setHitPoints() method simply assigns how many total hitpoints a troop can take, depending on their level. So if one level 4 barbarian can take 78 hitpoints, and my army is comprised of 100 barbarians, the total hitpoints of my army should be returned as 7800. The application won't deal with actually troops actually giving and receiving damage.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rule of thumb, correct in about 90% of cases:-
If you didn't know why something is static, then it shouldn't be.
Is TRAINING_COST going to be the same for all objects of the class? Then it might well be static. Does it ever change? If so, then it should be written in mixedCase without underscores. UPPER_CASE_WITH_UNDERSCORES is reserved for constants. If you want a training cost field per class, you must write it in each class as a field. Only allow access via methods; make sure all those fields have private access.
If you have a static field, it may change its value if it is set via the constructor. Initialise it when you declare it. private static int pocketCount = 3;
If you have something which never changes, that is a constant. Constants are usually static because they only have one value irrespective of how many objects there are:
public static final int BOILING_WATER = 100;
private static final int TRAINING_DAYS = 28;
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!