Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (763)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (852)
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  
  How to simplify existing Inventory System?  (Read 2179 times)
0 Members and 1 Guest are viewing this topic.
Offline theOne

Senior Newbie





« Posted 2016-09-24 22:48:04 »

Yeah I try to rewrite my Inventory  Cranky
So far it´s working and passing all Unittests but the more Testcases I find the more I have to rewrite, not the logic part, but the overall Dependencies.

I have an Item class and one Itemstack, which holds one item and it´s amount.
The Inventory is an List of InventorySlot and this InventorySlot holds an Item or an ItemStack.
Especially that InventorySlot can hold both seems to be problematic. Or that now Item needs to have an currentAmount Method only to be able to have it for the ItemStack.
Or ItemStack now has an isEquippable Method etc...

Furthermore I don´t knew yet if I will distinguish different Materials with an enum, with interface or even with ECS Components.

Any idea how to redo my class dependencies?


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
public class MyItem extends AbstractItem {

    public MyItem(String name, int itemId, int maxStackCount) {
        super(name, itemId, maxStackCount);
    }

    public MyItem(String name, int itemId) {
        super(name, itemId);
    }

public class InventorySlot<T extends IItem> {
    public int id;
    private T item;

    public InventorySlot(int id) {
        this.id = id;
    }
    boolean isOccupied() {
        return item != null;
    }
    public void add(T item) {
        this.item = item;
    }
    public T getItem() {
        return this.item;
    }

public abstract class AbstractItem extends AGameObject implements IItem {
    private String name;
    private int itemId,maxStack;
    private boolean isStackable;
   
    AbstractItem(String name, int itemId, int maxStackCount) {
        super();
        this.name = name;
        this.itemId = itemId;
        this.maxStack = maxStackCount;
        if (maxStackCount > 1) this.isStackable = true;
    }

    AbstractItem(String name, int itemId) {
        this(name, itemId, 1);
    }

    //no need for this
    public int getCurrentStackCount() {
        return 1;
    }




1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
public class ItemStack implements IItem {

    long stackId;
    IItem item;
    int currentCount;

    public ItemStack(IItem item) {
        this.item = item;
        this.currentCount = 1;
    }

    @Override
    public void removeAmount(int count) {
        this.remove(count);
    }

    boolean canAdd(IItem item) {
        if (item.equals(item)) {
            return true;
        }
        return false;
    }

    boolean canAdd(ItemStack stack) {
        if (item.equals(stack.item)) {
            return true;
        }
        return false;
    }

    public int getCurrentStackCount() {
        return this.currentCount;
    }

    public boolean add(IItem newItem) {
        //item which wants to be added is not the same as in the stack
        if (!canAdd(item)) return false;

        //this stack is already at maximum Stackvalue
        if (this.currentCount == item.maxStackCount()) return false;
        this.currentCount++;
        return true;
    }

    public ItemStack add(ItemStack stack, int transferCount) {
        return null;
    }

    public ItemStack add(ItemStack stack) {
        return this.add(stack, stack.currentCount);
    }

    boolean remove(int count) {
        if (this.currentCount - count >= 0) {
            this.currentCount -= count;
            return true;
        } else {
            return false;
        }
        //TODO item less or equal than zero
    }

    public long getId() {
        return stackId;
    }

    boolean isEmpty() {
        if (this.currentCount <= 0) return true;
        return false;
    }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
public class Inventory<T extends IItem> {
    Set<InventorySlot> slots = new HashSet<>();
    private int maxSlots;

    public Inventory() {
        this(64, 8, 8);
    }

    public Inventory(int rows, int cols) {
        this.inventoryRows = rows;
        this.inventoryCols = cols;
    }

    public Inventory(int size, int maxRows, int maxCols) {
        maxSlots = size;
        this.maxCols = maxCols;
        this.maxRows = maxRows;
    }

    public boolean add(T item) {  
        InventorySlot freeSlot = findFreeSlot();
        if (freeSlot == null) return false;
        freeSlot.add(item);

        return true;
    }


    /**
     * removes an item ENTIRELY from the Inventory
     *
     * @param item
     */

    public void remove(T item) {
        InventorySlot slot = this.slots.stream().filter(x -> x.getItem().getItemId() == item.getItemId()).findFirst().get();
        slot.add(null);
    }

