@@ -6,8 +6,9 @@ use crate::randomizer::Randomizer;
66use serde:: { Deserialize , Serialize } ;
77use std:: collections:: HashMap ;
88
9- /// The tombstone is a bag of items left at the hero's dying location.
10- /// When the next hero visits that location, it can pick up the items.
9+ /// A chest is a bag of items that can be picked up by the hero.
10+ /// It can randomly appear at a location upon inspection, or dropped
11+ /// by the hero when they die.
1112#[ derive( Serialize , Deserialize ) ]
1213pub struct Chest {
1314 items : HashMap < String , Vec < Box < dyn Item > > > ,
@@ -98,13 +99,37 @@ impl Chest {
9899 game. gold += self . gold ;
99100 ( to_log, self . gold )
100101 }
102+
103+ /// Add the elements of `other` to this chest
104+ pub fn extend ( & mut self , mut other : Self ) {
105+ // keep the best of each equipment
106+ if let Some ( sword) = other. sword . take ( ) {
107+ if sword. is_upgrade_from ( & self . sword . as_ref ( ) ) {
108+ self . sword = Some ( sword) ;
109+ }
110+ }
111+
112+ if let Some ( shield) = other. shield . take ( ) {
113+ if shield. is_upgrade_from ( & self . shield . as_ref ( ) ) {
114+ self . shield = Some ( shield) ;
115+ }
116+ }
117+
118+ // merge both item maps
119+ for ( key, other_items) in other. items . drain ( ) {
120+ let self_items = self . items . entry ( key) . or_default ( ) ;
121+ self_items. extend ( other_items) ;
122+ }
123+
124+ self . gold += other. gold ;
125+ }
101126}
102127
103128#[ cfg( test) ]
104129mod tests {
105130 use super :: * ;
106131 use crate :: item:: equipment:: { Shield , Sword } ;
107- use crate :: item:: Potion ;
132+ use crate :: item:: { Escape , Potion } ;
108133
109134 #[ test]
110135 fn test_empty_drop_pickup ( ) {
@@ -180,4 +205,36 @@ mod tests {
180205
181206 assert_eq ! ( 3 , * game. inventory( ) . get( "potion" ) . unwrap( ) ) ;
182207 }
208+
209+ #[ test]
210+ fn test_merge ( ) {
211+ let potions: Vec < Box < dyn Item > > = vec ! [ Box :: new( Potion :: new( 1 ) ) , Box :: new( Potion :: new( 1 ) ) ] ;
212+ let mut items = HashMap :: new ( ) ;
213+ items. insert ( "potion" . to_string ( ) , potions) ;
214+ let mut chest1 = Chest {
215+ items,
216+ sword : Some ( Sword :: new ( 1 ) ) ,
217+ shield : Some ( Shield :: new ( 10 ) ) ,
218+ gold : 100 ,
219+ } ;
220+
221+ let potions: Vec < Box < dyn Item > > = vec ! [ Box :: new( Potion :: new( 1 ) ) ] ;
222+ let escapes: Vec < Box < dyn Item > > = vec ! [ Box :: new( Escape :: new( ) ) ] ;
223+ let mut items = HashMap :: new ( ) ;
224+ items. insert ( "potion" . to_string ( ) , potions) ;
225+ items. insert ( "escape" . to_string ( ) , escapes) ;
226+ let chest2 = Chest {
227+ items,
228+ sword : Some ( Sword :: new ( 10 ) ) ,
229+ shield : Some ( Shield :: new ( 1 ) ) ,
230+ gold : 100 ,
231+ } ;
232+
233+ chest1. extend ( chest2) ;
234+ assert_eq ! ( 200 , chest1. gold) ;
235+ assert_eq ! ( 10 , chest1. sword. as_ref( ) . unwrap( ) . level( ) ) ;
236+ assert_eq ! ( 10 , chest1. shield. as_ref( ) . unwrap( ) . level( ) ) ;
237+ assert_eq ! ( 3 , chest1. items. get( "potion" ) . unwrap( ) . len( ) ) ;
238+ assert_eq ! ( 1 , chest1. items. get( "escape" ) . unwrap( ) . len( ) ) ;
239+ }
183240}
0 commit comments