Chris Thomas
Chris Thomas

Reputation: 1

Text adventure game in Python - Creating a random selection of items from a text file with weighted properties

I'm currently creating an inventory system for a text adventure game in Python. I have a list of items in a text file with the rarity of them item after a comma. e.g.

potion, 1
sword, 2
legendary armour, 7

I have tried a few variants of importing the file and random selection but I can't seem to find a solution by myself.

The basic operation is...

The items need to be weighted based on their rarity vs the current player level, so the higher the player level, the higher chance of a rarer item being offered.


So far I have tried importing the items and weights into different lists, but comparing these to the level is complicated.

I have also considered making separate text files based on each level and having duplicates of each item to measure the weightings but this would make thousands of lines just for the items.

There must be a way I am not considering.

Upvotes: 0

Views: 479

Answers (1)

Sam Mason
Sam Mason

Reputation: 16184

just answering the random part of the question, random.choices is useful for this. you can set the "weights" according to the item rarity and player level. for example:

read in data:

from io import StringIO
import csv

with StringIO("potion,1\nsword,2\nlegendary armour,7\n") as fd:
  items = {item: float(rarity) for item, rarity in csv.reader(fd)}

gives you a dictionary with keys set to the item name, and values set to the numeric value of the rarity. note that libraries like pandas can make this sort of thing easier.

I'd then calculate the "weight" by calculating something like the distance from rarity to player level by doing: 0.5**abs(rarity - level). this will give large numbers where the rarity and player level are similar (divide the level by something to adjust this) while smaller weights where this is less similar

this can then be used to pick a choice with:

from random import choices

level = 3
weights = [0.5**abs(rarity - level) for rarity in items.values()]

drops = choices(list(items.keys()), weights=weights, k=2)

this will sample from the items with probabilities proportional to weights. in this case it'll be (~31%, ~62%, ~8%) for the above items.

the above weighting function is symmetric, so when the player high level then they'll only get high level items. if you don't want that then you could use something like a "sigmoid function" to progressively reveal higher level items as the player level increases. this would look something like 1/(1 + math.exp(rarity - level))

Upvotes: 1

Related Questions