patternjavaMinor
Tool to calculate profitability of certain items in a game
Viewed 0 times
itemsgamecalculateprofitabilitycertaintool
Problem
I have created a tool that lets me calculate the profitability of doing certain actions in an MMORPG game which I play, it's more edging towards a quick-and-dirty solution than towards a neat solution because it's simply a tool and does not need excessive robustness, however I do think there is room for improvements.
I'd like a review on all aspects, first I'll start of by explaining what it is really about as some domain knowledge is required.
Domain knowledge
This tool focuses on items of 29 Defensive Rating (DR) as input and it is all about upgrading the items, ultimately the goal is to produce a 32 DR item, which can be sold for a fair amount of money.
The item comes with an upgrade of level 0, and for these practices it needs to be upgraded to level 7, though it can be upgraded beyond in the game, here is a table with characteristics:
When an item succeeds to 7, it can be converted to a "32DR crystal", which can be sold.
When an item fails, it will produce 1~15 Dazzling Ores and a Level 100 Chip. If the upgrade that failed was from 6 to 7, it will produce 2 Level 100 Chips. Upon failure the item is lost.
To increase upgrade success, you can add 500 Shiny Crystals from upgrade from 4 to 5 onwards, which will double your success chance.
My goal is to calculate the most profitable method (possibly negative profit, also called loss) given the price of the 29 DR item.
Implementation-wise, I have decided for now to let it run on the console for ease of use and with a few variable parameters hard-coded. they resemble the price/value of an item in the game
I'd like a review on all aspects, first I'll start of by explaining what it is really about as some domain knowledge is required.
Domain knowledge
This tool focuses on items of 29 Defensive Rating (DR) as input and it is all about upgrading the items, ultimately the goal is to produce a 32 DR item, which can be sold for a fair amount of money.
The item comes with an upgrade of level 0, and for these practices it needs to be upgraded to level 7, though it can be upgraded beyond in the game, here is a table with characteristics:
- Upgrade from 0 to 1: Costs 141,000, 100% regular chance
- Upgrade from 1 to 2: Costs 141,000, 100% regular chance
- Upgrade from 2 to 3: Costs 141,000, 100% regular chance
- Upgrade from 3 to 4: Costs 141,000, 100% regular chance
- Upgrade from 4 to 5: Costs 141,000, 50% regular chance
- Upgrade from 5 to 6: Costs 211,500, 25% regular chance
- Upgrade from 6 to 7: Costs 282,000, 12.5% regular chance
When an item succeeds to 7, it can be converted to a "32DR crystal", which can be sold.
When an item fails, it will produce 1~15 Dazzling Ores and a Level 100 Chip. If the upgrade that failed was from 6 to 7, it will produce 2 Level 100 Chips. Upon failure the item is lost.
To increase upgrade success, you can add 500 Shiny Crystals from upgrade from 4 to 5 onwards, which will double your success chance.
My goal is to calculate the most profitable method (possibly negative profit, also called loss) given the price of the 29 DR item.
Implementation-wise, I have decided for now to let it run on the console for ease of use and with a few variable parameters hard-coded. they resemble the price/value of an item in the game
Solution
Structural
At the moment, a lot of the details you would in the future want to abstract away (for your idea of multiple item types and goals) are sprayed all over your code. For example, look at how many places you have variables with names like
For this reason, I'd suggest a more object-oriented approach. Start by thinking about how to structure your data and functionality, and then go from there.
I'd suggest that your basic class at this point is
I'd also suggest having a method to get the item at the next level, which would have this serve as a singly-linked list.
Algorithmic
I don't know whether you will ever be using this with a high enough volume of items, or with items where the potential upgrade paths are long/complex enough, for performance to matter. But iterating over every possible combination of crystal usage is needlessly inefficient, and also imposes unnecessary constraints on how you structure your main loops which might make the program harder to alter later.
It's easy to calculate whether or not to use shiny crystals at an item level. The condition is:
Which rearranges to:
Here, success and failure value are the values of the products you get for each result, and
Note that this is something that depends only on features of a single level. So you can calculate individually for each level whether or not to use the crystals.
Putting it together
So putting that together,
With that, all you need to do is construct the
(As a side-note, one assumption I've made is that you can buy and sell items at any upgrade level, and that the level will be reflected in the price. I don't think much of what I've said would be very significantly different if that wasn't the case, but there would be some alterations)
At the moment, a lot of the details you would in the future want to abstract away (for your idea of multiple item types and goals) are sprayed all over your code. For example, look at how many places you have variables with names like
upgrade7ShinyCrystals. While this could be avoided with data structures like arrays, you'd fast get into a situation of further complicating already quite complicated code. This is likely to lead to brittle code, where if you find yourself asking a question like "What if I want to also include upgrading to a lower level then selling in the profitability calculations?" you'll have difficulty getting an answer.For this reason, I'd suggest a more object-oriented approach. Start by thinking about how to structure your data and functionality, and then go from there.
I'd suggest that your basic class at this point is
ItemAtLevel. I'm calling it that to separate it from the more general concept of just an Item, where you might think of the current level as just one particular field. Most of the important information about an item is specific per level, so it would have fields for:- Value
- Whether it is the highest level available
- Probability of success upgrading to next level
- Whether shiny crystals can be used
- The value of items produced when the upgrade fails
I'd also suggest having a method to get the item at the next level, which would have this serve as a singly-linked list.
Algorithmic
I don't know whether you will ever be using this with a high enough volume of items, or with items where the potential upgrade paths are long/complex enough, for performance to matter. But iterating over every possible combination of crystal usage is needlessly inefficient, and also imposes unnecessary constraints on how you structure your main loops which might make the program harder to alter later.
It's easy to calculate whether or not to use shiny crystals at an item level. The condition is:
failureValue*(1-P) + successValue*P < failureValue*(1-2P) + successValue*2P - crystalCostWhich rearranges to:
crystalCost < (successValue-failureValue)*PHere, success and failure value are the values of the products you get for each result, and
P is the probability of failure. Note that this is something that depends only on features of a single level. So you can calculate individually for each level whether or not to use the crystals.
Putting it together
So putting that together,
ItemAtLevel can have a boolean shouldUseCrystals() method which uses the above formula to determine whether or not it should use Crystals, then an int averageUpgradeProfit(bool useCrystals) method, which would be a simple calculation of the expected profit including both success and failure possibilities, along the lines of the one you do in your code.With that, all you need to do is construct the
ItemAtLevel instances for each level of your item- or items of interest, and then the rest is extremely simple. If you wanted to know the total expected profit upgrading to your highest level, you could just use a loop (or stream function) to total up the average profit at each level. If you wanted to know the optimal level to stop upgrading, it wouldn't be much harder.(As a side-note, one assumption I've made is that you can buy and sell items at any upgrade level, and that the level will be reflected in the price. I don't think much of what I've said would be very significantly different if that wasn't the case, but there would be some alterations)
Code Snippets
failureValue*(1-P) + successValue*P < failureValue*(1-2P) + successValue*2P - crystalCostcrystalCost < (successValue-failureValue)*PContext
StackExchange Code Review Q#56661, answer score: 7
Revisions (0)
No revisions yet.