Hi,
I still haven't finished the Event Notifier, have been also working on a Business Plan and associated stuff. Will get some done tonight though.
Probably more of getting ahead of yourself, if you don't mind me saying so :+) It's like you want to go car racing: but the chassis, engine and transmission are all separate parts, despite that, you are trying to get the air-conditioning, telemetry, and brake bias working.
I hope you view all of the following as constructive criticism:
Maybe time to reiterate my philosophy on this. Einstein once said:
"Things should be simple, simple as possible, but no simpler " . Often I find that people trip over on the last part, but here I think we need to start at the simple end.
So start with something very simple, get that working, then move on to more complexity after that.
The reason for the simplicity is twofold: You had a 25KLOC with lots of complexity, and which had unworkable design and code issues; It's easier to start simple and have it working and easy to extend, rather than start complex and finish up with it not working. Even if we had a complete design with 100 classes say, I would still get small parts of it working first.
With your code, I have said a few times already that the new code won't look anything like the original code, and I don't see it as being worthwhile to change the original code. This is probably hard to accept: you probably spent weeks doing it, now I am saying to tear it up and put it in the fire; or keep it for comparison purposes, old to new, to see just how much difference there is. So I am trying to steer away from criticising or changing the existing code, apart from ideas of doing things in a better way for the new code. Just on that: I reiterate the names you have IMO are terrible. Piece implies an individual thing, I would have called it
Squad
. What is Hex? You mentioned going from HexA to HexB, do you have hexagonal tiles on a map? To me that immediately sounds suspect / over complicated. Anyway those issues are in the future. Faction (whatever that is) is another thing to deal with later.
My idea at this stage is to implement the Event Notifier with everything it needs, and use it to do some very simple Combat: One Soldier fires at 1 Enemy until it dies. Then it should be easy to have 2 way combat, perhaps implement Armour, then combat with multiple targets, then more detailed Command events.
So to that end, in my mind the publishing of an Event, would have Sender, Receiver and the Event itself as arguments. The event itself can have information inside it, like the amount of damage the attack represents, or much later in the project things like Location.
I hope you realise that the Event class is an abstract base class, with the polymorphism one sends a pointer to a derived class to the function or container.
My idea was to have the Actors to have a Combat object, which would be both a Publisher and Subscriber to Combat type events. It owns the Weapon, Armour and Health objects for the Actor. It would also Register itself as being a participant in the Battle, and publish an event when it dies. I am also going to have a Command object, which commands the Soldiers (or groups of them). The Command object subscribes to Registration events, so it can assign an Enemy or Enemies to a Soldier. It can publish events to initiate the Battle. The Command can also publish movement events.
So, to get you thinking about this: What are the classes you are going to have for the Event Notifier, The events themselves and anything else needed to get it working? Hint look at the UML diagrams and the Java code in the documentation.
Thomas1965, who we have to thank for the unit testing and logging suggestion. |
Ok, awesome :+). It is good to know what everyone is suggesting, just so we don't become at cross purposes to each other :+) AFAIK the unit testing, logging and exceptions shouldn't be too hard.
On the data front have two PODs (one shown) here they are: |
While trying not to go directly against what
dhayden is saying (it might be your interpretation of what he said), I see that information as statistics. Even though it is to do with the Soldier, IMO it should not be directly in the Soldier class. Like everything else, it could exist in a separate
Statistics
class/object which a Soldier can own a pointer to. The Rank could still just be a string or enum, but the value of that is determined by the statistics. I am not sure you fully understand that concept yet, here is a further detailed example:
Say we have a Person class. It needs to store info about names, date of birth, address, driver's license, passport, swimming club membership etcetera. Instead of those things being strings, they would all have their own class and the Person stores pointers to those objects. Abilities to drive or swim would also be in separate objects which the Person would own pointers to.
It might be a surprise, but there are often ways of breaking things down to smaller classes. For example,
Scott Meyers (Author of Effective C++ series) not only had a
Date
class, but he had a class for
each month ! He reasoning was to make the class easy to use properly and hard to use improperly. The ambiguity with dates is the varying day/month , month/day formats around the world.
The thing is, one has to think in object oriented terms. This sounds obvious for OOP, but it is a completely different paradigm and mindset to procedural programming (PP) like one would do in the C language say. PP tends to be data centric: data in, some process, data out. So this is very different to OOP, where objects model the real world, or relationships between abstract concepts.