View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0000560 | LDMud | Efuns | public | 2008-08-13 14:45 | 2010-02-13 03:40 |
| Reporter | Largo | Assigned To | |||
| Priority | normal | Severity | feature | Reproducibility | always |
| Status | new | Resolution | open | ||
| Summary | 0000560: new efun to randomize array contents | ||||
| Description | Hey guys, I've written a small new efun named randomize_array() to replace some of these constructs with sort_array() to achieve an array randomization. Maybe you're interested in it, patch is attached. | ||||
| Additional Information | Note that small p_int -> size_t change in array.h: It's not needed by the patch, but using size_t in this place made more sense to me. | ||||
| Tags | ldmud-extensions | ||||
| Attached Files | shuffle_array.diff (3,442 bytes)
Index: version.sh
===================================================================
--- version.sh (Revision 2394)
+++ version.sh (Arbeitskopie)
@@ -17,7 +17,7 @@
# A timestamp, to be used by bumpversion and other scripts.
# It can be used, for example, to 'touch' this file on every build, thus
# forcing revision control systems to add it on every checkin automatically.
-version_stamp="2007-10-14 12:18:07"
+version_stamp="So 17. Aug 14:55:45 CEST 2008"
# The version number information
version_micro=716
Index: array.c
===================================================================
--- array.c (Revision 2394)
+++ array.c (Arbeitskopie)
@@ -69,6 +69,7 @@
#include "mempools.h"
#include "mstrings.h"
#include "object.h"
+#include "random.h"
#include "stdstrings.h"
#include "simulate.h"
#include "svalue.h"
@@ -2806,6 +2807,55 @@
return sp;
} /* f_transpose_array() */
+/*-------------------------------------------------------------------------*/
+svalue_t *
+f_shuffle_array (svalue_t *sp)
+
+/* EFUN shuffle_array()
+ *
+ * mixed *shuffle_array (mixed *arr);
+ *
+ * shuffle_array ( ({1,2,3}) )
+ * => ({3,1,2})
+ * => ({2,3,1})
+ * => ...
+ *
+ * shuffle_array() applied to an array results in an array of
+ * randomly arranged elements.
+ */
+
+{
+ vector_t *v; /* Input vector */
+ vector_t *w; /* Output vector */
+ size_t size; /* size of <v> */
+ size_t i;
+ svalue_t *pos, *next, tmp;
+
+ /* Get and test the arguments */
+ v = sp->u.vec;
+
+ if ( (size = VEC_SIZE(v)) < 2)
+ return sp;
+
+ /* Allocate and fill the result vector */
+ w = slice_array(v, 0, size - 1);
+ free_array(v);
+
+ /* shuffle the array elements */
+ for (pos = w->item, i = size; i-- > 0; ++pos)
+ {
+ next = w->item + random_number(size - i);
+ tmp = *next;
+ transfer_svalue_no_free(next, pos);
+ transfer_svalue_no_free(pos, &tmp);
+ }
+
+ /* Clean up and return the result */
+ put_array(sp, w);
+
+ return sp;
+} /* f_shuffle_array() */
+
/*=========================================================================*/
/* EFUN unique_array()
Index: array.h
===================================================================
--- array.h (Revision 2394)
+++ array.h (Arbeitskopie)
@@ -60,7 +60,7 @@
*/
struct vector_s {
- p_int size; /* Number of contained elements */
+ size_t size; /* Number of contained elements */
p_int ref; /* Number of references */
#ifdef DEBUG
p_int extra_ref; /* Second refcount, used to check .ref. */
@@ -119,6 +119,7 @@
extern svalue_t *v_sort_array(svalue_t *sp, int num_arg);
extern svalue_t *x_map_array(svalue_t *sp, int num_arg);
extern svalue_t *f_transpose_array(svalue_t *sp);
+extern svalue_t *f_shuffle_array(svalue_t *sp);
extern svalue_t *v_filter_objects(svalue_t *sp, int num_arg);
extern svalue_t *v_map_objects(svalue_t *sp, int num_arg);
Index: func_spec
===================================================================
--- func_spec (Revision 2394)
+++ func_spec (Arbeitskopie)
@@ -437,6 +437,7 @@
mixed *map_objects(mixed *, string, ...);
mixed *sort_array(mixed *,string|closure, ...);
mixed *transpose_array(mixed *);
+mixed *shuffle_array(mixed *);
mixed *unique_array(mixed *, string|closure, ...);
mixed filter(mapping|mixed *|string, string|closure|mapping, ...);
| ||||
| External Data (URL) | |||||
|
|
I have no objection to this per se, but this is easy to implement with an sefun like this: mixed *shuffle_array(mixed *a) { a = copy(a); for (int i = sizeof(a); i; ) { int j = random(i--); mixed t = a[i]; a[i] = a[j]; a[j] = t; } return a; } I prefer the name shuffle_array (or maybe just shuffle). Also, the algorithm in the patch isn't quite correct - random_number(size) should be random_number(size - i) for fair shuffling. |
|
|
alright, useful or not, I adapted the patch to solve the issues. |
|
|
I am not sure, if we should it as efun, because it does seem to be used so regularly or to be time-critical. But it might well be useful, I know a few places in our mudlib, which do a similar thing. Maybe we can include a collection of contributed sefuns? Either directly in the driver or in a 'unofficial ldmud extensions' (which could be in LPC as well as in C)? |
|
|
For now I added the patch to http://github.com/zesstra/ldmud-extensions in hope that people find it there. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2008-08-13 14:45 | Largo | New Issue | |
| 2008-08-13 14:45 | Largo | File Added: randomize_array.diff | |
| 2008-08-14 03:23 | fufu | Note Added: 0000757 | |
| 2008-08-17 07:02 | Largo | File Added: shuffle_array.diff | |
| 2008-08-17 07:03 | Largo | Note Added: 0000759 | |
| 2008-08-17 08:54 | fufu | File Deleted: randomize_array.diff | |
| 2008-08-17 08:54 | fufu | File Deleted: shuffle_array.diff | |
| 2008-08-17 08:55 | Largo | File Added: shuffle_array.diff | |
| 2009-10-08 07:40 | zesstra | Note Added: 0001516 | |
| 2010-02-13 03:40 | zesstra | Note Added: 0001719 | |
| 2010-02-15 17:57 | zesstra | Tag Attached: ldmud-extensions |