Twine Version: 2.3.5
Story Format: Harlowe
Okay, I’m trying to simulate a store and things are getting complicated… The math already seems to be slowing down the refresh rate of displaying quantities and dollars, and when we get into high numbers, things start to get weird. Like infinite loops popping up and stuff. I’m self-taught so I think it’s time to call in some help. I’ll just paste my code and explain it and you’ll hopefully see the problems.
Okay, so I first set up a customer modifier variable and a max customers variable somewhere else. Here, I set up an array of customers and then randomize it, then I make them into datamaps that have a certain number of slots to buy items, randomized between 1 and 3. Finally, those buy slots are all added up in the total $buyslots
(set: $customers to (range: 1,(ceil: $maxcustomers * $customermod)))
(set: $customers to (range: 1,(random: (round: $customers's length - ($customers's length * .10)), (round: $customers's length + ($customers's length * .10)))))
(set: $buyslots to 0)
(for: each _index, ...(range: 1, $customers's length))[
(set: $customers's (_index) to (dm:
"name","default",
"buyslots", 1
))
(set: $customers's (_index)'s buyslots to (random: 1,3))
(set: $buyslots to it + $customers's (_index)'s buyslots)
]
So next I need to take the list of products the store has in stock and shuffle it, because if it’s in the same order every time the first items on the list will be bought more often. So for each product on the now shuffled list, I first zero out a $salesmod (holds the number of sales for that item) and a “calc” in the items datamap (the final number of sales for that item). Anyway, then I calculate the popularity of the item (it needs to be limited to a range of 1-10, which the items can go outside of, but they are capped for this calculation - that’s what $poplimit is)
Next comes the part I’ve been having the most trouble with and I think the source of the infinite loop issue but I’m really not sure. For each buy slot, it picks a number from 1-10, and if that falls within the popularity of the item, the customer buys it, and a buy slot is removed.
Finally, the number of that item bought is calculated, that number is taken out of the store’s stock, the money is added to the store’s money, and the total sale is recorded.
(set: $products to (shuffled: ...$products))
(for: each _index, ...(range: 1, $products's length))[
(set: $salesmod to 0)
(set: $products's (_index)'s calc to 0)
(if: $products's (_index)'s number > 0)[
(if: $products's (_index)'s popularity < 0)[
(set: $poplimit to 0)
]
(else-if: $products's (_index)'s popularity > 10)[
(set: $poplimit to 10)
]
(else:)[
(set: $poplimit to $products's (_index)'s popularity)
]
(for: each _slot, ...(range: 1, $buyslots))[
(if: $buyslots >= 1)[
(set: $salecheck to (random: 1, 10))
(if: $salecheck <= $poplimit)[
(set: $salesmod to it + 1)
(set: $buyslots to it - 1)
]
]
]
(if: $salesmod <= $products's (_index)'s number)[
(set: $products's (_index)'s calc to $salesmod)
]
(else:)[
(set: $products's (_index)'s calc to $products's (_index)'s number)
]
(if: $products's (_index)'s calc <= 0 and $products's (_index)'s pop is "not popular")[
(set: $products's (_index)'s calc to 0)
]
(else-if: $products's (_index)'s calc <= 0)[
(set: $products's (_index)'s calc to 1)
]
(set: $products's (_index)'s number to (it - $products's (_index)'s calc))
(set: $dollarDiff to ($products's (_index)'s calc * $products's (_index)'s price))
(set: $dollars to it + $dollarDiff)
(set: $totalsale to it + $dollarDiff)
]
]
And here’s a pretty clunky way to get the list back in alphabetical order, by putting the names of the products in an array, sorting it, then matching the datamap of products to the alphabetized list (to display in many other areas of the game along with their number, price, etc.). If anyone knows a better way to do this, please tell me.
(set: $alphabetizer to (a:))
(set: $tempProducts to (a:))
(for: each _name, ...$products)[
(set: $alphabetizer to it + (a: _name's name))
]
(set: $alphabetizer to (sorted: ...$alphabetizer))
(for: each _name, ...$alphabetizer)[
(for: each _index, ...(range: 1, $products's length))[
(set: _item to $products's (_index))
(if: _item's name is _name)[
(set: $tempProducts to it + (a: _item))
]
]
]
(set: $products to $tempProducts)
Woooo! That’s it. What a mess. Hope someone can help.