Improve item combination algorithm
This commit is contained in:
+29
-10
@@ -27,33 +27,52 @@ import Data.Map.Merge.Strict
|
|||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.List (scanl',sortOn,sort)
|
import Data.List (scanl',sortOn,sort)
|
||||||
|
|
||||||
combinationsTrie :: Trie (Int,ItemBaseType) Item
|
combinationsTrie :: Trie (IcAmount,ItemBaseType) Item
|
||||||
combinationsTrie = foldr
|
combinationsTrie = foldr
|
||||||
(uncurry insertInTrie . first (sortOn snd))
|
(uncurry insertInTrie . first sort)
|
||||||
emptyTrie
|
emptyTrie
|
||||||
itemCombinations
|
itemCombinations
|
||||||
|
|
||||||
|
invertInventory :: IM.IntMap Item -> [(ItemBaseType,IcAmount,Int)]
|
||||||
|
invertInventory = IM.foldrWithKey
|
||||||
|
(\k it -> ((_iyBase $ _itType it, itStackAmount it,k) :) )
|
||||||
|
[]
|
||||||
|
splitIcAmounts :: [(ItemBaseType,IcAmount,Int)] -> [((IcAmount,ItemBaseType),(IcAmount,Int))]
|
||||||
|
splitIcAmounts = concatMap f
|
||||||
|
where
|
||||||
|
f (x,n,y) = [((i,x),(i,y)) | i <- [1..n]]
|
||||||
|
|
||||||
|
lookupItems' :: IM.IntMap Item -> [([(IcAmount,Int)],Item)]
|
||||||
|
lookupItems' = flip multiLookupTrieI combinationsTrie . sortOn fst . splitIcAmounts . invertInventory
|
||||||
|
|
||||||
|
combineItemListYou :: World -> [([Int],Item)]
|
||||||
|
combineItemListYou = map (first f) . lookupItems' . yourInv
|
||||||
|
where
|
||||||
|
f = concatMap g
|
||||||
|
g (amount,i) = replicate (_toInt amount) i
|
||||||
|
|
||||||
|
|
||||||
-- this can probably be improved by going through accessing the combinations
|
-- this can probably be improved by going through accessing the combinations
|
||||||
-- trie going through each combine type in your inventory in order, rather than
|
-- trie going through each combine type in your inventory in order, rather than
|
||||||
-- creating all multisets of combine types.
|
-- creating all multisets of combine types.
|
||||||
|
|
||||||
lookupItems :: [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,Int)]
|
lookupItems :: [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,IcAmount)]
|
||||||
-> [ ([(M.Map ModuleSlot ItemModuleType,Int)],Item) ]
|
-> [ ([(M.Map ModuleSlot ItemModuleType,Int)],Item) ]
|
||||||
lookupItems xs = lookupItemsUsingTrie (sortOn (\(_,ct,_,_) -> ct) xs) combinationsTrie
|
lookupItems xs = lookupItemsUsingTrie (sortOn (\(_,ct,_,_) -> ct) xs) combinationsTrie
|
||||||
|
|
||||||
lookupItemsUsingTrie :: [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,Int)]
|
lookupItemsUsingTrie :: [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,IcAmount)]
|
||||||
-> Trie (Int,ItemBaseType) Item
|
-> Trie (IcAmount,ItemBaseType) Item
|
||||||
-> [ ([(M.Map ModuleSlot ItemModuleType,Int)],Item) ]
|
-> [ ([(M.Map ModuleSlot ItemModuleType,Int)],Item) ]
|
||||||
lookupItemsUsingTrie [] t = maybeToList $ ([],) <$> _trieMVal t
|
lookupItemsUsingTrie [] t = maybeToList $ ([],) <$> _trieMVal t
|
||||||
lookupItemsUsingTrie ((mods,ct,i,n):xs) t = do
|
lookupItemsUsingTrie ((mods,ct,i,n):xs) t = do
|
||||||
n' <- [1..min n 4]
|
n' <- [1..min n 4]
|
||||||
let is = replicate n' (mods,i)
|
let is = replicate (_toInt n') (mods,i)
|
||||||
concatMap (map (first (is ++)) . lookupItemsUsingTrie xs) $ maybeToList (_trieChildren t M.!? (n',ct))
|
concatMap (map (first (is ++)) . lookupItemsUsingTrie xs) $ maybeToList (_trieChildren t M.!? (n',ct))
|
||||||
|
|
||||||
invertListInvMult :: IM.IntMap Item -> [[(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,Int)]]
|
invertListInvMult :: IM.IntMap Item -> [[(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,IcAmount)]]
|
||||||
invertListInvMult = powlistUpToN 4 . invertListInv
|
invertListInvMult = powlistUpToN 4 . invertListInv
|
||||||
|
|
||||||
invertListInv :: IM.IntMap Item -> [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,Int)]
|
invertListInv :: IM.IntMap Item -> [(M.Map ModuleSlot ItemModuleType,ItemBaseType,Int,IcAmount)]
|
||||||
invertListInv = IM.foldrWithKey
|
invertListInv = IM.foldrWithKey
|
||||||
(\k it -> ((_iyModules $ _itType it,_iyBase $ _itType it, k, itStackAmount it) :) )
|
(\k it -> ((_iyModules $ _itType it,_iyBase $ _itType it, k, itStackAmount it) :) )
|
||||||
[]
|
[]
|
||||||
@@ -61,8 +80,8 @@ invertListInv = IM.foldrWithKey
|
|||||||
-- gives a list of indices-item pairs.
|
-- gives a list of indices-item pairs.
|
||||||
-- Note that within the pair, indices can be repeated if two or more of an item
|
-- Note that within the pair, indices can be repeated if two or more of an item
|
||||||
-- are needed
|
-- are needed
|
||||||
combineItemListYou :: World -> [([Int],Item)]
|
combineItemListYou'' :: World -> [([Int],Item)]
|
||||||
combineItemListYou = map (second fst) . combineItemListYou'
|
combineItemListYou'' = map (second fst) . combineItemListYou'
|
||||||
|
|
||||||
combineItemListYou' :: World -> [([Int],(Item,[String]))]
|
combineItemListYou' :: World -> [([Int],(Item,[String]))]
|
||||||
combineItemListYou' = map addModules . concatMap lookupItems . invertListInvMult . yourInv
|
combineItemListYou' = map addModules . concatMap lookupItems . invertListInvMult . yourInv
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import LensHelp
|
|||||||
|
|
||||||
--import Data.Maybe
|
--import Data.Maybe
|
||||||
|
|
||||||
itemCombinations :: [([(Int,ItemBaseType)],Item)]
|
itemCombinations :: [([(IcAmount,ItemBaseType)],Item)]
|
||||||
itemCombinations =
|
itemCombinations =
|
||||||
[ po [PIPE, HARDWARE] (bangStick 1)
|
[ po [PIPE, HARDWARE] (bangStick 1)
|
||||||
, po [BANGSTICK 1, TIN] pistol
|
, po [BANGSTICK 1, TIN] pistol
|
||||||
|
|||||||
@@ -213,6 +213,23 @@ inventoryX c = case c of
|
|||||||
, makeTypeCraftNum 1 DRUM
|
, makeTypeCraftNum 1 DRUM
|
||||||
, makeTypeCraftNum 1 MOTOR
|
, makeTypeCraftNum 1 MOTOR
|
||||||
]
|
]
|
||||||
|
'F' ->
|
||||||
|
[ makeTypeCraftNum 5 PIPE
|
||||||
|
, makeTypeCraftNum 5 TUBE
|
||||||
|
, makeTypeCraftNum 5 HARDWARE
|
||||||
|
, makeTypeCraftNum 5 TIN
|
||||||
|
, makeTypeCraftNum 5 CAN
|
||||||
|
, makeTypeCraftNum 5 SPRING
|
||||||
|
, makeTypeCraftNum 5 PUMP
|
||||||
|
, makeTypeCraftNum 5 MAGNET
|
||||||
|
, makeTypeCraftNum 5 PLANK
|
||||||
|
, makeTypeCraftNum 5 PLATE
|
||||||
|
, makeTypeCraftNum 5 DRUM
|
||||||
|
, makeTypeCraftNum 5 MOTOR
|
||||||
|
, makeTypeCraftNum 5 TRANSFORMER
|
||||||
|
, makeTypeCraftNum 5 PRISM
|
||||||
|
, makeTypeCraftNum 5 LIGHTER
|
||||||
|
]
|
||||||
_ -> []
|
_ -> []
|
||||||
|
|
||||||
testInventory :: IM.IntMap Item
|
testInventory :: IM.IntMap Item
|
||||||
|
|||||||
+5
-1
@@ -22,7 +22,9 @@ module Dodge.Data
|
|||||||
, module Dodge.Config.Data
|
, module Dodge.Config.Data
|
||||||
, module Dodge.Equipment.Data
|
, module Dodge.Equipment.Data
|
||||||
, module MaybeHelp
|
, module MaybeHelp
|
||||||
|
, module Dodge.Data.ItemAmount
|
||||||
) where
|
) where
|
||||||
|
import Dodge.Data.ItemAmount
|
||||||
import Dodge.ShortShow
|
import Dodge.ShortShow
|
||||||
import Dodge.Creature.State.Data
|
import Dodge.Creature.State.Data
|
||||||
import Dodge.Creature.Stance.Data
|
import Dodge.Creature.Stance.Data
|
||||||
@@ -469,6 +471,8 @@ data Equipment = Equipment
|
|||||||
|
|
||||||
_itUseAimStance :: Item -> AimStance
|
_itUseAimStance :: Item -> AimStance
|
||||||
_itUseAimStance = _aimStance . _useAim . _itUse
|
_itUseAimStance = _aimStance . _useAim . _itUse
|
||||||
|
|
||||||
|
|
||||||
data ItemConsumption
|
data ItemConsumption
|
||||||
= LoadableAmmo
|
= LoadableAmmo
|
||||||
{ _laType :: AmmoType
|
{ _laType :: AmmoType
|
||||||
@@ -483,7 +487,7 @@ data ItemConsumption
|
|||||||
, _wpCharge :: Int
|
, _wpCharge :: Int
|
||||||
}
|
}
|
||||||
| ItemItselfConsumable
|
| ItemItselfConsumable
|
||||||
{ _itAmount :: Int
|
{ _icAmount :: IcAmount
|
||||||
}
|
}
|
||||||
| NoConsumption
|
| NoConsumption
|
||||||
data Item = Item
|
data Item = Item
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
module Dodge.Data.ItemAmount where
|
||||||
|
|
||||||
|
newtype IcAmount = IcAmount {_toInt :: Int}
|
||||||
|
deriving (Eq,Ord,Num,Integral,Real,Enum)
|
||||||
|
instance Show IcAmount where
|
||||||
|
show (IcAmount i) = 'x':show i
|
||||||
@@ -167,7 +167,7 @@ defaultItZoom :: ItZoom
|
|||||||
defaultItZoom = ItZoom 20 0.2 1
|
defaultItZoom = ItZoom 20 0.2 1
|
||||||
defaultConsumable :: Item
|
defaultConsumable :: Item
|
||||||
defaultConsumable = defaultItem
|
defaultConsumable = defaultItem
|
||||||
{ _itConsumption = ItemItselfConsumable {_itAmount = 1}
|
{ _itConsumption = ItemItselfConsumable {_icAmount = 1}
|
||||||
, _itInvColor = blue
|
, _itInvColor = blue
|
||||||
, _itDimension = defItDimCol blue
|
, _itDimension = defItDimCol blue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ basicItemDisplay it = Prelude.take (itSlotsTaken it) $
|
|||||||
Nothing' -> show (_laLoaded am)
|
Nothing' -> show (_laLoaded am)
|
||||||
Just' x -> show x ++ "R" ++ show (_laLoaded am)
|
Just' x -> show x ++ "R" ++ show (_laLoaded am)
|
||||||
Just am@ChargeableAmmo{} -> show $ _wpCharge am
|
Just am@ChargeableAmmo{} -> show $ _wpCharge am
|
||||||
Just x@ItemItselfConsumable{} -> "x" ++ show (_itAmount x)
|
Just x@ItemItselfConsumable{} -> show (_icAmount x)
|
||||||
Just NoConsumption -> ""
|
Just NoConsumption -> ""
|
||||||
Nothing -> ""
|
Nothing -> ""
|
||||||
theparam = fromMaybe []
|
theparam = fromMaybe []
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ copyItemToFloorID pos it w = (,) flid $ w'
|
|||||||
_ -> id
|
_ -> id
|
||||||
flid = IM.newKey $ _floorItems w
|
flid = IM.newKey $ _floorItems w
|
||||||
theflit = FlIt
|
theflit = FlIt
|
||||||
{_flIt = it & itConsumption . itAmount %~ const 1
|
{_flIt = it & itConsumption . icAmount %~ const 1
|
||||||
,_flItPos = p'
|
,_flItPos = p'
|
||||||
,_flItRot = rot
|
,_flItRot = rot
|
||||||
,_flItID = flid
|
,_flItID = flid
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ rmInvItem :: Int -- ^ Creature id
|
|||||||
-> Int -- ^ Inventory position
|
-> Int -- ^ Inventory position
|
||||||
-> World
|
-> World
|
||||||
-> World
|
-> World
|
||||||
rmInvItem cid invid w = case w ^? creatures . ix cid . crInv . ix invid . itConsumption . itAmount of
|
rmInvItem cid invid w = case w ^? creatures . ix cid . crInv . ix invid . itConsumption . icAmount of
|
||||||
Just x | x > 1 -> w & creatures . ix cid . crInv . ix invid . itConsumption . itAmount %~ subtract 1
|
Just x | x > 1 -> w & creatures . ix cid . crInv . ix invid . itConsumption . icAmount %~ subtract 1
|
||||||
_ -> w & creatures . ix cid . crInv %~ f
|
_ -> w & creatures . ix cid . crInv %~ f
|
||||||
& creatures . ix cid . crInvSel %~ g
|
& creatures . ix cid . crInvSel %~ g
|
||||||
& creatures . ix cid . crLeftInvSel %~ g'
|
& creatures . ix cid . crLeftInvSel %~ g'
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ putItemInInvID cid flid w = fromMaybe w
|
|||||||
$ tryPutItemInInv cid (_floorItems w IM.! flid) w
|
$ tryPutItemInInv cid (_floorItems w IM.! flid) w
|
||||||
|
|
||||||
putItemInInvSlot :: Int -> Item -> IM.IntMap Item -> IM.IntMap Item
|
putItemInInvSlot :: Int -> Item -> IM.IntMap Item -> IM.IntMap Item
|
||||||
putItemInInvSlot = IM.insertWith (const $ itConsumption . itAmount +~ 1)
|
putItemInInvSlot = IM.insertWith (const $ itConsumption . icAmount +~ 1)
|
||||||
|
|
||||||
{- | Pick up a specific item. -}
|
{- | Pick up a specific item. -}
|
||||||
tryPutItemInInv :: Int -> FloorItem -> World -> Maybe World
|
tryPutItemInInv :: Int -> FloorItem -> World -> Maybe World
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import Control.Lens
|
|||||||
--import Data.Maybe
|
--import Data.Maybe
|
||||||
|
|
||||||
itSlotsTaken :: Item -> Int
|
itSlotsTaken :: Item -> Int
|
||||||
itSlotsTaken it = case it ^? itConsumption . itAmount of
|
itSlotsTaken it = case it ^? itConsumption . icAmount of
|
||||||
Nothing -> moduleSizes it + ceiling (_itInvSize it)
|
Nothing -> moduleSizes it + ceiling (_itInvSize it)
|
||||||
Just i -> moduleSizes it + ceiling (_itInvSize it * fromIntegral i)
|
Just i -> moduleSizes it + ceiling (_itInvSize it * fromIntegral i)
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ import Dodge.Data
|
|||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
itStackAmount :: Item -> Int
|
itStackAmount :: Item -> IcAmount
|
||||||
itStackAmount it = fromMaybe 1 $ it ^? itConsumption . itAmount
|
itStackAmount it = fromMaybe 1 $ it ^? itConsumption . icAmount
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ makeTypeCraftNum :: Int -> ItemBaseType -> Item
|
|||||||
makeTypeCraftNum i ct = defaultCraftable
|
makeTypeCraftNum i ct = defaultCraftable
|
||||||
{ _itInvSize = 0.5
|
{ _itInvSize = 0.5
|
||||||
, _itCurseStatus = Uncursed
|
, _itCurseStatus = Uncursed
|
||||||
, _itConsumption = ItemItselfConsumable i
|
, _itConsumption = ItemItselfConsumable $ IcAmount i
|
||||||
}
|
}
|
||||||
& itType . iyBase .~ ct
|
& itType . iyBase .~ ct
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,11 @@ multiLookupTrie xs t@(Trie my ch)
|
|||||||
case M.lookup z ch of
|
case M.lookup z ch of
|
||||||
Nothing -> multiLookupTrie zs t
|
Nothing -> multiLookupTrie zs t
|
||||||
Just t' -> map (_1 %~ (z:)) (multiLookupTrie zs t') ++ multiLookupTrie zs t
|
Just t' -> map (_1 %~ (z:)) (multiLookupTrie zs t') ++ multiLookupTrie zs t
|
||||||
|
|
||||||
|
multiLookupTrieI :: Ord a => [(a,c)] -> Trie a b -> [([c],b)]
|
||||||
|
multiLookupTrieI xs t@(Trie my ch)
|
||||||
|
| null xs || null ch = maybe [] (\y -> [([],y)]) my
|
||||||
|
| otherwise = let ((z1,z2):zs) = xs in
|
||||||
|
case M.lookup z1 ch of
|
||||||
|
Nothing -> multiLookupTrieI zs t
|
||||||
|
Just t' -> map (_1 %~ (z2:)) (multiLookupTrieI zs t') ++ multiLookupTrieI zs t
|
||||||
|
|||||||
Reference in New Issue
Block a user