Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Organizing ArrayLists for item lists?  (Read 4227 times)
0 Members and 1 Guest are viewing this topic.
Offline SkyAphid
« Posted 2012-03-07 03:04:55 »

I need a good way to organize an ArrayList full of single items, so that I can draw it like this:

Bandaid x 3
Sword x 3
Shield x 2

Instead of this:
Bandaid
Bandaid
Bandaid
Sword
Sword
Sword
Shield
Shield

Any ideas? I tried placing them in a normal array. It went terrible. I'm relatively new to Java still too, so I may not be aware of fancier ways of doing this.
Thanks!

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline UprightPath
« Reply #1 - Posted 2012-03-07 03:15:14 »

The way I'd do it? I don't know! Several. Heh. Ahem.

One way. Create an ItemStack class, that holds a reference to the item object, then a number of. Give it a split method, a combine method, etc. When you receive an item, check if you have an ItemStack for it, whether you're at the maximum number in the stack, then react accordingly.

Another way. Keep the List. However, when you're iterating through it, generate a secondary list, that holds the 'itemName x Number' string. If the list is sorted, then you just keep a count of the items until they change type, then add that string to your list.

Another way. If you can't have multiple stacks you can have a HashSet<Item, Integer> and use that to manage your item list, instead of an ArrayList.

Offline Geemili

Senior Duke


Medals: 9
Projects: 1
Exp: 2 years


No Games Finished


« Reply #2 - Posted 2012-03-07 03:33:28 »

I think you should make something called an item stack.  Then, each time you add an item, you loop through the ArrayList until you find an item stack of the your item. If there is one, add one to the amount in the item stack. If not, create a new item stack.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public void addItem(Item item) {
    for(ItemStack i: inventory) {
        if(item == i.item()) {
            i.add(); //You could have a parameter, but it is not necessary, as an itemstack will contain only one type of item
            break;
        }
    }

    inventory.add(new ItemStack(item));
}


That was a code I thought up of right on the spot. I wouldn't expect it to work.

[Edit] Ninja'd
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Cero
« Reply #3 - Posted 2012-03-07 03:37:57 »

normally you would have an inventory where every item has a number of how much

apple 3

but this assumes that all Bandaids are the same
there are games in which every weapon for example has unique stats
so a broad sword with 5 strength is obviously not the same as one with 3

in that case you can still say broad sword (3), displaying wise, but need unique objects
if items can be unique, the type of the item, here: broad sword, would have an ID and you group them for a list which you draw

all depends on how you plan on showing this infos to the player

Offline SkyAphid
« Reply #4 - Posted 2012-03-07 04:15:04 »

The way I'd do it? I don't know! Several. Heh. Ahem.

One way. Create an ItemStack class, that holds a reference to the item object, then a number of. Give it a split method, a combine method, etc. When you receive an item, check if you have an ItemStack for it, whether you're at the maximum number in the stack, then react accordingly.

Another way. Keep the List. However, when you're iterating through it, generate a secondary list, that holds the 'itemName x Number' string. If the list is sorted, then you just keep a count of the items until they change type, then add that string to your list.

Another way. If you can't have multiple stacks you can have a HashSet<Item, Integer> and use that to manage your item list, instead of an ArrayList.
A hashset sounds good. Thanks! If I need more help, I'll let you guys know!

EDIT!
So I messed with hashsets, but I have no idea how to get data from it. lol. Can someone explain? I add in the elements, then I can check if an element is there...but then what?

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline Stranger

Senior Duke


Medals: 7



« Reply #5 - Posted 2012-03-07 07:30:06 »

Another way. If you can't have multiple stacks you can have a HashSet<Item, Integer> and use that to manage your item list, instead of an ArrayList.
A hashset sounds good. Thanks! If I need more help, I'll let you guys know!

EDIT!
So I messed with hashsets, but I have no idea how to get data from it. lol. Can someone explain? I add in the elements, then I can check if an element is there...but then what?

it's meant HashMap<Item, Integer>. You can put into and get data from it.
If order of  insertion is important you may use LinkedHashMap.

Anton
Offline UprightPath
« Reply #6 - Posted 2012-03-07 07:57:49 »

Merph! HashMap is what I meant. HashSet is basically a set that's meant to ensure uniqueness. If you add the same item twice, it'll only be in the collection once.

HashMap is a mapping, based on the hash of the Key, to a value. Think of it like the Key being an index in an array. It's easier that way.

The HashSet can be used with the ItemStack class to ensure that there's only one of each object in a list. Stuff like that.

Edited to fix the bad tags.

Offline Roquen
« Reply #7 - Posted 2012-03-07 08:59:18 »

If a given item is stackable, then that means that an individual one doesn't have any item specific state (every item is simply a copy of it's archtype).  In that case I'd simply have a count associated with a given instance of an item.
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #8 - Posted 2012-03-07 18:06:29 »

If a given item is stackable, then that means that an individual one doesn't have any item specific state (every item is simply a copy of it's archtype).  In that case I'd simply have a count associated with a given instance of an item.

