Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Edit: I got a working version using an ArrayList

void addItem(Item item, int count){

        int stacks;

        for (int i = 0; i < useableSlots && count != 0; i++){
            if (itemSlot[i].stack.size() > 0){
                if (itemSlot[i].stack.get(0) == item) {
                    if(itemSlot[i].stack.size() < item.stackLimit){

                        int n = itemSlot[i].stack.size();

                        for(; n < item.stackLimit && count > 0; count--, n++) {
                            itemSlot[i].stack.add(item);
                        }
                    }
                }
            }
            if (i == (useableSlots - 1) && count > 0){
                for(int n = 0; n < useableSlots && count != 0; n++){

                    stacks = ((count - (count % item.stackLimit)) / item.stackLimit);

                    if(itemSlot[n].occupied == false){
                        if(stacks == 0){
                            for(int j = 0; j < count; j++){
                                itemSlot[n].stack.add(item);
                                itemSlot[n].occupied = true;
                            }
                            count = 0;
                        }
                        else {
                            for(int j = 0; j < item.stackLimit; j++){
                                itemSlot[n].stack.add(item);
                            }
                            count -= item.stackLimit;
                            itemSlot[n].occupied = true;
                        }
                    }
                    if (n == (useableSlots - 1)){
                        println("You don't have any room in your inventory");
                    }
                }
            }
        }
    }

.

package com.projects.aoa;

import java.util.*;

public class Itemslot extends Item{

    List<Item> stack = new ArrayList<Item>();
    Item oi = new Item();
    boolean occupied, isArray, full;

}

.

public class Inventory {

    int useableSlots, slots = 50;
    Itemslot[] itemSlot = new Itemslot[slots];


...}

I have an inventory made up of an array of Item objects. I'm trying to have like items stack up to a certain limit before taking up another inventory space. I must be going about this the complete wrong way, because I've had the same problem for every on of my attempts. The hp potion stackLimit is 25, (27 hpPotions would take two inventory spaces, one with 25 the other with 2.)

Main

playerOne.backPack.addItem(hpPotion, 20);
playerOne.backPack.printInventory();
playerOne.backPack.addItem(hpPotion, 15);
playerOne.backPack.printInventory();

Item.java

package com.projects.aoa;

import static com.projects.aoa.Print.*;

import java.util.*;
import java.io.*;

class Item {

//Item
String name, type, category;
int id;
int hp, mp, str, def, duration;

//Inventory
public boolean filled;
public int count, stackLimit;

static void getAllStats(Item[] e){
    for(Item i : e){
        getItemStats(i);
    }
}

static void getItemStats(Item i){
    i.getStats();
}

void getStats(){
    try {
        //System.out.println(System.getProperty("user.dir"));

        FileInputStream fstream = new FileInputStream(System.getProperty("user.dir") 
                + "/src/com/projects/aoa/" + this.type + "_" + this.name + ".txt");

        DataInputStream in = new DataInputStream(fstream);

        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        String line;
        int counter = 0;

        while ((line = br.readLine()) != null) {
            if (line.length() == 0){
                break;
            }

            switch (counter) {
            case 0:
                this.hp = Integer.parseInt(line);
                counter++;
                break;
            case 1:
                this.mp = Integer.parseInt(line);
                counter++;
                break;
            case 2:
                this.def = Integer.parseInt(line);
                counter++;
                break;
            case 3:
                this.str = Integer.parseInt(line);
                counter++;
                break;
            case 4:
                this.stackLimit = Integer.parseInt(line);
                counter++;
                break;
            case 5:
                this.duration = Integer.parseInt(line);
                counter++;
                break;
            }   
        }


        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

void printStats(){
    println("[" + name + "]");
    println("Type: " + type);
    println("Duration: " + duration);
    println("HP:  " + hp);
    println("MP:  " + mp);
    println("Def: " + def);
    println("Str: " + str);
}
}

Inventory Output: 3rd Attempt

addItem(hpPotion, 20);

[1]  Mallet              [2]  BronzeHelmet        [3]  hpPotion(20)        [4]  Empty               [5]  Empty               

[6]  Empty               [7]  Empty               [8]  Empty               [9]  Empty               [10] Empty               

[11] Empty               [12] Empty               [13] Empty               [14] Empty               [15] Empty               

[16] Empty               [17] Empty               [18] Empty               [19] Empty               [20] Empty  

addItem(hpPotion, 15);

[1]  Mallet              [2]  BronzeHelmet        [3]  hpPotion(10)        [4]  hpPotion(10)        [5]  Empty               

[6]  Empty               [7]  Empty               [8]  Empty               [9]  Empty               [10] Empty               

[11] Empty               [12] Empty               [13] Empty               [14] Empty               [15] Empty               

[16] Empty               [17] Empty               [18] Empty               [19] Empty               [20] Empty 

This same thing happens in the Second attempt, except it shows up adding the two

[3]  hpPotion(35)        [4]  hpPotion(35)

It seems like it would just be a simple fix (and maybe it is), but I just have no clue what it could be. Any help would be appreciated.

Third Attempt

void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    for(int i = 0; i < 20; i++){
        if(itemSlot[i] == item && count > 0){
            room = (item.stackLimit - itemSlot[i].count);
            if(room > 0){
                if(count >= room){
                    itemSlot[i].count += room;
                    count -= room;
                }
                else if(count > 0 && count < room){
                    itemSlot[i].count += count;
                    count = 0;
                    break;
                }
            }
        }

        if(i >= 19 && count > 0){
            for(int n = 0; n < 20; n++){
                if(itemSlot[n].filled == false){
                    int stacks = ((count - (count % item.stackLimit)) / 25);
                    println(stacks);
                    if (stacks == 0){
                        itemSlot[n] = item;
                        itemSlot[n].filled = true;
                        itemSlot[n].count = count;
                        count = 0;
                        break;
                    }
                    else {
                        itemSlot[n] = item;
                        itemSlot[n].filled = true;
                        itemSlot[n].count = item.stackLimit;
                        count -= item.stackLimit;
                    }
                }
            }
        }
    }
}

Second Attempt

