budget: Fix for ship, plane, land unit building abroad

The budget command simulates an update by running selected parts of
the update code.  It skips parts that depend on hidden information
such as guerrilla warfare.  For speed, it also skips parts it doesn't
need, such as distribution and foreign sectors, ships, planes and land
units.

Skipping foreign sectors is wrong when any of the player's ships,
planes or land units will be repaired in foreign sectors, because it
makes budget use old materials and work instead of new.

Skipping foreign ships, planes and land units is wrong when they
compete with the player's for materials and work.

The bug goes back to Chainsaw's option BUDGET.  See the previous
commit for more detailed historical notes.  The update test
demonstrates it in several variations.

Fix it with the sledgehammer: don't skip foreign sectors, ships,
planes and land units.  This makes budget almost twenty times slower
in my testing.  Probably tolerable on a reasonably beefy machine, but
we can do better; the next few commits will claw back most of the lost
performance.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2016-07-10 21:15:15 +02:00
parent 459dec0af0
commit 70f69640e1
8 changed files with 57 additions and 51 deletions

View file

@ -128,9 +128,7 @@ extern void prod_plane(int, int, struct bp *, int);
extern void populace(struct sctstr *, int); extern void populace(struct sctstr *, int);
extern int total_work(int, int, int, int, int, int); extern int total_work(int, int, int, int, int, int);
/* prepare.c */ /* prepare.c */
extern void prepare_sects(int); extern void prepare_sects(int, struct bp *);
extern void tax(struct sctstr *, int);
extern void bank_income(struct sctstr *, int);
extern void pay_reserve(struct natstr *, int); extern void pay_reserve(struct natstr *, int);
/* produce.c */ /* produce.c */
extern void produce(struct natstr *, struct sctstr *); extern void produce(struct natstr *, struct sctstr *);

View file

@ -35,7 +35,7 @@
#include <config.h> #include <config.h>
#include <ctype.h> #include <limits.h>
#include "commands.h" #include "commands.h"
#include "item.h" #include "item.h"
#include "optlist.h" #include "optlist.h"
@ -145,41 +145,42 @@ calc_all(void)
struct budget *budget = &nat_budget[player->cnum]; struct budget *budget = &nat_budget[player->cnum];
struct natstr *np; struct natstr *np;
struct bp *bp; struct bp *bp;
int n; int i;
struct sctstr *sp;
int etu = etu_per_update; int etu = etu_per_update;
memset(nat_budget, 0, sizeof(nat_budget)); memset(nat_budget, 0, sizeof(nat_budget));
np = getnatp(player->cnum); np = getnatp(player->cnum);
/* Take care not to disclose others going broke: */
for (i = 0; i < MAXNOC; i++)
nat_budget[i].start_money = nat_budget[i].money = INT_MAX;
budget->start_money = budget->money = np->nat_money; budget->start_money = budget->money = np->nat_money;
bp = bp_alloc(); bp = bp_alloc();
for (n = 0; NULL != (sp = getsectid(n)); n++) { prepare_sects(etu, bp);
bp_set_from_sect(bp, sp); for (i = 0; i < MAXNOC; i++) {
if (sp->sct_own == player->cnum) { prep_ships(etu, i);
sp->sct_updated = 0; prep_planes(etu, i);
tax(sp, etu); prep_lands(etu, i);
if (sp->sct_type == SCT_BANK) pay_reserve(getnatp(i), etu);
bank_income(sp, etu);
}
} }
prep_ships(etu, player->cnum);
prep_planes(etu, player->cnum);
prep_lands(etu, player->cnum);
pay_reserve(np, etu);
/* Maintain ships, planes and land units */ /* Maintain ships, planes and land units */
prod_ship(etu, player->cnum, bp, 0); for (i = 0; i < MAXNOC; i++) {
prod_plane(etu, player->cnum, bp, 0); prod_ship(etu, i, bp, 0);
prod_land(etu, player->cnum, bp, 0); prod_plane(etu, i, bp, 0);
prod_land(etu, i, bp, 0);
}
/* Produce */ /* Produce */
produce_sect(np, etu, bp); for (i = 0; i < MAXNOC; i++)
produce_sect(getnatp(i), etu, bp);
/* Build ships, planes and land units */ /* Build ships, planes and land units */
prod_ship(etu, player->cnum, bp, 1); for (i = 0; i < MAXNOC; i++) {
prod_plane(etu, player->cnum, bp, 1); prod_ship(etu, i, bp, 1);
prod_land(etu, player->cnum, bp, 1); prod_plane(etu, i, bp, 1);
prod_land(etu, i, bp, 1);
}
if (CANT_HAPPEN(np->nat_money != budget->start_money)) if (CANT_HAPPEN(np->nat_money != budget->start_money))
np->nat_money = budget->start_money; np->nat_money = budget->start_money;