Not always...

One common feature is 'cursed' items. Usually you want these to look as identical as possible to an uncursed version, until you identify that it's cursed somehow (eg. by equipping it, or paying for it to be identified). In this case you *do* want it to stack otherwise it's a dead giveaway that your shiny new sword is a bit suspect.

Similarly, you might have two different 'special' items (say, acid sword and fire sword) but both are picked up as 'unidentified sword' and stack together, and only unstack when you've identified one or both of them.

The way I solved it was for my item class to be aware of stacking:
1  
2  
3  
4  
5  
6  
interface Item
{
  public boolean tryStack(Item other); // returns true if successfully stacked
  public int getCount(); // stack size (1 if single item)
  public Item split(int splitCount); // split a stacked item into two stacks (say, splitting a pile of coins)
}


Internally each item class handles it's own stacking checking. Simple items (like coins and arrows) just check the object types and merge. Items with different states (cursed items) are held in a separate internal list. So a big stack might be represented as Sword with a count of 10, and an internal arraylist of other Sword-derived classes.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline sproingie

JGO Kernel


Medals: 202



« Reply #9 - Posted 2012-03-07 18:12:31 »

Your typical cursed item is often magical and distinct in some fashion anyhow, so you could also just make unidentified items not stack.  But otherwise, there's a good point -- even mundane items may have different properties such as wear. 

You should probably differentiate between items that are actually found in quantity, such as torches, crossbow bolts, and gold coins, and items that you just want to collapse into a stack purely as a UI thing when displaying an inventory.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #10 - Posted 2012-03-07 18:20:30 »

Your typical cursed item is often magical and distinct in some fashion anyhow, so you could also just make unidentified items not stack.


You could do, but IMHO it's really handy to support 'mixed' stacks that look like a uniform stack to the player. Another good usage would be items with a 'wearLevel' stat (ie. weapons that degrade over use and must be repaired). You want your vanilla items to stack even though they might have slightly different repair levels.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline sproingie

JGO Kernel


Medals: 202



« Reply #11 - Posted 2012-03-07 18:30:22 »

You're absolutely right, which is why heterogeneous stacking should be strictly a UI thing, allowing players to drill down and expand a stack into individual items if they want.  Homogeneous stacks like gold don't need that kind of detail.
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #12 - Posted 2012-03-07 19:32:56 »

That'd be an interesting way of dealing with the two different ways of stacking. I'd worry about having the stacking code not all in one place but that can probably be worked around easily enough.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Roquen
« Reply #13 - Posted 2012-03-08 13:41:04 »

I'm not seeing any added fun-factor here.  Needing to dig through a stacked daggers UI element to find my "insto-kill fuzzy bunny dagger, +13" sounds like an extra pain.  Also, from a perception standpoint, if you have a 'stack' of something it's implying non-uniqueness of the items...even if they are different.  This also implies that the visual representation (at least in a container) of given set of stackable items are all the same.  Which also hurt the player's perception of difference.  Or showing the one at the top (cursor position, whatever) which is kind-of confusing when scanning one's inventory.  So, I'm not seeing how this could be made to increase the fun-factor.

(edit: spelling)
Offline sproingie

JGO Kernel


Medals: 202



« Reply #14 - Posted 2012-03-08 16:10:32 »

One presumes stacking is for items that are undifferentiated by criteria that matter to the player.  It's not fun scrolling through large inventories.

Actually I'm not too big on the whole Player As Pack Mule thing.  One only carries around that much loot to sell, and the whole shopping economy of old school RPGs is a tedious affair that really needs to be streamlined.
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #15 - Posted 2012-03-08 16:29:42 »

I'm not seeing any added fun-factor here.  Needing to dig through a stacked daggers UI element to find my "insto-kill fuzzy bunny dagger, +13" sounds like an extra pain.

Heterogeneous stacking is only for attributes that don't matter to the player (ie. I don't care that one Iron Sword is at 100% repair, and the other at 98% repair) or are not visible to the player. The user should see a stack of 'unidentified sword x3', but actually unstacking one and wielding it is going to be a bit of a lottery.

Bonus points if your identification system allows you to incrementally learn about objects by wielding them rather than just being a binary switch from 'unidentified' to knowing it's complete life story.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Roquen
« Reply #16 - Posted 2012-03-08 16:52:06 »

On the whole I prefer the "every item is unique" school except basics like consumables, raw materials, etc. etc. Which are about the only things I'd want to stack.  But then again some of the Zeldas and The Secret of Mana are excellent, so go figure.

Quote
Bonus points if your identification system allows you to incrementally learn about objects by wielding them rather than just being a binary switch from 'unidentified' to knowing it's complete life story.
Yes! Learn as you go.  I also quite like hidden mechanic.
Offline SkyAphid
« Reply #17 - Posted 2012-03-10 00:27:55 »

If a given item is stackable, then that means that an individual one doesn't have any item specific state (every item is simply a copy of it's archtype).  In that case I'd simply have a count associated with a given instance of an item.

