Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Logic Assistance Required  (Read 942 times)

Iituem

  • Bay Watcher
    • View Profile
Logic Assistance Required
« on: August 22, 2015, 02:00:41 pm »

Let's say I have 21 villages, 20 of which produce 25 grain and 1 of which (a mountain village) demands 500 grain.

The four main grain villages are A, B, C and D, who are linked together in a trade route that goes A-B-C-D-E.

A, B, C and D each have four attached villages, which I describe as aA, aB, aC, aD, etc.  In short form, their links are as follows:

aA=aB=A=aC=aD (four villages trade-linked to A)

bA=bB=B=bC=bD

cA=aB=C=cC=cD

dA=dB=D=dC=dD

A-B-C-D-E


Each village has a 'push' of 25 grain, and village E has a 'pull' of 500, but it can only directly affect village D.

How can I transfer that 'pull' across the network of villages without having to calculate the entire trade route from top to bottom - is there a dynamic way I could do this, such that I could add or take away villages without having to redo the whole calculation from scratch?

Trying to model dynamic trade routes/trade flow for a game.
Logged
Let's Play Arcanum: Of Steamworks & Magic Obscura! - The adventures of Jack Hunt, gentleman rogue.

No slaughtering every man, woman and child we see just to teleport to the moon.

Nirur Torir

  • Bay Watcher
    • View Profile
Re: Logic Assistance Required
« Reply #1 on: August 22, 2015, 02:48:15 pm »

I assume that E can't call aA up on the telephone and say it desperately needs grain. Is it feasible to propagate "needs grain" (and/or "selling grain") tags through the network every trade cycle?

Logged

LordBucket

  • Bay Watcher
    • View Profile
Re: Logic Assistance Required
« Reply #2 on: September 05, 2015, 04:54:13 am »

How can I transfer that 'pull' across the network of villages without having to calculate the entire trade route from top to bottom - is there a dynamic way I could do this, such that I could add or take away villages without having to redo the whole calculation from scratch?

First:
1) Give each point on the network a list of adjacent points.
2) Create a temporary array to store exchanges that are "in process"

Then, every cycle:

3) Be aware that step 7 happened on the previous iteration
4) Iterate through villages, checking for matches between what adjacent village want and can give. Any time you have a match, deduct inventory from the give side and add an entry to the temp array indicating who gets what and how much.
5) After step 4 is complete, perform the changes indicted by the temp array
6) Wipe your temp array
7) Assign "how much I want" and "how much I can give" values to each point on the network based on current conditions

The temporary array prevents teleports. You (probably) don't want 1 giving to 2 giving to 3 giving to 4 giving to 5 all on the same turn, simply because you checked those locations in that order.

Note that this process allows networks that are considerably more complicated than the one you have.

Note also that this method does allow individual points to deliver to multiple recipients per iteration if they have enough to deliver. You can add a "how many deliveries have I made?"  variable if you want to limit the number of deliveries from each location per turn, for example. Simply check to see if more deliveries are allowable in step 4, then increment it every time a delivery is made, then wipe that data for all locations in step 6.

When computing "how much I can give" remember that each location probably uses the grain too. You might consider also adding a minimum threshold to keep them from giving away grain that they need. If you have 100 people in a location and they each eat 1 grain per turn, you don't want them giving away the last 100 grain and starving to death on that turn just because their neighbor wanted it and they were "capable" of delivering.

Note also that if you iterate exclusively numerically through your connections list, that will create favoritism whereby, for example, if location 1 and 2 both want grain, and location 3 is able to provide it to both of them but only has enough supply for one of the two, location 1 always gets it. You could avoid this in many ways, but for example, you could create a temporary sort by size of demand. Or by adding up the total want, and giving each a fraction of the available give corresponding to how much their want is. For example, if A wants 10 and B wants 15 and C can give 10, then A gets 10/(10+15) * 10 = 4 and B gets 15/(10+15) * 10 = 6.


Note also that this method will result in somewhat delayed propagation. If A and Z are 5 steps away on the network, it will take more than 5 turns for grain from Z to reach A, because the "I need message" will take time to get there, and no individual point knows where its deliveries eventually end up.

Alternately you could set up a LIFO structure, but the above is far simpler and probably does everything you want. You don't really care about pathing in this scenario. It doesn't matter if A gets its grain from D or E, only that the grain propagates through the network and ends up where it's wanted.
« Last Edit: September 05, 2015, 05:29:54 am by LordBucket »
Logged