Array.Shuffle() is a new method that randomly shuffles an array using Fisher–Yates algorithm.
[INTERPRETER] * NEW: Array.Shuffle() is a new method that randomly shuffles an array using Fisher–Yates algorithm.
This commit is contained in:
parent
7df526ac5d
commit
a6eb422756
2 changed files with 85 additions and 0 deletions
|
@ -44,6 +44,7 @@
|
|||
#include "gbx_api.h"
|
||||
#include "gbx_c_file.h"
|
||||
#include "gbx_struct.h"
|
||||
#include "gbx_math.h"
|
||||
#include "gbx_c_array.h"
|
||||
|
||||
static bool _create_static_array;
|
||||
|
@ -768,6 +769,82 @@ BEGIN_METHOD(Array_Swap, GB_INTEGER index; GB_INTEGER index2)
|
|||
END_METHOD
|
||||
*/
|
||||
|
||||
BEGIN_METHOD_VOID(Array_Shuffle)
|
||||
|
||||
int count = THIS->count;
|
||||
int size = THIS->size;
|
||||
void *p1, *p2;
|
||||
int i, j;
|
||||
void *swap;
|
||||
|
||||
if (check_not_multi(THIS) || count <= 1)
|
||||
return;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1: swap = &&__SWAP_BYTE; break;
|
||||
case 2: swap = &&__SWAP_SHORT; break;
|
||||
case 4: swap = &&__SWAP_INT; break;
|
||||
case 8: swap = &&__SWAP_LONG; break;
|
||||
default: swap = &&__SWAP_ANY;
|
||||
}
|
||||
|
||||
for (i = count - 1; i >= 1; i--)
|
||||
{
|
||||
j = (int)(rnd() * (i + 1));
|
||||
p1 = CARRAY_get_data_unsafe(THIS, i);
|
||||
p2 = CARRAY_get_data_unsafe(THIS, j);
|
||||
|
||||
goto *swap;
|
||||
|
||||
__SWAP_BYTE:
|
||||
{
|
||||
char t = *(char *)p1;
|
||||
*(char *)p1 = *(char *)p2;
|
||||
*(char *)p2 = t;
|
||||
continue;
|
||||
}
|
||||
|
||||
__SWAP_SHORT:
|
||||
{
|
||||
short t = *(short *)p1;
|
||||
*(short *)p1 = *(short *)p2;
|
||||
*(short *)p2 = t;
|
||||
continue;
|
||||
}
|
||||
|
||||
__SWAP_INT:
|
||||
{
|
||||
int t = *(int *)p1;
|
||||
*(int *)p1 = *(int *)p2;
|
||||
*(int *)p2 = t;
|
||||
continue;
|
||||
}
|
||||
|
||||
__SWAP_LONG:
|
||||
{
|
||||
int64_t t = *(char *)p1;
|
||||
*(char *)p1 = *(char *)p2;
|
||||
*(char *)p2 = t;
|
||||
continue;
|
||||
}
|
||||
|
||||
__SWAP_ANY:
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned char *q;
|
||||
unsigned char *const end = (unsigned char *)p1 + size;
|
||||
|
||||
for (p = p1, q = p2; p < end; ++p, ++q ) {
|
||||
const unsigned char t = *p;
|
||||
*p = *q;
|
||||
*q = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_METHOD
|
||||
|
||||
static void add(CARRAY *_object, GB_VALUE *value, int index)
|
||||
{
|
||||
void *data;
|
||||
|
@ -1754,6 +1831,7 @@ GB_DESC NATIVE_Array[] =
|
|||
GB_METHOD("Clear", NULL, Array_Clear, NULL),
|
||||
GB_METHOD("Resize", NULL, Array_Resize, "(Size)i"),
|
||||
//GB_METHOD("Swap", NULL, Array_Swap, "(Index)i(Index2)i"),
|
||||
GB_METHOD("Shuffle", NULL, Array_Shuffle, NULL),
|
||||
|
||||
GB_INTERFACE("_convert", _convert),
|
||||
|
||||
|
|
|
@ -85,6 +85,13 @@ int CARRAY_get_static_count(CLASS_ARRAY *desc);
|
|||
size_t CARRAY_get_static_size(CLASS *class, CLASS_ARRAY *desc);
|
||||
void CARRAY_release_static(CLASS *class, CLASS_ARRAY *desc, void *data);
|
||||
|
||||
#define CARRAY_get_data_unsafe(_array, _index) \
|
||||
({ \
|
||||
int __index = (_index); \
|
||||
CARRAY *__array = (CARRAY *)(_array); \
|
||||
(void *)((char *)(__array->data) + __index * __array->size); \
|
||||
})
|
||||
|
||||
#define CARRAY_get_data(_array, _index) \
|
||||
({ \
|
||||
int __index = (_index); \
|
||||
|
|
Loading…
Reference in a new issue