Not always...

One common feature is 'cursed' items. Usually you want these to look as identical as possible to an uncursed version, until you identify that it's cursed somehow (eg. by equipping it, or paying for it to be identified). In this case you *do* want it to stack otherwise it's a dead giveaway that your shiny new sword is a bit suspect.

Similarly, you might have two different 'special' items (say, acid sword and fire sword) but both are picked up as 'unidentified sword' and stack together, and only unstack when you've identified one or both of them.

The way I solved it was for my item class to be aware of stacking:
1  
2  
3  
4  
5  
6  
interface Item
{
  public boolean tryStack(Item other); // returns true if successfully stacked
  public int getCount(); // stack size (1 if single item)
  public Item split(int splitCount); // split a stacked item into two stacks (say, splitting a pile of coins)
}


Internally each item class handles it's own stacking checking. Simple items (like coins and arrows) just check the object types and merge. Items with different states (cursed items) are held in a separate internal list. So a big stack might be represented as Sword with a count of 10, and an internal arraylist of other Sword-derived classes.

Could you possibly go into more detail on how the actual stacking would work in a more detailed conceptual way? I'd appreciate it, I like your idea.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #18 - Posted 2012-03-11 11:19:43 »

Could you possibly go into more detail on how the actual stacking would work in a more detailed conceptual way? I'd appreciate it, I like your idea.

So I went back and dug into the code in Albion to remind myself how I did it, and lo and behold I'd ripped up my original version and done it (almost) how sproingie said - homogeneous stacking is done within each Item (using that interface above) and heterogeneous stacking is handled in the UI layer. (Actually it's done in a 'perception' layer which filters raw inventory into something the UI can do, but that's just so that all UI code can use the same filtering code).

The actual homogeneous stacking is done in the inventory:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
   /** Adds the item to the inventory
    *  Returns true if the item was merged/stacked with an existing item
    */

   public boolean addItem(Item newItem)
   {
      // First check if we can hard stack with any existing items
      boolean wasStacked = false;
     
      for (Item existingItem : items)
      {
         if (existingItem.tryStack(newItem))
         {
            wasStacked = true;
            break;
         }
      }
     
      // Can't hard stack, so we'll just add the item directly
      if (!wasStacked)
         items.add(newItem);
     
      return wasStacked;
   }


Removing an item is pretty easy too:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
   public Item removeCount(Item existingItem, final int count)
   {
      assert (items.contains(existingItem));
     
      if (existingItem.getCount() > count)
      {
         Item unstacked = existingItem.split(1);
         return unstacked;
      }
      else if (existingItem.getCount() == count)
      {
         removeItem(existingItem);
         return existingItem;
      }
      else
      {
         // Oh noes! Tried to split a stack but stack isn't big enough
         assert (false);
         return null;
      }
   }


This is (conceptually) just a way of making an inventory of 1000 gold coins actually represented by one Coin object with an internal 'count' of 1000, rather than 1000 individual Coin objects. tryStack() is implemented for each item type, and (usually) just checks if the two objects are the same object type, then increments an internal counter.

The perception filter for the UI just runs through all items in a list and produces a Description of each item based on the current character's stats. A Description is basically image+name+description. Items which produce identical Descriptions are 'soft' stacked together ( Map<Description, ArrayList<Item>>) for the ui to use. Any ui command which operates on one of these lists (eg. equip) randomly operates on one of the items within it.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline sproingie

JGO Kernel


Medals: 202



« Reply #19 - Posted 2012-03-11 18:37:23 »

Ooh, I like how the UI is generated by the character's stats.  So if I have an INT of 3, I could get:

You gots:

* 2 clubby things
* 3 stabby things.  One of them is real shiny.
* More than 3 drinky things
* More than 3 shiny spendy things.  They almost fill one human skull.

Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 136
Projects: 4
Exp: 3 years



« Reply #20 - Posted 2012-03-11 19:19:01 »

ArrayList of ArrayLists! e.g.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
ArrayList<ArrayList> list = new ArrayList<Type>();
ArrayList<Bandaid> bandaidList = new ArrayList<Type>();
ArrayList<Sword> swordList = new ArrayList<Type>();
ArrayList<Shield> shieldList = new ArrayList<Type>();
...
void codeHere(){
...
list.add(bandaidList);
//etc.


}
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #21 - Posted 2012-03-11 20:50:07 »

Ooh, I like how the UI is generated by the character's stats.  So if I have an INT of 3, I could get:

You gots:

* 2 clubby things
* 3 stabby things.  One of them is real shiny.
* More than 3 drinky things
* More than 3 shiny spendy things.  They almost fill one human skull.



Haha, it doesn't got that far, but that would be great! It'd certainly stop people using intelligence and lore as dump stats. Smiley

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (43 views)
2014-10-16 15:22:06

Norakomi (33 views)
2014-10-16 15:20:20

lcass (37 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (67 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (86 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!