Price identification

3.6 · 3.7 · 5.0

Work a shop price backwards to the base costs that could have produced it, then to the items that carry those base costs. The arithmetic is a straight port of get_cost() and set_cost() from src/shk.c — integer division, round-half-up, artifact and anger surcharges applied after the rounding, which is where most price calculators drift.

Item & version
Object table
3.7 and 5.0 ship identical object tables, so they share one dataset.
Weapons and armor add 10 × N to base cost when N > 0. Negative enchantment costs nothing.
Object classes

Observations

One price rarely pins an item down. Add a second reading — the sell price for the same item, or the same item quoted at another shop or another Charisma — and the candidate sets are intersected.

How this works & what it cannot tell you

Price identification narrows an item to a base-cost bucket, never to a single item. Base cost 100 alone covers dozens of objects. Combine the bucket with what you already know — the object class, the appearance, what you have already identified — and, where possible, with a second observation.

The algorithm, exactly

Buying (get_cost) — base cost, 0 becomes 5; a 1-in-4 unidentified surcharge (×4/3, keyed off the object's ID, unknowable to you); then at most one of dunce cap / Tourist below XL14 / visible tourist shirt (×4/3, they are if / else-if in the C, so they never stack); then the Charisma ladder; then the rounding tweak tmp = floor((floor(tmp×10 / divisor) + 5) / 10); clamp up to 1; then artifact ×4; then the angry-shopkeeper + floor((tmp+2)/3). Those last two land after the rounding, on purpose.

Selling (set_cost) — the shopkeeper keeps half (÷2), or two thirds (÷3) if you look like a rube; a separate 1-in-4 markdown (×3/4, keyed off the shopkeeper's ID, and only when base cost > 1); the same rounding tweak; never rounded down to zero. Charisma and shopkeeper anger do not affect what you are offered.

The reverse lookup brute-forces every base cost from 1 to 30000 forward through the algorithm along both branches of the unknowable surcharge and keeps exact matches. It does not try to invert the arithmetic — round-half-up is not invertible.

Probability footnotes

Percentages are the item's generation probability within its own object class, using the class totals from the object table as the denominator — never a hardcoded 1000. In 5.0 the weapon probabilities sum to 1002, because silver mace was added without rebalancing the rest.

In 3.6 every ring carries prob 0 in objects.c — that is genuinely what the table says; the ring class is filled by picking uniformly instead. Ring probabilities for 3.6 are therefore shown as a uniform 1/28 and marked uniform. 3.7 and 5.0 give every ring an explicit probability of 1.

The other class lumps several C object classes together (coins, iron balls, chains, venom), so its total is not a meaningful denominator and no probability is shown for it.

Objects with base cost 0 are kept in the data so the denominators stay right, but they are never offered as candidates.