--{-# LANGUAGE TupleSections #-} module Dodge.Combine (combineList) where import NewInt import Dodge.Data.CombAmount import Dodge.Item.InvSize import Dodge.Item.Grammar import Data.Bifunctor import Data.Foldable import Data.List (sort, sortOn) import qualified Data.Map.Strict as M import Dodge.Base.You import Dodge.Combine.Combinations import Dodge.Data.Combine import Dodge.Data.Universe import Dodge.Item.Display import Dodge.Item.InventoryColor import qualified IntMapHelp as IM import SimpleTrie combineList :: World -> [SelectionItem CombItem] combineList = map f . combineItemListYouX where f (is, itm) = SelItem { _siPictures = basicItemDisplay itm , _siHeight = itInvHeight itm , _siWidth = 15 , _siIsSelectable = True , _siColor = itemInvColor $ baseCI itm , _siOffX = 2 , _siPayload = Just $ CombItem is itm } combineItemListYouX :: World -> [([Int], Item)] combineItemListYouX = map (first concat) . flatLookupItems . _unNIntMap . yourInv flatLookupItems :: IM.IntMap Item -> [([[Int]], Item)] flatLookupItems = flip multiLookupTrieI combinationsTrie . sortOn fst . groupSplitItemAmounts . invertInventoryToMap combinationsTrie :: Trie (CombAmount, ItemType) Item {-# INLINE combinationsTrie #-} combinationsTrie = foldl' (flip $ uncurry insertInTrie . first sort) emptyTrie itemCombinations groupSplitItemAmounts :: M.Map ItemType [Int] -> [((CombAmount, ItemType), [Int])] groupSplitItemAmounts = M.foldMapWithKey f where f ibt is = [((fromIntegral i, ibt), take i is) | i <- [1 .. length is]] invertInventoryToMap :: IM.IntMap Item -> M.Map ItemType [Int] invertInventoryToMap = IM.foldrWithKey (\k it -> M.insertWith (++) (_itType it) [k]) mempty