diff options
Diffstat (limited to '19.c')
-rw-r--r-- | 19.c | 51 |
1 files changed, 30 insertions, 21 deletions
@@ -45,7 +45,6 @@ blueprint_ctor(struct blueprint * b, int id, int ore_ore, int clay_ore, struct material { long amount; long robots; - long pending; }; @@ -54,7 +53,6 @@ material_ctor(struct material * m, long amount, long robots) { m->amount = amount; m->robots = robots; - m->pending = 0; } @@ -63,11 +61,11 @@ material_ctor(struct material * m, long amount, long robots) // Amount increases by the number of robots // Number of robots increases by number of pending robots void -material_tick(struct material * m) +material_tick(struct material * m, int build) { m->amount += m->robots; - m->robots += m->pending; - m->pending = 0; + if (build) + ++m->robots; } @@ -76,6 +74,7 @@ struct inventory { struct material clay; struct material bsdn; struct material geod; + enum MATERIAL pending; }; @@ -86,6 +85,7 @@ inventory_init(struct inventory * i) material_ctor(&i->clay, 0, 0); material_ctor(&i->bsdn, 0, 0); material_ctor(&i->geod, 0, 0); + i->pending = -1; } @@ -113,10 +113,11 @@ inventory_cmp(struct inventory const * a, struct inventory const * b) void inventory_tick(struct inventory * i) { - material_tick(&i->ore); - material_tick(&i->clay); - material_tick(&i->bsdn); - material_tick(&i->geod); + material_tick(&i->ore, i->pending == ORE); + material_tick(&i->clay, i->pending == CLAY); + material_tick(&i->bsdn, i->pending == BSDN); + material_tick(&i->geod, i->pending == GEOD); + i->pending = -1; } @@ -126,35 +127,39 @@ inventory_build(struct inventory * i, struct blueprint const * b, enum MATERIAL { switch (m) { case ORE: - if (i->ore.amount < b->ore_ore) + if (i->pending != -1 + || i->ore.amount < b->ore_ore) return -1; i->ore.amount -= b->ore_ore; - i->ore.pending += 1; + i->pending = ORE; break; case CLAY: - if (i->ore.amount < b->clay_ore) + if (i->pending != -1 + || i->ore.amount < b->clay_ore) return -1; i->ore.amount -= b->clay_ore; - i->clay.pending += 1; + i->pending = CLAY; break; case BSDN: - if (i->ore.amount < b->bsdn_ore + if (i->pending != -1 + || i->ore.amount < b->bsdn_ore || i->clay.amount < b->bsdn_clay) return -1; i->ore.amount -= b->bsdn_ore; i->clay.amount -= b->bsdn_clay; - i->bsdn.pending += 1; + i->pending = BSDN; break; case GEOD: - if (i->ore.amount < b->geod_ore + if (i->pending != -1 + || i->ore.amount < b->geod_ore || i->bsdn.amount < b->geod_bsdn) return -1; i->ore.amount -= b->geod_ore; i->bsdn.amount -= b->geod_bsdn; - i->geod.pending += 1; + i->pending = GEOD; break; default: @@ -224,7 +229,8 @@ inventory_build_exhaustive(struct inventory * i, struct blueprint const * b, int // Try building a geode robot, and check if that's better than doing nothing. if (inventory_build(&test, b, GEOD) == 0) { // fprintf(stderr, "%d: building a geod robot (%ld)\n", remaining, test.geod.amount); - inventory_build_exhaustive(&test, b, remaining); + inventory_tick(&test); + inventory_build_exhaustive(&test, b, remaining - 1); if (inventory_cmp(&test, &best) > 0) best = test; test = *i; @@ -233,7 +239,8 @@ inventory_build_exhaustive(struct inventory * i, struct blueprint const * b, int // Try building a obsidian robot, and checking if that's better than anything else if (inventory_build(&test, b, BSDN) == 0) { // fprintf(stderr, "%d: building a bsdn robot (%ld)\n", remaining, test.bsdn.amount); - inventory_build_exhaustive(&test, b, remaining); + inventory_tick(&test); + inventory_build_exhaustive(&test, b, remaining - 1); if (inventory_cmp(&test, &best) > 0) best = test; test = *i; @@ -242,7 +249,8 @@ inventory_build_exhaustive(struct inventory * i, struct blueprint const * b, int // Try building a clay robot, and checking if that's better than anything else if (inventory_build(&test, b, CLAY) == 0) { // fprintf(stderr, "%d: building a clay robot (%ld)\n", remaining, test.clay.amount); - inventory_build_exhaustive(&test, b, remaining); + inventory_tick(&test); + inventory_build_exhaustive(&test, b, remaining - 1); if (inventory_cmp(&test, &best) > 0) best = test; test = *i; @@ -251,7 +259,8 @@ inventory_build_exhaustive(struct inventory * i, struct blueprint const * b, int // Try building a ore robot, and checking if that's better than anything else if (inventory_build(&test, b, ORE) == 0) { // fprintf(stderr, "%d: building a ore robot (%ld)\n", remaining, test.ore.amount); - inventory_build_exhaustive(&test, b, remaining); + inventory_tick(&test); + inventory_build_exhaustive(&test, b, remaining - 1); if (inventory_cmp(&test, &best) > 0) best = test; test = *i; |