what DS structure will do a PROPER shuffle??

T

TheDragon327

Guest
so i have a grid that is 2 wide with and index of 50 items

if items at index 5 are apple,25
and items at index 12 are orange,30

when i do a shuffle...i want items apple,25 and orange,30 to still be together...but at different index values?

i dont want apple to be at index 2 and 25 to be at index 11...i want them to stay together

can someone tell me what DS structure or command to use for this type of operation?
 
B

Bayesian

Guest
what do you mean by "together", since they start out at indexes 5 and 12.
He means keeping the rows together instead of shuffling just the columns

There is no function that does the operation, you have to do it manually. Here is how to do it with arrays, you should be able to adapt this for grids just be sure to use the "#" accessor
 
D

dannyjenn

Guest
Depending on what you're trying to do, you could store all the indices in a ds_list and then shuffle the indices (rather than trying to shuffle the array).
 

samspade

Member
so i have a grid that is 2 wide with and index of 50 items

if items at index 5 are apple,25
and items at index 12 are orange,30

when i do a shuffle...i want items apple,25 and orange,30 to still be together...but at different index values?

i dont want apple to be at index 2 and 25 to be at index 11...i want them to stay together

can someone tell me what DS structure or command to use for this type of operation?
In my head, I thought ds_grid_shuffle only shuffled rows, but I guess it doesn't according to the manual. Anyway, I think this would work (I adapted yellowafterlife's array script because I think this would be a useful script to have in general).

Code:
///scr_ds_grid_row_shuffle(index)
/// @description Shuffle Grid Rows
/// @param ds_grid

var _grid, _size, _temp_array, j;
_grid = argument0;
_size = ds_grid_height(_grid);
_temp_array = array_create(2, -1);

for (var i = 0; i < _size; i += 1)
{
    j = irandom_range(i, _size - 1)
    if (i != j)
    {
        _temp_array[0] = _grid[# 0, i];
        _temp_array[1] = _grid[# 1, i];
        _grid[# 0, i] = _grid[# 0, j];
        _grid[# 1, i] = _grid[# 1, j];
        _grid[# 0, j] = _temp_array[0];
        _grid[# 1, j] = _temp_array[1];
    }
}
I admit, I'm not testing it today because it is late (probably will tomorrow) so I might very well have gotten something wrong, but it, or something close to that, should work. Feel free to correct mistakes or add other feedback.

Also, while I think a grid sounds better for what you want, an alternative would be to store arrays inside of a list. Then you can shuffle the list without worries. I do this for a lot of things, but it also means you have to pull the arrays out of the list for use, which can be kind of annoying.
 
T

TheDragon327

Guest
yeah...i just wish they could code the darn Shuffle feature to shuffle only the index values...
especially when it comes to much larger grids....like 5 wide or 10 wide.....leave all the information in the columns together and only shuffle the rows...
 

samspade

Member
yeah...i just wish they could code the darn Shuffle feature to shuffle only the index values...
especially when it comes to much larger grids....like 5 wide or 10 wide.....leave all the information in the columns together and only shuffle the rows...
I tested my originally posted code and it worked, but you raised a good point, so I modified the code to handle grids of arbitrary size. No promises on how efficient it is or if there might be some bias in how it is shuffled but it seems to work fine (if anyone has any comments on that feel free to suggest). You could simply switch the order to shuffle columns, and if you wanted add a switch statement with both and an extra argument to determine whether to shuffle by row or column.

Code:
///scr_ds_grid_row_shuffle(index)
/// @description Shuffle Grid Rows
/// @param ds_grid

#region //initialize temporary variables

var _grid, _width, _height, _temp_array, _current_row, _row_to_swap;
_grid = argument0;
_width = ds_grid_width(_grid);
_height = ds_grid_height(_grid);
_temp_array = array_create(_width, -1);

#endregion


#region //shuffle grid by rows

//loop through all rows
for (_current_row = 0; _current_row < _height; _current_row += 1) {
  
    //pick a random row greater the number of rows already shuffled
    _row_to_swap = irandom_range(_current_row, _height - 1)
  
    //if that random row is not this row
    if (_current_row != _row_to_swap) {
      
        //save all columns of this row into a temporary array
        for (var _col = 0; _col < _width; _col += 1) {
            _temp_array[_col] = _grid[# _col, _current_row];
        }

        //copy all columns of the random row into the current row
        for (var _col = 0; _col < _width; _col += 1) {
            _grid[# _col, _current_row] = _grid[# _col, _row_to_swap];
        }
      
        //copy the saved columns to the random row
        for (var _col = 0; _col < _width; _col += 1) {
            _grid[# _col, _row_to_swap] = _temp_array[_col];
        }
      
    }
}

#endregion

If you want to test it, create a blank project, add the script, and put in the following object:

Code:
/// @description Create Event
randomize();
grid = ds_grid_create(irandom_range(2, 5), irandom_range(2, 5));
for (var i = 0; i < ds_grid_width(grid); i += 1) {
    for (var j = 0; j < ds_grid_height(grid); j += 1) {
        grid[# i, j] = irandom(10);
    }
}
draw_x = 50;
draw_y = 50;
offset = 30;

/// @description Step Event
if (keyboard_check_pressed(ord("R"))) {
    game_restart();
}
if (keyboard_check_pressed(vk_space)) {
    ds_grid_shuffle(grid);
}
if (keyboard_check_pressed(vk_enter)) {
    scr_ds_grid_shuffle_rows(grid);
}

/// @description Draw Event
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_valign(fa_middle);
var _text;
for (var i = 0; i < ds_grid_width(grid); i += 1) {
    for (var j = 0; j < ds_grid_height(grid); j += 1) {
        _text = string(grid[# i, j]);
        draw_text(draw_x + i * offset, draw_y + j * offset, _text);
    }
}

/// @description Clean Up Event (unnecessary here, but good practice)
ds_grid_destroy(grid);
 
It might be worth suggesting adding a ds grid shuffle feature by row/column actually. I've also had a few opportunities where I could have used it
 

samspade

Member
It might be worth suggesting adding a ds grid shuffle feature by row/column actually. I've also had a few opportunities where I could have used it
I'll let other people do that. Unless you mean suggesting to YOYO that they should add the feature in, in which case I agree. It makes sense as to why they don't have it for arrays, as their array system is pretty bare bones, but since the main point of their data structures is to provide additional functionality it seems like the ability to sort by row or column would be a good addition.


As I was typing this, I realized that in addition to all the ways suggested above, there's another fairly simply way to shuffle by row taken from excel. Just add another col and fill it with random numbers then use ds_grid_sort on that column as that does keep rows together. Won't work for columns though because I don't think there's a ds_gird_sort for columns (unless I'm really missing something) which also seems like it would be a good addition for YOYO to add.
 
Top