    void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    outerLoopCurrentStack:
    for(int i = 0; i < 20; i++) {
        if(itemSlot[i].name == item.name){
            if(itemSlot[i].count < itemSlot[i].stackLimit){

                while(count > 0){
                    count--;
                    itemSlot[i].count++;

                    if(itemSlot[i].count == itemSlot[i].stackLimit) {
                        break outerLoopCurrentStack;
                    }
                }
            }
        }
        else if((i >= 19) && (count > 0)){
            newStack = true;
        }
    }

    if(newStack = true){

        outerLoopNewStack:
        for(int i = 0; i < 20; i++){
            if(itemSlot[i].filled == false){

                itemSlot[i] = item;
                itemSlot[i].filled = true;

                while(count > 0){
                    count--;
                    itemSlot[i].count++;

                    if(count == 0){
                        newItem = false;
                        count = 0;
                        break outerLoopNewStack;
                    }
                }
            }
        }
    }
}
     }  

First Attempt

    void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    for (int i = 0; i < 20; i++){
        if(itemSlot[i].name == item.name) {
            if(itemSlot[i].count < item.stackLimit){
                room = (item.stackLimit - itemSlot[i].count);
                if (count > room){
                    itemSlot[i].count += room;
                    itemSlot[i].filled = true;
                    count -= room;
                }
                else {
                    itemSlot[i].count += count;
                    break;
                }
            }
        }
        else if(i == 19){
            newStack = true;
        }
    }

    if (newStack == true){
        for(int i = 0; i < 20; i++){
             if(itemSlot[i].filled == false) {
                if(count > item.stackLimit){
                    itemSlot[i] = item;
                    itemSlot[i].count = item.stackLimit;
                    itemSlot[i].filled = true;
                    count -= item.stackLimit;
                }
                else{
                    itemSlot[i] = item;
                    itemSlot[i].count = count;
                    itemSlot[i].filled = true;
                    break;
                }
            }
        }
    }
     }
share|improve this question
So let me just clarify, does this mean that you want 1 widget and 20 widgets to count as a single backpack unit, but 21 would overflow to 2 backpack units? Is that correct? – danpalmer Dec 9 '11 at 17:16
@danpalmer Yes, but 26 would make it overflow into 2 stacks (one 25 and the other with 1.) Sorry forgot to mention what the stackLimit is. – iRector Dec 9 '11 at 17:20
this is an interesting problem, I am just doing a pseudo-code mockup now. – danpalmer Dec 9 '11 at 17:22
Sounds good, thank you. – iRector Dec 9 '11 at 17:31
I'm actually not sure why your third attempt isn't working. – AHungerArtist Dec 9 '11 at 17:35
show 2 more comments

3 Answers

up vote 2 down vote accepted

It looks like you're putting the same object into both inventory slots, so when you change the .count member it changes it in both slots.

The first sign is that you're comparing the existing item to the one that gets inserted with ==. When you're overflowing, try changing

itemslot[i] = new Item(item);

instead of

itemslot[i] = item;

Assuming you have a copy constructor.

share|improve this answer
+1 for actually addressing the problem with the current code. – AHungerArtist Dec 9 '11 at 17:59

Look into the Composite Pattern, with an eye of the items being part of the "contents" of the inventory.

Then you can have a bag which is "contained" in the user's contents, while having contents which are contained in the bag.

Top level stuff like calculating weight will sum up the weight of each item in the current container. If that involves asking an item that is a container it's weight, the container-item will calculate it's weight by using the same technique (until eventually non-container items just report back their non-calculated weights).

Either way, you want to get away from arrays for collections that exhibit behavior, as you can't add the behavior into the collection with an array, and having it outside (in a bunch of methods) will eventually make your code hard to maintain / fix / change.

share|improve this answer

Ok, I think there are 2 possible ways of doing this, and I would probably do it the other way.

Alternative Method
I would abstract the backpack mechanics away from the actual data store. I would have either an array, or a dictionary to do this. I would probably use a dictionary to do { item => count }, but I understand this may not be practical if you have particular data stored with each instance of each item.

From this data store, when presenting to the user through an interface, or to other code that might check whether the backpack is full, you can then just iterate over the dictionary generating a running count of how many spaces are taken up. I think this is the best way of doing it.

Edit: I think this method is vaguely speaking, what @EdwinBuck mentioned in his answer.

However, it might not be practical for your application (game) and so I hope the following basic algorithm might help you a bit. I don't know if it works perfectly, and it's probably not massively efficient, but I doubt backpacks would be large enough for that to matter.

def addItem(item, count)

    foreach (slot in backpack)
        if (slot.type = Array<Item>)
            if (slot.count < max)

                // Enough space to add at least one more
                if (count > 1)
                    foreach (count) addItem(item, 1)
                    // yes this is recursive to get the checking
                else
                    slot.add(item)
                end

            else

                // Not enough space, create a new slot
                var newSlot
                backpack.add(newSlot)

                if (count > 1)
                    foreach (count) addItem(item, 1)
                    // yes this is recursive to get the checking
                else
                    newSlot.add(item)
                end 

            end
        end
    end
end
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.