Help me design my movement system properly

Started by
10 comments, last by King of Men 16 years, 10 months ago
My current game has two kinds of locations that can be occupied by units: Provinces, and ProvinceBorders. (So you can be in Kansas, Oz, or the Kansas-Oz border.) Now, when a unit is ordered from one place to another, it needs to know what its next step is. (Going from Kansas to Oz, your first step is the border.) It seems to me that the unit should not be keeping track of what kind of location it's in. Rather it should simply see a Location::nextStep(Location* goal) method, for my provinces and borders to overload. So, is there an elegant way I can do this without casting? My first solution is to put three virtual methods in the Location class:

  virtual Location* nextStop (Location* goal) = 0;
  virtual Location* nextStop (Province* goal) = 0;
  virtual Location* nextStop (ProvinceBorder* goal) = 0;
which takes care of the immediate problem. But clearly this isn't very extensible if I need to add another subclass of Location. Better solutions?
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
Advertisement
Why do you need different methods for provinces and borders? This isn't clear to me. I'd just model the map as a graph, with provinces and borders as vertices and border-province connections as edges and then run the whole thing through a shortest-path algorithm like the Floyd-Warshall algorithm.. Then you'd just need the "Location* nextStep(Location*)" method to spit out the precalculated solution.
Alternately you can make some base class BaseLocation, that Location, Province, and ProvinceBorder all inherit from, and then pass that as the argument. Then you only need one method signature:

virtual Location* nextStop (BaseLocation* goal) = 0;
-david
So what you have is a map of nodes, where nodes of type A only connect to nodes of type B, which in turn connect to exactly two nodes of type A?

Is there a significant advantage to having "NodeA and NodeB" over just having "Node.type = A and Node.type = B"?

What, exactly is the functional difference? Is there a difference in logic, or a difference in methods? What is common between them?
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by erissian
So what you have is a map of nodes, where nodes of type A only connect to nodes of type B, which in turn connect to exactly two nodes of type A?

Is there a significant advantage to having "NodeA and NodeB" over just having "Node.type = A and Node.type = B"?

What, exactly is the functional difference? Is there a difference in logic, or a difference in methods? What is common between them?


That is precisely the kind of graph I have, yes. The distinction is imposed by the logic of my economic system; there is no particular advantage for the movement part, in fact it causes problems! But I'm really quite happy with the way my economic system works, so the movement system for units will just have to accommodate that.

Quote:Alternately you can make some base class BaseLocation, that Location, Province, and ProvinceBorder all inherit from, and then pass that as the argument. Then you only need one method signature:

virtual Location* nextStop (BaseLocation* goal) = 0;


I don't understand how this is different from the solution I already have, except that it introduces an additional and un-necessary layer of abstraction. To be clear, Province and ProvinceBorder both inherit from Location.
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
So if it is designed around your economic system, then how does you economic system make use of it?
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Province store production units; ProvinceBorders store the difficulty of getting from one Province to another, the number of transport units assigned to that route, the infrastructure built, and a couple of other things.
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
So non-economic units aren't affected by difficulty in crossing borders, infrastructure, etc.?
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Not in the same way. Which, indeed, is why I need my two Location subclasses to handle things differently. :)

Edit: I guess what you're saying is that, since there is a genuine difference in the interface, the military units do in fact need to know about the difference, so I should expose the Province and ProvinceBorder classes directly?
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.
The way I would do it, just because of the way I plan things, is to have one node type, which has flags indicating any special properties, and whose information is exposed to all units. That way, if I decide that some information may be related to two different kinds of units, I don't have to have copies of variables, or adjust the superclass beyond its scope. Also, if I chose to make a third unit type which required the information from both sets, it would add unnecessary complexity to the problem.

In other words, when I design things, I don't just think of "How am I going to use this?" but I try also to think of "How am I going the change this later?"

Ultimately, you have to do what makes sense to you, but I would just make it a single, very informative class, which you can exploit however you need to.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)

This topic is closed to new replies.

Advertisement