View file

@ -92,7 +92,7 @@ update_main(void)
} }
logerror("preparing sectors..."); logerror("preparing sectors...");
prepare_sects(etu); prepare_sects(etu, NULL);
logerror("done preparing sectors."); logerror("done preparing sectors.");
for (i = 0; i < MAXNOC; i++) { for (i = 0; i < MAXNOC; i++) {
prep_ships(etu, i); prep_ships(etu, i);

View file

@ -44,10 +44,13 @@
#include "prototypes.h" #include "prototypes.h"
#include "update.h" #include "update.h"
static void tax(struct sctstr *, int);
static void bank_income(struct sctstr *, int);
void void
prepare_sects(int etu) prepare_sects(int etu, struct bp *bp)
{ {
struct sctstr *sp; struct sctstr *sp, scratch_sect;
int n; int n;
/* Process all the fallout. */ /* Process all the fallout. */
@ -72,6 +75,7 @@ prepare_sects(int etu)
} }
for (n = 0; NULL != (sp = getsectid(n)); n++) { for (n = 0; NULL != (sp = getsectid(n)); n++) {
bp_set_from_sect(bp, sp);
sp->sct_updated = 0; sp->sct_updated = 0;
if (sp->sct_type == SCT_WATER || sp->sct_type == SCT_SANCT) if (sp->sct_type == SCT_WATER || sp->sct_type == SCT_SANCT)
@ -85,16 +89,25 @@ prepare_sects(int etu)
if (running_test_suite) if (running_test_suite)
seed_prng(sp->sct_uid); seed_prng(sp->sct_uid);
guerrilla(sp); if (player->simulation) {
do_plague(sp, etu); /* work on a copy, which will be discarded */
populace(sp, etu); scratch_sect = *sp;
sp = &scratch_sect;
}
if (!player->simulation) {
guerrilla(sp);
do_plague(sp, etu);
populace(sp, etu);
}
tax(sp, etu); tax(sp, etu);
if (sp->sct_type == SCT_BANK) if (sp->sct_type == SCT_BANK)
bank_income(sp, etu); bank_income(sp, etu);
bp_set_from_sect(bp, sp);
} }
} }
void static void
tax(struct sctstr *sp, int etu) tax(struct sctstr *sp, int etu)
{ {
struct budget *budget = &nat_budget[sp->sct_own]; struct budget *budget = &nat_budget[sp->sct_own];
@ -120,7 +133,7 @@ tax(struct sctstr *sp, int etu)
budget->money += mil_pay; budget->money += mil_pay;
} }
void static void
bank_income(struct sctstr *sp, int etu) bank_income(struct sctstr *sp, int etu)
{ {
double income; double income;

View file

@ -252,6 +252,7 @@ produce_sect(struct natstr *np, int etu, struct bp *bp)
if (player->simulation) { if (player->simulation) {
/* work on a copy, which will be discarded */ /* work on a copy, which will be discarded */
scratch_sect = *sp; scratch_sect = *sp;
bp_to_sect(bp, &scratch_sect);
sp = &scratch_sect; sp = &scratch_sect;
} }

View file

@ -1,12 +1,5 @@
budget budget
| Note: f1#100 not actually built (plague kills off mil) | Note: f1#100 not actually built (plague kills off mil)
| BUG: missing cs#91
| BUG: mispredicts f1#75..78
| BUG: missing f1#91
| BUG: missing f1#92
| BUG: f1#100 not actually built
| BUG: missing inf#91
| BUG: missing inf#92
| TODO is it accurate? | TODO is it accurate?
neweff * ?newd#- neweff * ?newd#-
production * production *

View file

@ -1,3 +1 @@
budget budget
| BUG: missing f1#93
| BUG: missing inf#93

View file

@ -33,21 +33,21 @@
Play#1 output Play#1 1 bank 41 bars 410 Play#1 output Play#1 1 bank 41 bars 410
Play#1 output Play#1 1 refinery 2580 petrol 290 Play#1 output Play#1 1 refinery 2580 petrol 290
Play#1 output Play#1 1 enlistment center 75 mil 225 Play#1 output Play#1 1 enlistment center 75 mil 225
Play#1 output Play#1 1 Ship building 10 ships 1520 Play#1 output Play#1 1 Ship building 11 ships 1920
Play#1 output Play#1 1 Ship maintenance 32 ships 2207 Play#1 output Play#1 1 Ship maintenance 32 ships 2207
Play#1 output Play#1 1 Plane building 13 planes 1924 Play#1 output Play#1 1 Plane building 15 planes 3412
Play#1 output Play#1 1 Plane maintenance 21 planes 1244 Play#1 output Play#1 1 Plane maintenance 21 planes 1244
Play#1 output Play#1 1 Unit building 6 units 2300 Play#1 output Play#1 1 Unit building 8 units 2900
Play#1 output Play#1 1 Unit maintenance 16 units 510 Play#1 output Play#1 1 Unit maintenance 16 units 510
Play#1 output Play#1 1 Sector building 40 sectors 774 Play#1 output Play#1 1 Sector building 40 sectors 774
Play#1 output Play#1 1 Sector maintenance 2 sectors 120 Play#1 output Play#1 1 Sector maintenance 2 sectors 120
Play#1 output Play#1 1 Military payroll 1164 mil, 0 res 5820 Play#1 output Play#1 1 Military payroll 1164 mil, 0 res 5820
Play#1 output Play#1 1 Total expenses.....................................................25249 Play#1 output Play#1 1 Total expenses.....................................................27737
Play#1 output Play#1 1 Income from taxes 26911 civs, 9007 uws +12627 Play#1 output Play#1 1 Income from taxes 26911 civs, 9007 uws +12627
Play#1 output Play#1 1 Total income......................................................+12627 Play#1 output Play#1 1 Total income......................................................+12627
Play#1 output Play#1 1 Balance forward 25000 Play#1 output Play#1 1 Balance forward 25000
Play#1 output Play#1 1 Estimated delta -12622 Play#1 output Play#1 1 Estimated delta -15110
Play#1 output Play#1 1 Estimated new treasury.............................................12378 Play#1 output Play#1 1 Estimated new treasury..............................................9890
Play#1 output Play#1 6 0 99 Play#1 output Play#1 6 0 99
Play#1 input neweff * ?newd#- Play#1 input neweff * ?newd#-
Play#1 command neweff Play#1 command neweff
@ -389,16 +389,18 @@
Play#6 command budget Play#6 command budget
Play#6 output Play#6 1 Sector Type Production Cost Play#6 output Play#6 1 Sector Type Production Cost
Play#6 output Play#6 1 Ship maintenance 1 ship 540 Play#6 output Play#6 1 Ship maintenance 1 ship 540
Play#6 output Play#6 1 Plane building 1 plane 120
Play#6 output Play#6 1 Plane maintenance 3 planes 147 Play#6 output Play#6 1 Plane maintenance 3 planes 147
Play#6 output Play#6 1 Unit building 1 unit 150
Play#6 output Play#6 1 Unit maintenance 3 units 90 Play#6 output Play#6 1 Unit maintenance 3 units 90
Play#6 output Play#6 1 Sector maintenance 1 sector 60 Play#6 output Play#6 1 Sector maintenance 1 sector 60
Play#6 output Play#6 1 Military payroll 168 mil, 0 res 840 Play#6 output Play#6 1 Military payroll 168 mil, 0 res 840
Play#6 output Play#6 1 Total expenses......................................................1675 Play#6 output Play#6 1 Total expenses......................................................1945
Play#6 output Play#6 1 Income from taxes 4000 civs, 0 uws +1749 Play#6 output Play#6 1 Income from taxes 4000 civs, 0 uws +1749
Play#6 output Play#6 1 Total income.......................................................+1749 Play#6 output Play#6 1 Total income.......................................................+1749
Play#6 output Play#6 1 Balance forward 25000 Play#6 output Play#6 1 Balance forward 25000
Play#6 output Play#6 1 Estimated delta +74 Play#6 output Play#6 1 Estimated delta -196
Play#6 output Play#6 1 Estimated new treasury.............................................25074 Play#6 output Play#6 1 Estimated new treasury.............................................24804
Play#6 output Play#6 6 0 99 Play#6 output Play#6 6 0 99
Play#6 input ctld Play#6 input ctld
Play#6 output Play#6 1 Bye-bye Play#6 output Play#6 1 Bye-bye