I'm working on a gam (naturally), and the primary activity for the player is to buy and sell commodities at various marketplaces.
Each commodity has the following properties:
Base Price: if all things were otherwise equal, this would be the measure of value for the commodity Supply Factor: when a player sells one unit of this commodity in a market, the "supply" goes up by this factor Demand Factor: when a player purchases one unit of this commodity in a market, the "demand" goes up by this factor.
Within each market, the commodities are given the following local properties: Local Supply Local Demand
To keep things "simple", I have these values generated randomly with the equivalent of a 3d6, so Supply and Demand can be anywhere from 3-18.
The price for one unit of a commodity in a particular market is calculated like so:
Price = BasePrice * (LocalDemand+DemandFactor*UnitsDemanded) / (LocalSupply+SupplyFactor*UnitsSupplied)
In this way, player purchases will drive the price up, and player sales will drive the price down.
Now comes the problem, and I'll use a concrete example as it is not entirely obvious from just looking at the formula.
We have commodity X with a base price of 100, and local demand and local supply both of 10, and a supply and demand factor each of 1.
So, desiring to purchase a single unit, I calculate the price:
Price = 100 * (10+1*0) / (10+1*0) = 100
And I purchase the unit, which drives up the price to:
Price = 100 * (10+1*1) / (10+1*0) = 110
And if the player then sells the commodity at that price, he immediately profits 10.
This is no good.
So, my first pass at this solution is to calculate the price based on what the supply or demand WILL BE after the purchase is over, which works after a fashion, but consider that in the example above, the purchase of 1 unit will be 110, whereas the purchase of 10 units will have a unit price of:
(100 * (10+1*10) / (10+1*0)) = 200 (total of 2000 to buy 10 units)
So, naturally this is unfair, and so the player would get the best price for purchasing one unit at a time.
And I don't want the player to have to do that, so I want to calculate the price one unit at a time.
This in itself is relatively easy, just loop through the units I want to purchase, and add it up.
Unfortunately, it doesn't exactly take care of the fractional units.
I might not have mentioned that you can own fractional units of commodities. You can.
Another thing to compound the issue is that the "currency" is simply another commodity, which can itself have supply, demand, supply factor, demand factor, sales, purchases, and so on.
So purchasing is a two step problem.
First, for a particular number of units of a commodity, determine the "value" of them in a way that ensure that buying and then immediately selling is a losing proposition.
Second, for a particular "value", determine the number of units that would need to be "sold" in order to make up that value.
Another wrinkle: it should not be advantageous to purchase fractional units. The price for buying half a unit, and then buying another half a unit should not be better or worse than buying one whole unit at one time.
Answer
When computing the price for the units that the player is trading, don't use the final number of units left after the transaction. Instead, use the arithmetic mean of the two quantities, before and after the transaction.
For example: if the player wants to purchase 1 unit out of 10 available units, use the price of the commodity as it would be at 9.5 units available. If the player instead wants to do two transactions of 0.5 units each, you'd first pay him at 9.75 price and then at 9.25 price, thus giving him the same amount of currency.
This should also solve the issue of buying, immediately selling and thus generating a profit, since in both instances you would sell for an average number of units, which would be equal in both instances. In our previous example the player would buy 1 unit out of 10 at the price of 9.5 units, then sell that unit back at the price of 9.5 units, therefore gaining just as much currency as he lost.
Another advantage to this approach is that you should no longer need that loop you mentioned.
No comments:
Post a Comment