    /**
     * removes given amount of an item form the Inventory, only works if amount >1
     *
     * @param item
     * @param amount
     */

    public void remove(T item, int amount) {
        InventorySlot slot = this.slots.stream().filter(x -> x.getItem().getItemId() == item.getItemId()).findFirst().orElse(null);
        slot.getItem().removeAmount(amount);
    }

    public InventorySlot getSlotByItem(IItem item) {
        return this.slots.stream().filter(x -> x.getItem().getItemId() == item.getItemId()).findFirst().orElse(null);
    }

    public InventorySlot getSlotAt(int place) {
        return this.slots.stream().filter(x -> x.id == place).findAny().orElse(null);
    }

    private InventorySlot findFreeSlot() {
        InventorySlot freeSlot = this.slots.stream().filter(x -> !x.isOccupied()).findFirst().orElse(null);
        return freeSlot;
    }

    public int getUsedSlots() {
        return (int) this.slots.stream().filter(x -> x.isOccupied()).count();
    }

    public Set<InventorySlot> getItems() {
        return this.slots;
    }


Edit: deleted some unimportant Methods and getter/setter.
btw: Is the Spoiler tag not working?

Edit2: reduced unnecessary Code...
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #1 - Posted 2016-10-05 07:08:17 »

Why do you have abstraction here that goes above what there should be.

An inventory can be as simple as an unordered table of all necessary data.

So I would drop abstraction. I would create a list of all items and load it in. (Yeah don't create 100 item classes please)

1 Dagger
2 Gold
3 Princec's Love For Java
4 Bucket

Then add these to a table. Call it your 'lookup table'. Then you can refer to it like Inventory.isItemWeapon(player_invy.get(0));

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline QuicK2800

Senior Newbie


Medals: 1
Exp: 4 years



« Reply #2 - Posted 2016-12-12 19:15:06 »

@Hydroque has a good solution to this issue.

An aside about software development:

Abstraction is good when dealing with complicated systems and abstract ideas. For something as simple as an inventory, there is no need to abstract this concept further using abstract classes. The same is true for "Item" and "ItemStack". If desired, you can use interfaces to provide a clear and explicit definition of these objects. In the code that you posted, there is a lot of unnecessary abstraction. (Your example actually makes the concepts more difficult to understand)

Combining Hydroque's approach with yours:

All you need are three classes: Item, ItemStack, and Inventory
(giving Inventory its own class will help with abstraction down the road)

Item should contain the basics of what an Item is:
an ID, Title, Description, etc.

There are multiple ways that you could conceptualize your list of Items...
1) Reference a static list of items using aliasing to create instances of particular items (I think Minecraft likes to do things this way, if I remember correctly)
2) Load items from something similar to JSON into a table (Probably only want to mess with this if you're planning a huge project)
3) Enums (blegh)
4) Flyweight or Factory design patterns
5) many many more...

ItemStack should merely be a container for Items:
It should contain what Item it is referring to, how many of that Item, and possibly a maximum stack size for that Item.

Inventory should be a structure that allows for indexing such as a 2-D table.
This structure should only contain ItemStacks, no Items.
It should provide methods to add ItemStacks and remove ItemStacks only.

If you want something that is easily sortable, you could use an ArrayList with a Comparator.
(If this interests you, I could explain this idea further)

When designing systems in the future, try to keep "KISS" in mind. (Keep It Simple, Stupid!). In general, the simpler a solution is, the more elegant it will be and the easier it will be to work with.

Cheers,

-QuicK
Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (541 views)
2018-06-10 19:43:48

EgonOlsen (645 views)
2018-06-10 19:43:44

EgonOlsen (442 views)
2018-06-10 19:43:20

DesertCoockie (788 views)
2018-05-13 18:23:11

nelsongames (1019 views)
2018-04-24 18:15:36

nelsongames (1006 views)
2018-04-24 18:14:32

ivj94 (1587 views)
2018-03-24 14:47:39

ivj94 (559 views)
2018-03-24 14:46:31

ivj94 (1393 views)
2018-03-24 14:43:53

Solater (564 views)
2018-03-17 05:04:08
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
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!