GameMaker Shuffling a DS grid with multiple lines & fields [SOLVED]

Tony Brice

Member
I'm writing a card game which requires 12 items of data for each of the 46 cards so I'm using a ds_grid to store all the data. I've now come to the part where I need to shuffle all the cards and then allocate half the deck to each player so I thought I'd use the ds_grid_shuffle command.

This shuffles all the data in every field and doesn't preserve the data correctly afterwards because items are everywhere and all I need it to do is keep the data on the X side all in the same place and just change it's Y position in the grid.

I know you can sort lines by using one of the columns but that's not actually shuffling the cards as I'm always going to end up with the same ones in each pile. Anyone know how I can get a shuffle to work the same way?
 
J

japreja

Guest
You can find a wealth of information by searching the Legacy GMC Forums, it is not searched with the current forum search. You have to go into the old forum and search from there. A wealth of information there but it may need some modification with the Studio Versions of GM. Also google pointed me to this YouTube tutorial Video that may have everything you need, I didn't watch it completely.

 

Tony Brice

Member
So far I've tried the legacy forum and watched through that video - which uses ds_stack and not ds_grid, although I guess it's pretty similar how they work. Writing a manual shuffle routine is going to be a pain in the butt if i end up having to do it that way. Someone must have found a way round this before?
 
T

TimothyAllen

Guest
I'm going to state the obvious here and point out that using an array makes it even harder. You do realise that they don't even have a shuffle function, right?
Im going to state the obvious here and point out that a DS_LIST has a shuffle function. You are only wanting to shuffle one dimension of your grid... thus a ds_list of arrays will suffice. Where each entry of the ds_list is an array that represents a card and each entry in the arrays represent the data of the card.

EDIT: Just to be a bit more obvious (pseudo)
Code:
deck = ds_list_create();
ds_list_add(deck,
    ["Card 1", data0, data1, data2, ..., data11],
    ["Card 2", data0, data1, data2, ..., data11],
    ...,
    ["Card 46", data0, data1, data2, ..., data11]));

ds_list_shuffle(deck);
 
Last edited by a moderator:

Tony Brice

Member
So, just to make sure that I'm obviously stating the obvious, I'm going to have to store each of my ds_grid lines within a ds_list because I've loaded in my data from a csv file - which can only be imported into a ds_grid - as far as I'm aware. Hopefully, it does actually work this way.

As my test routines are all set up to use a ds_grid it will need to also be possible to read the ds_list back into a ds_grid. If not then I'm looking at changing how all the data is used in the game.

I'll give that a test run and see if that works then. Thanks for your help so far.
 
T

TimothyAllen

Guest
Well, not so obvious because you didnt say you were using a csv file. But anyway, its easy to write a shuffle function. So 2 of your options are write a custom shuffle for a ds_grid, or load your csv into a ds_grid, but then write it into a ds_list of arrays.

Edit: you could also write your own load_csv function that returns a ds_list of arrays... but not sure its worth the trouble.
 

TheouAegis

Member
Whatever values you end up loading into the grid, they're all numerically indexed.

ds_list_shuffle(deck);
with instance_create(obj_deck.x, obj_deck.y, obj_card) value = ds_list_find(deck,0);
ds_list_delete(deck,0);

Then use value to index the grid.
 
Last edited:

CMAllen

Member
You can 'shuffle' a ds_grid, it just takes an extra 'sorting' column that is fed random values for every entry. Then you sort the ds_grid by that column (ascending or descending doesn't matter). The result is that the ds_grid is now in random order. Refill that column with random values and sort again to re-randomize.
 

Tony Brice

Member
Thanks a lot everyone for your advice here. I was working on using the solution CMAllen suggested by using sort and having an extra field of random numbers but then came up with another solution.

Now I have the ds_grid which contains all the data for the cards.
I have a ds_list containing all the card numbers - 0 to 45.
I have a ds_list for the players cards and the AI cards.

I shuffle the ds_list of card numbers.
I load the player cards and AI cards by iterating through the list of card numbers and adding to each list alternately.
Now I can just reference the grid by each card number in the player/AI hands to get what data I want - and the original deck of cards in the grid never actually changes.

I did a test script to show me the data after each shuffle and it all seems to work perfectly.
 
N

nyancats1993

Guest
We'll seeing as how this is the first thing to pop up when people look for ds_grid shuffle that isn't the function page I figured I'd post this here. This post was also the reason i made this script because I haven't seen anyone else make it yet.

Code:
///ds_grid_shuffle_adv(DSGridIndex, x, y)
// This script will not "randomize()", you must set that your self,
// that way you can use a seed if you want.

/**
 * Shuffles around the grid based on row or column
 *
 * @param   DSMapIndex  The input DS map, DSMap
 * @param   x           shuffles by column (true or false)
 * @param   y           shuffles by row (true or false)
 *
 * @return  nothing
 */


var _grid, _width, widthmax, _height, heightmax, _gridTemp;


_grid     = argument[0];
_width    = ds_grid_width(_grid);
widthmax  = _width
_height   = ds_grid_height(_grid);
heightmax = _height
_gridTemp = ds_grid_create(_width,_height)

if (argument[1] = 1) && (argument[2] = 0)
{
    for (var _i=0; _i < widthmax; _i++)
    {
        _width = ds_grid_width(_grid)
        var xrandom = irandom(_width-1)
        ds_grid_set_grid_region(_gridTemp, _grid, xrandom, 0, xrandom, _height-1, _i, 0)
        ds_grid_set_grid_region(_grid, _grid, xrandom+1, 0, _width-1, _height-1, xrandom, 0);
        ds_grid_resize(_grid,_width-1,_height);
        if (_width = 1) break;
    }
    ds_grid_resize(_grid, widthmax, heightmax)
    _grid = _gridTemp
}


if (argument[1] = 0) && (argument[2] = 1)
{
    for (var _i=0; _i < heightmax; _i++)
    {
        _height = ds_grid_height(_grid)
        var yrandom = irandom(_height-1)
        ds_grid_set_grid_region(_gridTemp, _grid, 0, yrandom, _width-1, yrandom, 0, __i)
        ds_grid_set_grid_region(_grid, _grid, 0, yrandom+1, _width-1, _height-1, 0, yrandom);
        ds_grid_resize(_grid,_width,_height-1);
        if (_height = 1) break;
    }
    ds_grid_resize(_grid, widthmax, heightmax)
    _grid = _gridTemp
}

if  (argument[1] = 1) && (argument[2] = 1)
{
    ds_grid_shuffle(_grid)
}

ds_grid_destroy(_gridTemp)
 
Top