• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Card Sort

F

foxroar1

Guest
Hi everyone,

I need help.

I have 7 card objects that are created, they move to a specific spot, and then I want to sort them.

Each card is the same object (obj_card). So they run the same code.

I have spent the last two hours thinking about and trying to find a way to sort them. I need to figure out what the adjacent cards are, and then put the objects in ascending order from left to right.

I already know how to determine what number each card is. I just can't for the life of me figure out how to detect an adjacent objects variable.

I appreciate the help!
 

Slyddar

Member
You probably should be storing them in a list, or possibly a grid, holding id and value, then sorting and manipulating would be easy.
 
Yeah, you need a controller object, not the cards themselves. You -could- do it within the cards but it's way easier to just have something else list and order them.
 

spe

Member
You can set a controller object to loop through the cards, like this:
Code:
for (var i = 0; i < instance_number(obj_card); i++) {
    ds_list_add(list, instance_place(x+sprite_get_width(spr_card)*i,y,obj_card)
}
Just replace x and y in the script with the actual coordinates of where the first card should be, or just place the controller object on that particular spot in the room. This code assumes there is no gap between the cards; you may have to add in the size of the gap to the equation if there is one. Also, you might want to check if instance_exists before putting the card into a list (oh, and don't forget to initialize the ds_list beforehand) otherwise you might encounter some problems, depending on the game. Maybe not. Just an idea to help get you going in the right direction.
 
F

foxroar1

Guest
Thank you both for the advice, I'm really close to getting it to work now.

But is there a way to make and sort a 2D DS list?

I'm getting it to sort, but if there's duplicate card numbers then two of the cards stack. Super hard to explain in text, I think a 2D DS list will solve it.

I will check out spe's suggestion in the morning. Too tired!
 
D

dannyjenn

Guest
You could implement a sort of linked list data structure using the cards themselves (not a ds_list).

Here's an example of how you could go about setting it up.
Code:
// obj_card's create event:

next = noone;
Code:
// obj_controller's create event:

#macro DISTANCE_BETWEEN_CARDS 200 // adjust this value

first_card = instance_create_layer(x,y,"Instances",obj_card); // we first instantiate the first card
number_of_cards = 1; // and we now have one card

var current_card = first_card; // and the card we've just instantiated is the current card

repeat(6){ // six more times,
    x += DISTANCE_BETWEEN_CARDS; // we update x such that the card we're about to instantiate will be instantiated at the next position

    var card = instance_create_layer(x,y,"Instances",obj_card); // we instantiate a new card,
    number_of_cards += 1; // and we now have 1 more card

    current_card.next = card; // and the card we've just instantiated is 'next' relative to the current (previous) card,
    current_card = card; // and the current card is now the card we've just instantiated
}

x = first_card.x; // we reset the controller's x to the x at which it started

sort_and_reposition(); // (a script we're going to make)
So when the controller is instantiated, seven cards are also instantiated. But these seven cards are linked together through their 'next' variables.
You can then write a script to sort the cards and reposition them:
Code:
// script sort_and_reposition()

// I don't know the name of this sorting algorithm, and it is NOT a very efficient algorithm (I believe it's in the order of n-squared).
// But it's easy to understand and implement. And seeing as you won't be calling this script every frame, and seeing as your list of cards isn't very long, efficiency isn't really an issue here.

// The idea is to check the cards two at a time. We start with the first two cards (cards 1 and 2)... if they are out of order we switch them around...
// Then we check the second two cards (cards 2 and 3) and do the same thing. And then we check the third two cards (3 and 4) and do the same thing.
// We do that until we reach the end.

// And we do that whole process a total of 6 times, because if we just do it once the cards will still be out of order.


repeat(obj_controller.number_of_cards-1){ // six times
    var current_card = obj_controller.first_card; // we begin on the first card
    var previous_card = noone; // there's no card before the first card

    while(current_card.next!=noone){ // we loop until we arrive at the last card

        // each iteration, we move to the next card:
        previous_card = current_card;
        current_card = current_card.next;

        if(current_card.value<previous_card.value){ // if the current card and the previous card are in the wrong order, then we want to switch them around

            // we switch them simply by changing their links:
            previous_card.next = current_card.next;
            current_card.next = previous_card;

            // and we need to update obj_controller's first_card so that it always remains the first card
            if(previous_card==obj_controller.first_card){
                obj_controller.first_card = current_card;
            }
        }
    }
}

// And now we reposition the cards:
var current_card = obj_controller.first_card; // we begin on the first card
while(current_card.next!=noone){ // we loop through all the cards
    current_card.x = obj_controller.x; // we update the card's x to the controller's x
    obj_controller.x += DISTANCE_BETWEEN_CARDS; // we update the controller's x
}
obj_controller.x = obj_controller.first_card.x; // we reset the controller's x afterwards
 
Last edited by a moderator:
F

foxroar1

Guest
Thank you so much for all the responses, I figured out how to not make them stack. I used a different variable, image_index instead of their card number.

When there were two cards of the same number, the list was just finding the first one, so they'd stack. But image_index always gave each position in the list a different number.

One final question unrelated, when I accidentally hit the tilt of my middle mouse button, the object editor, or room if I'm in that editor, flies away. Does anyone know how to disable this?
 
Top