2

Possible Duplicate:
Swap two items in List<T>

Edit: Maybe this will work for getting the 'b' value?

for (int i = 0; i < inventory.Count; i++)
{
    if (inventory[a].ItemRectangle.Intersects(inventory[i].ItemRectangle))
    {
        itemB = inventory[i];
    }
}

Edit: Here's my progress.

Item itemA;
Item itemB;

int a = -1;
int b = -1;

if (a != -1 && b != -1)
{
    itemA = inventory[a];
    itemB = inventory[b];

    Swap(ref itemA, ref itemB);

    inventory[a] = itemA;
    inventory[b] = itemB;
}

And here's is where I'm getting the 'a' value.

if (item.ItemSelected == true)
{
    a = item.ItemIndex;
}
else
    a = -1;

I haven't figured out how to get the 'b' value because I would have to check for an item colliding with another item that are both in the same list. If anybody know how I can do this, please tell me. It would look something like this I guess:

if (item.ItemRectangle.Intersects(//the other item.ItemRectangle)
{
    b = item.ItemIndex;
}
else
    b = -1;

I've made a List < Item > called inventory. So now I want to implement a swap function, like this:

foreach (Item item in inventory)
{
    if (mouseRectangle.Intersects(item.ItemRectangle))
    {
        if (Input.EdgeDetectLeftMouseDown())
        {
            switch (item.ItemSelected)
            {
                case false:
                    item.ItemSelected = true;
                    break;
                case true:
                    item.ItemSelected = false;
                    break;
            }
        }  
    }
    else if (Input.EdgeDetectLeftMouseDown())
    {
        switch (item.ItemSelected)
        {
            case true:
                item.ItemSelected = false;
                break;
        }
    }
    else if (item.ItemSelected == true)
    {
        item.ItemPosition = new Vector2(mouseRectangle.X, mouseRectangle.Y);
        item.ItemRectangle = new Rectangle(mouseRectangle.X, mouseRectangle.Y, 32, 32);
    }
    else if (item.ItemSelected == false && //a lot of checks to determine it is not intersecting with an equip slot
    {
        item.ItemPosition = item.OriginItemPosition;
        item.ItemRectangle = item.OriginItemRectangle;
    }
    else if (item.ItemRectangle.Intersects(item.ItemRectangle))
    {
        //SwapItem(inventory, item, item);
    }

So that's the part of the code I need help with. I want any item in the list to be able to swap with any other item in the list. My SwapItem method is just a placeholder, I dont actually have a SwapItem method yet.

I want the arguments that you pass in to the method to be related to the items I want to swap. So the first item would be the item that I have selected with my mouse, and the other item should be the item that the first item is intersecting with.

Community
  • 1
  • 1
user1476943
  • 65
  • 1
  • 2
  • 7
  • 1
    Go and learn the C# language, and then come back and you will get help. It is clear to me that you don't understand the basics of programming, the for loop should be among the first things you learn. I would recommend that you start by learning C++ first, so that you can understand the basics of programming, and program efficiently in higher level languages like C#, but this is up to you. – Tibi Jul 02 '12 at 10:22
  • First off, I know I've been quite annoying asking so much. But that's why I came here, to learn. And I do know what a for loop is, I just don't see why I need it here. The only time my a and b values are anything besides -1 is when I have an item selected and click another item. That way it will pass the if check and swap the items. I don't see what I've done wrong here to be honest. The only thing I'm having trouble with is getting the b value, because I have to check for collision between two items in the same list. – user1476943 Jul 02 '12 at 13:52
  • Look again at my answer, I edited, hopefully you will understand. – Tibi Jul 02 '12 at 14:37
  • I should have enough information now to figure it out, either with my own method or with yours. Thanks a lot for your help. – user1476943 Jul 02 '12 at 14:47
  • Your method works fine, but it lags a lot, unlike foreach. So I will have to use foreach. But it should work. – user1476943 Jul 02 '12 at 15:08
  • There is probably another thing that makes it lag, I doubt that a for loop can make it lag. – Tibi Jul 02 '12 at 15:12

2 Answers2

22

To swap an element of the list you can write an extension method as.

public static class ExtensionMethods
{
    public static void Swap<T>(this List<T> list, int index1, int index2)
    {
         T temp = list[index1];
         list[index1] = list[index2];
         list[index2] = temp;
    }
}

Remember to put the extension method inside a static class.

then you can do:

yourList.Swap(0,1); // swap element at index 0 with element at index 1
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 2
    +1 for using extension method! – Darj Jul 01 '12 at 21:07
  • How can you declare .Swap like that when you have to declare ExtensionMethods.Swap... – Obsivus Mar 31 '14 at 14:40
  • @Obsivus, I am not really sure about your question, are you trying to ask how [Extension method works](http://www.hanselman.com/blog/HowDoExtensionMethodsWorkAndWhyWasANewCLRNotRequired.aspx) ? – Habib Mar 31 '14 at 14:44
  • Nvm I was thinking wrong, Sorry. Will up the answer :) It worked perfectly – Obsivus Mar 31 '14 at 14:53
  • @Obsivus, I have no idea how you are using it. Declare it inside a public static class, and then it should be available with `List` – Habib Mar 31 '14 at 14:56
0

To swap the values of two variables, the easiest method is using references. This is a classic pointer exercise in c++, but it can apply to C# as well.

// Replace int with any data type / class you need
void Swap (ref int a, ref int b)
{
   int c = a; 
   a = b; 
   b = c;
}

The algorithm used is very simple, and the explanation is usually done like this: you have two glasses, one with water, and one with oil. To put the oil in the first glass, you will need to use a third glass, put the water inside, then put the oil in the first glass, and the water in the second one.


Here is what I had in mind. Look for the comments, so you can understand what's going on.:

// Unlike foreach, with for I can change the values in the list
for (int i = 0; i < inventory.Count; i++)
{
    if (mouseRectangle.Intersects(inventory[i].ItemRectangle))
    {
        if (Input.EdgeDetectLeftMouseDown())
        {
            // You can replace the switch with this shorter structure
            // if A is a bool value, !A will have the opposite value
            inventory[i].ItemSelected = !inventory[i].ItemSelected;
        }  
    }
    else if (Input.EdgeDetectLeftMouseDown())
    {
        // You don't need a case-switch for a single condition. An if should suffice
        if (inventory[i].ItemSelected) 
            inventory[i].ItemSelected = false;
    }
    else if (inventory[i].ItemSelected == true)
    {
        inventory[i].ItemPosition = new Vector2(mouseRectangle.X, mouseRectangle.Y);
        inventory[i].ItemRectangle = new Rectangle(mouseRectangle.X, mouseRectangle.Y, 32, 32);
    }
    else if (inventory[i].ItemSelected == false && //a lot of checks to determine it is not intersecting with an equip slot
    {
        inventory[i].ItemPosition = inventory[i].OriginItemPosition;
        inventory[i].ItemRectangle = inventory[i].OriginItemRectangle;
    }

    // Something definitely wrong with this line, a rectangle to instersect with itself??
    else if (inventory[i].ItemRectangle.Intersects(inventory[PROBABLY_SOMETHING_ELSE].ItemRectangle))
    {
        Swap (ref inventory[i], ref inventory[PROBABLY_SOMETHING_ELSE])
    }
}
Tibi
  • 4,015
  • 8
  • 40
  • 64
  • Hmm... what are you trying to swap exactly? Inventory seems to be the container, and the other parameters in the sample code are item and item, which is the same thing... – Tibi Jul 01 '12 at 15:12
  • What I don't understand is that you are trying to replace 'item' with 'item', are you trying to swap an object with itself? To fix the error, you could replace foreach with for, and iterate with an index value instead. You will also need to replace item with inventory[index]... – Tibi Jul 01 '12 at 15:19
  • Nope, 'item' will keep its value through the entire code block, and then change it to the next value in the list, keep it again for the entire code block and so on. I think you want to swap two items with different indices from the list, so you need to make the replacement I told you about. – Tibi Jul 01 '12 at 15:23
  • Yes, but I don't want those indices to be 'hard coded'. Index a = the item I am selecting. Index b = the item that item a is colliding with. – user1476943 Jul 01 '12 at 15:28
  • Exactly, why not make two variables a and b which have these values, and swap inventory[a] with inventory[b]? You also need to replace foreach with for, because you can't modify values in a list while you are looping using foreach. – Tibi Jul 01 '12 at 15:32
  • Could you please give me an example of such a loop? Everything I have tried so far didn't work. – user1476943 Jul 01 '12 at 19:12
  • Example: `for (int i = 0; i < inventory.Length; i++)`, and you need to figure out the values of a and b. I can't tell you more than this, it's your code, your application. – Tibi Jul 01 '12 at 19:17
  • I have updated my code. If you could take a look and tell me if my technique is correct, I would be much obliged. (new code is at the top) – user1476943 Jul 01 '12 at 20:38
  • Also, do I really need the for loop? I'm not sure what the use of it is. – user1476943 Jul 01 '12 at 21:42
  • If you have a glass with water and another with oil, just pour the water into the oil, let the oil rise, then slowly pour the oil off the top into the other glass! Just poking fun at your analogy. – A-Type Jul 02 '12 at 18:29
  • @A-Type This is how teachers at school explain it, and I find it easier to understand this way. Your method is not good, the glasses would have to be less-than-half empty for it to work, and it's not as efficient as this one. – Tibi Jul 03 '12 at 09:28
  • @Tibi well criticized :) Cheers on your thorough answer anyways. Last time I try to be clever... – A-Type Jul 03 '12 at 16:33