Jump to content

[1.12.2] Comparing ItemStack lists


unassigned

Recommended Posts

Hello, I have two ItemStack lists of the same length (that CAN contain ItemStack.Empty), and I want to compare them and see if they are the same. This list can carry duplicates of items. I have some base functionality working, however, with my current code, all duplicates within the recipe are accounted for as one. For example, one of my recipes require 6x Iron Blocks, and 1x Nether Star, however, if the list has 2x Iron Blocks and the 1x Nether Star, it will run. Here is an example of the lists I am comparing:

Current Items:
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0
0xtile.air@0
1xitem.netherStar@0
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0

Needed Items:
1xitem.netherStar@0
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0
1xtile.blockIron@0
0xtile.air@0

 

Here is the current comparison code I have:

            int matches = 0;
            Iterator<ItemStack> iteratorRecipe = recipeList.iterator();
            for(ItemStack ingredient : infusionItems) {
                while(iteratorRecipe.hasNext()){
                    ItemStack recipeReqire = iteratorRecipe.next();
                    if(ItemStack.areItemStackTagsEqual(recipeReqire, ingredient)){
                        iteratorRecipe.remove();
                        matches++;
                    }
                }
            }

 

And here is the whole method for those who need it:

Spoiler

    public IResourceInfusion getInfusion(){
        ArrayList<ItemStack> infusionItems = new ArrayList<>();

        for(TileVoidInfuser infuser : getInfusersNear()){
            if(infuser.stack() != null) { infusionItems.add(infuser.stack()); }
        }
        if(infusionItems.size() < 8) return null;

        for(ItemStack[] recipe : VoidUtilsAPI.RESOURCE_MODIFIERS.keySet()){
            ArrayList<ItemStack> recipeList = new ArrayList<>(Arrays.asList(recipe));

            while (recipeList.size() < 8) {
                System.out.println("Adding an Empty Stack to the list!");
                ItemStack stack = ItemStack.EMPTY;
                stack.setCount(0);
                recipeList.add(stack);
            }

            System.out.println(recipeList.size());
            System.out.println("Required Items:");
            for(ItemStack stack : recipeList) { System.out.println(stack); }

            System.out.println(infusionItems.size());
            System.out.println("Have Items:");
            for(ItemStack stack : infusionItems) { System.out.println(stack); }

            int matches = 0;
            Iterator<ItemStack> iteratorRecipe = recipeList.iterator();
            for(ItemStack ingredient : infusionItems) {
                while(iteratorRecipe.hasNext()){
                    ItemStack recipeReqire = iteratorRecipe.next();
                    if(ItemStack.areItemStackTagsEqual(recipeReqire, ingredient)){
                        iteratorRecipe.remove();
                        matches++;
                    }
                }
            }

            if(matches == 8) return VoidUtilsAPI.RESOURCE_MODIFIERS.get(recipe);

        }

        return null;
    }

 

 

 

Thanks!

Link to comment
Share on other sites

1 hour ago, unassigned said:

