Skip to content

Instantly share code, notes, and snippets.

@SecondReality
Created December 26, 2013 06:14
Show Gist options
  • Save SecondReality/8130379 to your computer and use it in GitHub Desktop.
Save SecondReality/8130379 to your computer and use it in GitHub Desktop.
This was a small Haskell program I made long ago work out the optimal minions to buy in the Vampire Wars Facebook game.
import Data.List (sortBy)
import Text.Printf (printf)
-- MinionData: Name, initial cost, produce, cost increase
data MinionData = MinionData String Integer Integer Integer deriving Show
minions =
[
MinionData "Bum" 5000 100 500,
MinionData "Park Jogger" 20000 400 2000,
MinionData "Escaped Mental Patient" 25000 500 2500,
MinionData "Cop" 100000 2000 10000,
MinionData "High School Football Team" 350000 7000 35000,
MinionData "Blood Bank Nurse" 600000 12000 60000,
MinionData "Paramedic" 750000 15000 75000,
MinionData "Diner Waitress" 900000 18000 90000,
MinionData "Group of Ninjas" 1000000 20000 100000,
MinionData "Mime" 1200000 24000 120000,
MinionData "Hacker" 1250000 25000 125000,
MinionData "College Fraternity" 3250000 65000 325000,
MinionData "Bank Teller" 4000000 80000 400000,
MinionData "SWAT Strike Team" 12000000 150000 750000,
MinionData "Law Firm" 25000000 200000 2500000
]
-- Returns the initial state of the world: 0 of each minion
initialState :: [(MinionData, Integer)]
initialState = zip minions (repeat 0)
-- Given a minion and a current count of them this will return the cost
getPrice :: (MinionData, Integer)->Integer
getPrice (MinionData _ initialCost _ costIncrease, amountOwned) = (initialCost + (costIncrease * amountOwned))
-- Given a minion type and current amount this returns the return on investment
-- Return on investment is the income generated / investment - converted to %
roi :: (MinionData, Integer)->Double
roi minionAndCount@(MinionData _ initialCost produce _, amountOwned) = 100 * (fromIntegral produce / fromIntegral (getPrice minionAndCount))
-- Given a world representation sort it in order of ROI:
roiSort :: [(MinionData, Integer)]->[(MinionData, Integer)]
roiSort = Data.List.sortBy (\ x y -> compare (roi y) (roi x))
minionString :: (MinionData, Integer)->String
minionString minionAndCount@(MinionData name initialCost produce _, amountOwned) = printf "%-40s%-10s%s" name (show amountOwned) (show (roi minionAndCount))
printMinion :: (MinionData, Integer) -> IO ()
printMinion = putStrLn.minionString
printMinions :: [(MinionData, Integer)] -> IO ()
printMinions = mapM_ printMinion
main = do
putStrLn "Welcome to Vampire Wars Investment Helper"
putStrLn "Your current minions:"
-- Print out the minions, ordered by the ROI. The format is: minion name, count, roi
printMinions initialState
putStrLn "Input your list of minions"
-- The minion count is input as a Haskell array, e.g. [1,2,3,4]
minionCount <- getLine
let minionArray = (read minionCount::[Integer]) ++ repeat 0 in
printMinions (roiSort(zip minions minionArray))
-- Unused functions --
-- Buy n of the minion at the given index (n can be negative to sell them).
buy :: Integer->Int->[(MinionData, Integer)]->[(MinionData, Integer)]
buy minionCount index world = (++) begin $ (minion, amount+minionCount):tail end
where (begin, end) = splitAt index world; (minion, amount) = head end
-- Given the inventory, calculate the total income:
income :: [(MinionData, Integer)]->Integer
income = sum . map getProfit
-- Given a minion and a count, returns the amount of blood generated
getProfit :: (MinionData, Integer)->Integer
getProfit (MinionData _ _ produce costIncrease, amountOwned) = amountOwned * produce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment