#Removing items in descending order in a for loop

1 messages · Page 1 of 1 (latest)

urban pendant
#

Hello everyone! i was wondering if i could get some help with a function i want to create. Lost story short i have a currency system of 4 types and i want to remove one at a time depending on the amount i select. In current scenario i want to buy something and i have 2 gold, 3 silver and 1 copper coin. the amount is free to add so i want to get 3 times said item. what i would like is to iterate through the 2/3/1 coins and remove that amount in a descending order. so it would take the 2 gold + 1 silver leaving me with 0 gold / 2 silver and 1 copper!

Its not actually coins its an energy system that i want to have it as a combined amount. so if i wanted to give 5 amounts of said energy it would iterate through those amounts and remove them in descending order as it loops.

thick scarab
#

do those coin represent the same currency? for example a gold coin is 100x the base currency 1 value, silver is 10 and copper is 1?

but you can just do that
have a counter for how many coins to remove
loop through the gold, or just subtract the gold,
if the whole gold is not enough to pay for the full counter, carry over the remainder, and remove that from silver, then carry over that remainder and remove it from copper

urban pendant
#

yes this is what i want to do but im kinda stuck! idid try with a nested loop

            for (int i = 0; i < currency.ItemSlots.Count; i++)
            {
                Debug.Log("Item slots count are " + currency.ItemSlots.Count);
                if (currency.ItemSlots[i].Item != null && currency.ItemSlots[i].Amount >= _amount)
                {
                    Debug.Log("Items are " + currency.ItemSlots[i].Item.ItemName);

                    for (int j = 0; j < _amount; j++)
                    {
                        Item oldItem = currency.RemoveItem(currency.ItemSlots[i].Item.ID);
                        oldItem.Destroy();
                    }
                }
            }

but this wont work

#

i tried to see if the amount is proper and take the amount it needs and then move on but i surely messed this up

thick scarab
#
int requiredSum= 3;
int gold = 2;
if (gold >= requiredSum) {
    gold -= requiredSum;
}
else {
    requiredSum -= gold;
    gold = 0;
    // now start subtracting from silver with the remaining requiredSum
}
urban pendant
#

oh i see so in the else statement i should have all 4 currencies and just substract or do multiple else statements?

thick scarab
#

my example isn't very good but in each else check you check for the next currency until you're completely through

in your specific case, you could just set the payment sum before the loop and every time you remove an item, you could just decrease that sum by 1, and if it has reached 0, you exit the method/loop

#

although it's probably good to also check if you have enough coins in the first place

#

assuming your itemSlots are already sorted like you want it to

#

so you start with the slot for gold, then silver etc

urban pendant
#

ye the slots are sorted, its where each item amount is held. i see i see thank you! i will give it a try!!

thick scarab
#

then this check needs to be a bit different too

if (currency.ItemSlots[i].Item != null && currency.ItemSlots[i].Amount >= _amount)
#

because assuming the sum of each slots is enough to pay, you also go through the slot if the amount is not >= _amount

urban pendant
#

those slots are in a list so i iterate through the 4 of them

#

ohh indeed

#

i see i see pff cool cool i will try with a predefined amount and do a loop on all slots!

thick scarab
#

so I'd remove this
currency.ItemSlots[i].Amount >= _amount
then make a separate variable before you start any loop
remainingAmount = _amount;

and here, I'd then count down the remaining amount

for (int j = 0; j < currency.ItemSlots[i].Amount; j++)
                    {
                        Item oldItem = currency.RemoveItem(currency.ItemSlots[i].Item.ID);
                        oldItem.Destroy();
                        remainingAmount--;
                        if (remainingAmount <= 0) { 
                            return; // Exit method here
                         }
                    }
urban pendant
#

oh thank you very much i will give this one a shot and see where it takes me!

thick scarab
#

i have also changed the loop condition to check through all the itemslot entries, since we don't know for sure that the itemSlots are more than amount

urban pendant
#

thank you thank you!

urban pendant
#

hello again! sorry to bother you once more but ive hit a snag! which is strange! the function works in debug but not when i actually remove the items!

remainingAmount = _amount;

            for (int i = 0; i < currency.ItemSlots.Count; i++)
            {
                if (currency.ItemSlots[i].Item != null)
                {
                    for (int j = 0; j < currency.ItemSlots[i].Amount; j++)
                    {
                        Debug.Log("slot index loop is " + j + " slot is " + currency.ItemSlots[i].Item.ItemName + " remaining amount " + currency.ItemSlots[i].Amount);
                        //Item oldItem = currency.RemoveItem(currency.ItemSlots[i].Item.ID);
                        //oldItem.Destroy();
                        //currency.ItemSlots[i].Amount--;
                        remainingAmount--;
                        if (remainingAmount <= 0)
                        {
                            Debug.Log("Remaining amount is 0 break");
                            return;
                        }
                    }
                }
            }

So without removing the items , the loop stays intact and it iterates it whole, but if i do remove the item on each loop j is less since the amount changed so it removes the items equal times! so if i need 4 it takes 2 of each. but it does work in the way that it should since without the removing it iterates the proper amount of times

thick scarab
#

maybe try iterate back to front.
currency.ItemSlots[i].Amount shrinks when you take out elements, or alternatively do
j--
if you take out an element, so it moves back the iterator

#

approach 1:
for (int j = currency.ItemSlots[i].Amount - 1; j >= 0; j--)

#

so it doesnt matter if .Amount shrinks when you take out an entry

urban pendant
#

oh fixed it!

            remainingAmount = _amount;
            for (int i = 0; i < currency.ItemSlots.Count; i++)
            {
                if (currency.ItemSlots[i].Item != null)
                {
                    int curAmount = currency.ItemSlots[i].Amount;
                    for (int j = 0; j < curAmount; j++)
                    {
                        Debug.Log("slot index loop is " + j + " slot is " + currency.ItemSlots[i].Item.ItemName + " remaining amount " + currency.ItemSlots[i].Amount);
                        Item oldItem = currency.RemoveItem(currency.ItemSlots[i].Item.ID);
                        oldItem.Destroy();
                        //currency.ItemSlots[i].Amount--;
                        remainingAmount--;
                        if (remainingAmount <= 0)
                        {
                            return;
                        }
                    }
                }
            }
#

i added another counter so it wont interact with the slot counts

thick scarab
#

that works too in this case yeah