Quick actions

cmd+k|ctrl+k

Navigation

Languages

LifeRPG - RP Reward Calculator

Snippet info

Language

Haskell

Visibility

public

Author

robjameswhitaker

Created

2016-09-21T16:53:05Z

Updated

2016-09-23T19:49:28Z

import Data.List
--------------------------------------------------------------------------------
-- LifeRPG - RP Reward Calculator 
-- 
-- A simple calculator to help decide how to price rewards in LifeRPG. 
--
-- Instructions: 
-- 
-- 1) Fill in the price of your reward in real currency:
price = 49.99
--
-- 2) Add high and low "real currency to RP" conversion points below. Additional
--    points may be added, but there must be at least two. "Dollar" here can be
--    replaced with RealCurrency, Minute, Hour, or Day. It makes no difference,
--    but might help clarity.
conversionPoints = 
    [ a 10  Dollar reward `should` cost 250  RP
    , a 50  Dollar reward `should` cost 750  RP
    , a 100 Dollar reward `should` cost 1000 RP
    ]
--
-- 3) Click the "Run" button below to calculate your reward cost.
--
-- Note: I use the term "price" here, but it can just as well be thought of
--       as "time" if the reward costs time instead of money. 
--------------------------------------------------------------------------------

---- PROGRAM START: DO NOT EDIT THIS ----

main :: IO ()
main = do
    let points = sort conversionPoints
    if length points < 2 then error "Must have 2 or more conversion points."
    else return ()
    if price < 0 || any (\(x,y) -> x < 0 || y < 0) points then
        error "All values must be positive."
    else return ()
    let (lowPoints,highPoints) = partition ((>=) price . fst) points
    printRP $ calcRP price lowPoints highPoints
  where
    printRP rp = do
        putStr "Your reward should cost: "
        putStr $ show rp 
        putStrLn " RP!"

calcRP :: Float -> [(Float,Float)] -> [(Float,Float)] -> Int
calcRP price lowPoints highPoints
    | null lowPoints  = round $
        price * (snd . head $ highPoints) / (fst . head $ highPoints)
    | null highPoints = round $
        price * (snd . last $ lowPoints) / (fst . last $ lowPoints)
    | otherwise       = round rpAmount
  where
    lowRP = (snd . last) lowPoints
    lowCurrency = (fst . last) lowPoints
    highRP = (snd . head) highPoints
    highCurrency = (fst . head) highPoints
    rpSlope = (highRP - lowRP) / (highCurrency - lowCurrency)
    rpAmount = (price - lowCurrency) * rpSlope + lowRP
            
---- eDSL Helpers ----
data Currency = RealCurrency | Dollar | RP | Minute | Hour | Day

reward = ""

a :: Float -> Currency -> String -> Float
a realCurrency _ _ = realCurrency

cost :: Float -> Currency -> Float
cost = const

should :: Float -> Float -> (Float, Float)
should = (,)

        
INFO