Complete.Org: Mailing Lists: Archives: freeciv-dev: December 1999:
[Freeciv-Dev] Re: Using tax rates
Home

[Freeciv-Dev] Re: Using tax rates

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: Using tax rates
From: Jeff Mallatt <jjm@xxxxxxxxxxxx>
Date: Tue, 14 Dec 1999 10:32:14 -0500

At 1999/12/13 10:17 , you wrote:
>I've been working on extending Xconq to handle Civ-type games, and
>have some good luck building on work by Hans Ronne from a while ago.
>One of things I've had to do was work out the trade -> tax/lux/science
>conversion, the problem being how to "fairly" divide up small amounts
>by percentage.  My first attempt at this didn't work very well, so I
>cheated :-) and looked at freeciv sources, and found a really
>interesting algorithm in cityturn.c:set_tax_income.  It seems to work,
>but there is no explanation of how/why, and I must confess that it has
>me stumped.
>
>Is there some kind soul out there who understands freeciv's trade
>conversion algorithm and can explain it?  Thanks!

I'll try...

Below is a slightly modified and commented version.

The algorithm of interest is the while loop.  We want two things: 1. the
sum of the three tax/sci/lux totals to equal the available trade
production; 2. the allocations to the tax/sci/lux totals to be in the same
ratio as their "percentages", as set by the player.

The first is accomplished simply by decrementing trade_to_dist once for
each increment of any tax/sci/lux total, and stopping when there is nothing
more to distribute.  (The while loop just keeps going until there is no
more trade to be distributed (trade_to_dist == 0).  The three if's at the
end of the loop also check to make sure that there is remaining trade to
distribute, before doing so.)

The second is done by using the three tax/sci/lux accumulators.  Each time
through the loop, each accumulator is incremented by its "percentage", as
set by the player.  Whenever an accumulator gets to or beyond 100%, a point
is added to the corresponding total, and the amount of trade to be
distributed is decremented.  (Note that any number (from zero through all
three) of the totals may be incremented in a single pass through the while
loop.)  Also, when an accumulator reaches 100%, we subtract 100 from it to
"reset" it (subtracting 100, rather than setting it to 0, retains any
remainder above 100).

I put some printf's in the code to generate the following.  The first
column is the trade to distribute, the next three are the accumulators and
the last three are the totals.

Tax=40% Sci=50% Lux=10%
---------------------------------------
TTD=12 Ta=0  Sa=0  La=0  Tt=0 St=0 Lt=0
TTD=12 Ta=40 Sa=50 La=10 Tt=0 St=0 Lt=0
TTD=11 Ta=80 Sa=0  La=20 Tt=0 St=1 Lt=0
TTD=10 Ta=20 Sa=50 La=30 Tt=1 St=1 Lt=0
TTD=9  Ta=60 Sa=0  La=40 Tt=1 St=2 Lt=0
TTD=8  Ta=0  Sa=50 La=50 Tt=2 St=2 Lt=0
TTD=7  Ta=40 Sa=0  La=60 Tt=2 St=3 Lt=0
TTD=7  Ta=80 Sa=50 La=70 Tt=2 St=3 Lt=0
TTD=5  Ta=20 Sa=0  La=80 Tt=3 St=4 Lt=0
TTD=5  Ta=60 Sa=50 La=90 Tt=3 St=4 Lt=0
TTD=2  Ta=0  Sa=0  La=0  Tt=4 St=5 Lt=1
TTD=2  Ta=40 Sa=50 La=10 Tt=4 St=5 Lt=1
TTD=1  Ta=80 Sa=0  La=20 Tt=4 St=6 Lt=1
TTD=0  Ta=20 Sa=50 La=30 Tt=5 St=6 Lt=1

Well, I hope this makes things more clear (or, at least not *less* clear :).

static void set_tax_income(struct city *pcity)
{
  int sci, tax, lux;
  int trade_to_dist;

  /* init totals to zero */
  pcity->science_total = 0;
  pcity->luxury_total = 0;
  pcity->tax_total = 0;

  /* set accumulators to zero */
  sci = tax = lux = 0;
  /* loop, distributing available trade production until no more... */
  trade_to_dist = pcity->trade_prod;
  while (trade_to_dist) {
    /* add to each accumulator its percentage (if anarchy, only lux) */
    if( get_gov_pcity(pcity)->index != game.government_when_anarchy ) {
      tax += (100 -
              game.players[pcity->owner].economic.science -
              game.players[pcity->owner].economic.luxury);
      sci += game.players[pcity->owner].economic.science;
      lux += game.players[pcity->owner].economic.luxury;
    } else {/* ANARCHY */
      lux+= 100;
    }
    /* for each accumulator: if it has reached 100%, reset the
       accumulator (by '-= 100', because it may be greater than 100),
       add one to the corresponding total, and subtract one from the
       available trade production. */
    if (tax >= 100 && trade_to_dist) {
      tax -= 100;
      pcity->tax_total++;
      trade_to_dist--;
    }
    if (sci >= 100 && trade_to_dist) {
      sci -= 100;
      pcity->science_total++;
      trade_to_dist--;
    }
    if (lux >= 100 && trade_to_dist) {
      lux -= 100;
      pcity->luxury_total++;
      trade_to_dist--;
    }
  }

  /* add the effects of specialists */
  pcity->luxury_total+=(pcity->ppl_elvis*2); 
  pcity->science_total+=(pcity->ppl_scientist*3);
  pcity->tax_total+=(pcity->ppl_taxman*3);          
}

jjm


[Prev in Thread] Current Thread [Next in Thread]