SWY1985 / CivOne

An open source implementation of Sid Meier's Civilization.
http://www.civone.org/
Creative Commons Zero v1.0 Universal
245 stars 49 forks source link

Buy values sometimes too high #332

Closed AlexFolland closed 7 years ago

AlexFolland commented 7 years ago

I don't know what causes this, but sometimes the buy values are not proportional to the number of shields required. The SETI Program wonder should cost 4800 coins if you buy it on the first turn, then 4 times the remaining shields on subsequent turns. It should never cost a value higher than 4800 with no shields or or 2396 with 1 or more shield. Each shield costs 4 coins, or 8 if there are no shields.

image

AlexFolland commented 7 years ago

Here's another example. A Factory requires 200 production to complete. In this screenshot, I have built 80 shields, so 120 shields remain. The buy value should be 480, but instead, it says 960. In this case, it's exactly double what it should be.

image

SWY1985 commented 7 years ago

That's a bugger, I thought I had it all figured out.

AlexFolland commented 7 years ago

I might be wrong and buildings might cost double what units cost. I was doing my calculation based on Settlers, which is a unit I buy very often in Civilization. However, 17980 is beyond that anyway.

SWY1985 commented 7 years ago

We figured it out here: https://forums.civfanatics.com/threads/buy-unit-building-wonder-price.576026/#post-14490920

I have either made a mistake in the implementation, or there's some extra rules that we didn't take into account.

AlexFolland commented 7 years ago

That formula looks non-linear. The unit price formula may be non-linear, but the buildings formula is definitely linear. Notice how every buy value is a multiple of 2 for non-wonder buildings and 4 for wonders.

Here is a pseudocode assignment for buildings:

price = ( totalShieldsRequired - currentShields ) << ( isWonder ? 2 : 1 ) << ( ( currentShields ) ? 0 : 1 )

The << are bitwise shift left operators for fast multiplication; a minor optimization for speed. Multiply by 4 or 2 if isWonder instead if you want to avoid bitwise shift operators, and 1 or 2 if currentShields.

I'm not sure about the formula for units. Your current formula may well apply to them. Tristan_C was right in that thread about buildings and wonders though. CivOne is just incorrectly applying the units formula to buildings.