patternMinor
Calculator for magic item creation in RPG
Viewed 0 times
itemmagicforrpgcreationcalculator
Problem
I have created a simple calculator that will assist in creating magic items from the tabletop RPG Pathfinder. Here are the full requirements, and if you want a more concise version, here is a player generated summary of the process.
I have been trying to get into F# and functional programming in general. I come from a strong object-oriented background and it has been difficult in ignoring those habits. Please focus on whether or not this is idiomatic F#. I would love to hear if there is a better way to write any of it. And, if you find bug, I'd be happy to know that too.
Questions
A couple of things specifically that I feel could be better would be the DC calculation. I wasn't sure how to approach applying the rush function only if the item was rushed. I also tried finding a place where I could apply functional composition, but I think I needed all the intermediate steps that I stop on.
Code
```
let baseDC casterLevel =
5 + casterLevel
let rush dc =
dc + 5
let ignoreRequirements requirements dc =
dc + (5 * requirements)
let getBuildPrice basePrice =
basePrice * 0.5
let getTime basePrice =
floor (8.0 * basePrice / 1000.0)
let getMinBonusForNoCursed dc =
dc - 6
let buildDaysWhileAdventuring isRushed buildTime =
let adventuringBuildTime = buildTime / 4.0
floor (if isRushed then adventuringBuildTime else adventuringBuildTime * 2.0)
[]
let main argv =
printfn "%A" argv
let isRushed = true
let casterLevel = 1
let requirementsIgnored = 1
let basePrice = 5000.0
let buildPrice = getBuildPrice basePrice
let buildTime = getTime basePrice
let daysAdventuring = buildDaysWhileAdventuring isRushed buildTime
let DC =
match isRushed with
| false -> baseDC casterLevel |> ignoreRequirements requirementsIgnored
| true -> baseDC casterLevel |> ignoreRequirements requirementsIgnored |> rush
let minDC = getMinBonusForNoCursed DC
printfn "Min/DC: %i/%i Cost: %.2f Days/Hou
I have been trying to get into F# and functional programming in general. I come from a strong object-oriented background and it has been difficult in ignoring those habits. Please focus on whether or not this is idiomatic F#. I would love to hear if there is a better way to write any of it. And, if you find bug, I'd be happy to know that too.
Questions
A couple of things specifically that I feel could be better would be the DC calculation. I wasn't sure how to approach applying the rush function only if the item was rushed. I also tried finding a place where I could apply functional composition, but I think I needed all the intermediate steps that I stop on.
Code
```
let baseDC casterLevel =
5 + casterLevel
let rush dc =
dc + 5
let ignoreRequirements requirements dc =
dc + (5 * requirements)
let getBuildPrice basePrice =
basePrice * 0.5
let getTime basePrice =
floor (8.0 * basePrice / 1000.0)
let getMinBonusForNoCursed dc =
dc - 6
let buildDaysWhileAdventuring isRushed buildTime =
let adventuringBuildTime = buildTime / 4.0
floor (if isRushed then adventuringBuildTime else adventuringBuildTime * 2.0)
[]
let main argv =
printfn "%A" argv
let isRushed = true
let casterLevel = 1
let requirementsIgnored = 1
let basePrice = 5000.0
let buildPrice = getBuildPrice basePrice
let buildTime = getTime basePrice
let daysAdventuring = buildDaysWhileAdventuring isRushed buildTime
let DC =
match isRushed with
| false -> baseDC casterLevel |> ignoreRequirements requirementsIgnored
| true -> baseDC casterLevel |> ignoreRequirements requirementsIgnored |> rush
let minDC = getMinBonusForNoCursed DC
printfn "Min/DC: %i/%i Cost: %.2f Days/Hou
Solution
I see a few problems with this, most notably, you have a plethora of magic numbers.
In order, I see:
For a functional program, it's not too bad. I don't like how many times you use
let baseDC casterLevel =
5 + casterLevel
let rush dc =
dc + 5
let ignoreRequirements requirements dc =
dc + (5 * requirements)
let getBuildPrice basePrice =
basePrice * 0.5
let getTime basePrice =
floor (8.0 * basePrice / 1000.0)
let getMinBonusForNoCursed dc =
dc - 6
let buildDaysWhileAdventuring isRushed buildTime =
let adventuringBuildTime = buildTime / 4.0
floor (if isRushed then adventuringBuildTime else adventuringBuildTime * 2.0)In order, I see:
5 + casterLevel: what is5?
dc + 5: what is5? Is it the same as #1?
5 * requirements: what is5? Is it the same as #1 or #2?
basePrice * 0.5: what is0.5? Is it1 / 2or something different?
8.0 * basePrice: what is8.0?
#5 / 1000.0: what is1000.0?
dc - 6: what is6?
buildTime / 4.0: what is4.0?
adventuringBuildTime * 2.0: what is2.0, is it4.0 / 2, is it the4.0from #8 / 2?
For a functional program, it's not too bad. I don't like how many times you use
if (I always prefer match), but when dealing with boolean types it does quite fine.Code Snippets
let baseDC casterLevel =
5 + casterLevel
let rush dc =
dc + 5
let ignoreRequirements requirements dc =
dc + (5 * requirements)
let getBuildPrice basePrice =
basePrice * 0.5
let getTime basePrice =
floor (8.0 * basePrice / 1000.0)
let getMinBonusForNoCursed dc =
dc - 6
let buildDaysWhileAdventuring isRushed buildTime =
let adventuringBuildTime = buildTime / 4.0
floor (if isRushed then adventuringBuildTime else adventuringBuildTime * 2.0)Context
StackExchange Code Review Q#162040, answer score: 2
Revisions (0)
No revisions yet.