if(ItemStack.areItemStackTagsEqual(recipeReqire, ingredient)){

Tags don’t include size, you also want to check the size/count of the ItemStack. I believe that ItemStack provides you with a method for this but if it doesn’t you can do it yourself with ItemStack#getCount

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

Just now, Cadiboo said:

Tags don’t include size, you also want to check the size/count of the ItemStack. I believe that ItemStack provides you with a method for this but if it doesn’t you can do it yourself with ItemStack#getCount

Well, they are all 1 in size. How this works is that it gets a list of items from surrounding 'infusers', which can only hold one item. So I need to compare the lists against each other, to make sure each element matches (excluding order). However, as standard collection sorting doesn't work on ItemStacks, I'm stumped.

Link to comment
Share on other sites

1 hour ago, unassigned said:

if(infuser.stack() != null)

ItemStacks are never null

 

So it works with this?

Actual Items:
1xitem.netherStar@0
1xtile.blockIron@0
1xtile.blockIron@0
0xtile.air@0
0xtile.air@0
0xtile.air@0
0xtile.air@0
0xtile.air@0

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

3 minutes ago, Cadiboo said:

ItemStacks are never null

  

So it works with this?


Actual Items:
1xitem.netherStar@0
1xtile.blockIron@0
1xtile.blockIron@0
0xtile.air@0
0xtile.air@0
0xtile.air@0
0xtile.air@0
0xtile.air@0

Yes, as long as there are 1 or more nether star and 2 or more iron blocks.

Here is the recipe being registered

Spoiler

        VoidUtilsAPI.addDuplicatableItem(new ItemStack[]{new ItemStack(Items.NETHER_STAR), new ItemStack(Blocks.IRON_BLOCK),
                        new ItemStack(Blocks.IRON_BLOCK), new ItemStack(Blocks.IRON_BLOCK), new ItemStack(Blocks.IRON_BLOCK),
                        new ItemStack(Blocks.IRON_BLOCK), new ItemStack(Blocks.IRON_BLOCK)},
                new ResourceInfusion(new ItemStack(Items.IRON_INGOT), 100000, 0.01f, 5));

 

 

 

Link to comment
Share on other sites

31 minutes ago, vhbob said:

If you iterate through the actual items list and check to see if the recipe list contains that item, and add 1 to the counter, that should work, no?

Well, I have to remove the result, otherwise, it will not know if the duplicate items have been checked, thus 1 item would throw the counter up and return true.

Edited by unassigned
Link to comment
Share on other sites

1 hour ago, diesieben07 said:

Well, first of all, is this is a "shaped" recipe or a "shapeless" one? I.e., does the position of the stacks in the list matter, or not?

 

This is considered a shapless recipe, as the order does not matter. (including within the list)

 

1 hour ago, diesieben07 said:

 Also, do excess input items cause the recipe to fail (e.g.: Input is 3 stone and 1 dirt, recipe is just 2 stone, does it still apply)?

Yes, if there is an item that does not belong, the process should be stopped.

Link to comment
Share on other sites

On 12/31/2018 at 8:05 AM, diesieben07 said:

Okay. Here is your process:

  1. Clone the required ingredient list (deep clone, i.e. you need to clone the stacks within it, too).
  2. Loop through the presented input list:
    1. Try to find a match for the current input stack in the cloned ingredient list and modify the count of the stack in the cloned ingredient list accordingly (i.e. if input stack is 3 Stone and 5 Stone is required, change the 5 to a 2).
    2. If you don't find a match, abort (something was presented that is not required).
  3. After you are done with all presented input the recipe matches if and only if the cloned ingredient lists contains only empty stacks.

Okay, I went against what you said (even though it's probably better) and ended up switching to use ingredients, made an actual class that handles the items, and it is working now. However, I'd like to post my result to see how this can be improved, as I'm sure by the way it looks, there is a better way.

        if (!input.apply(in)) return false;
        List<Ingredient> matches = new ArrayList<>();
        ItemStack[] stacks = { infuser1, infuser2, infuser3, infuser4, infuser5, infuser6, infuser7, infuser8 };
        boolean[] unused = { true, true, true, true, true, true, true, true };
        for (ItemStack s : stacks) {
            if (unused[0] && modifier1.apply(s)) {
                matches.add(modifier1);
                unused[0] = false;
            } else if (unused[1] && modifier2.apply(s)) {
                matches.add(modifier2);
                unused[1] = false;
            } else if (unused[2] && modifier3.apply(s)) {
                matches.add(modifier3);
                unused[2] = false;
            } else if (unused[3] && modifier4.apply(s)) {
                matches.add(modifier4);
                unused[3] = false;
            } else if (unused[4] && modifier5.apply(s)) {
                matches.add(modifier2);
                unused[4] = false;
            } else if (unused[5] && modifier6.apply(s)) {
                matches.add(modifier3);
                unused[5] = false;
            } else if (unused[6] && modifier7.apply(s)) {
                matches.add(modifier4);
                unused[6] = false;
            } else if (unused[7] && modifier8.apply(s)) {
                matches.add(modifier4);
                unused[7] = false;
            }
        }

        return matches.size() == 8;

As I said, I went from supplying an array of ItemStack for the ingredients, to just having 8 separate ingredients and checking them.  

Link to comment
Share on other sites

12 hours ago, unassigned said:

} else if

Dear sweet jebus chritie.

 

DRY!

Fek.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Wouldn't it be amazing if Java had switch statements or loops...

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

12 hours ago, Cadiboo said:

Wouldn't it be amazing if Java had switch statements or loops...

 

On 1/3/2019 at 11:07 AM, Draco18s said:

Dear sweet jebus chritie.

 

DRY!

Fek.

haha, I was just trying to get a visual, I meant to change this with for loop before posting, but I wanted to see if there was anything better functional wise (ex. more optimized). However, for those interested here is what it looks like now:

    public boolean matches(ItemStack in, ItemStack infuser1, ItemStack infuser2, ItemStack infuser3, ItemStack infuser4,
                           ItemStack infuser5,ItemStack infuser6,ItemStack infuser7,ItemStack infuser8){

        if (!input.apply(in)) return false;
        
        List<Ingredient> matches = new ArrayList<>();
        ItemStack[] stacks = { infuser1, infuser2, infuser3, infuser4, infuser5, infuser6, infuser7, infuser8 };
        Ingredient[] ingredients = { modifier1, modifier2, modifier3, modifier4, modifier5, modifier6, modifier7, modifier8 };
        boolean[] unused = { true, true, true, true, true, true, true, true };
        
        for (ItemStack s : stacks) {
            for(int i = 0; i < ingredients.length; i++) {
                if(unused[i] && ingredients[i].apply(s)){
                    matches.add(ingredients[i]);
                    unused[i] = false;
                }
            }
        }
        
        return matches.size() == 8;
    }

Thanks.

Link to comment
Share on other sites

11 hours ago, unassigned said:

boolean[] unused = { true, true, true, true, true, true, true, true };

personally I would do something like `final boolean[] used = new boolean[8]`

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

On 1/5/2019 at 11:17 AM, Cadiboo said:

personally I would do something like `final boolean[] used = new boolean[8]`

That would make all the booleans false by default.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

4 hours ago, larsgerrits said:

That would make all the booleans false by default.

That was the point, their using a boolean array called unused that is initialised to true, I would use a boolean array called used that is automatically initialised to false

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

7 hours ago, larsgerrits said:

That would make all the booleans false by default.

So...invert the rest of your logic that deals with the field.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.