From c8fb341e1ac066ecfb12daa843b49995cf6d5a0e Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 24 Aug 2008 16:08:13 +0000 Subject: [PATCH] Fixed random_int and random_real functions; added random_boolean. Split random_select into random_select and random_select_many. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1161 0fc631ac-6414-0410-93d0-97cfa31319b6 --- doc/function/index.txt | 4 +- doc/function/random_boolean.txt | 22 +++++ doc/function/random_int.txt | 1 + doc/function/random_real.txt | 1 + doc/function/random_select.txt | 14 +--- doc/function/random_select_many.txt | 29 +++++++ doc/function/random_shuffle.txt | 3 +- src/script/functions/basic.cpp | 80 +++++++++++-------- .../drupal/mse-drupal-modules/highlight.inc | 2 + 9 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 doc/function/random_boolean.txt create mode 100644 doc/function/random_select_many.txt diff --git a/doc/function/index.txt b/doc/function/index.txt index 7bb07b3c..5a7b4ab9 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -14,6 +14,7 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:abs]] Absolute value | [[fun:random_int]] Generate a random [[type:int]]. | [[fun:random_real]] Generate a random [[type:double]]. +| [[fun:random_boolean]] Generate a random [[type:boolean]]. ! Text manipulation <<< | [[fun:to_upper]] Convert a string to upper case, @"aBc" -> "ABC"@. @@ -44,7 +45,8 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:sort_list]] Sort a list. | [[fun:filter_list]] Filter a list, keeping only elements that match a predicate. | [[fun:random_shuffle]] Randomly shuffle a list. -| [[fun:random_select]] Pick random elements from a list. +| [[fun:random_select]] Pick a random element from a list. +| [[fun:random_select_many]] Pick multiple random elements from a list. ! Keywords <<< | [[fun:expand_keywords]] Expand the keywords in a piece of text. diff --git a/doc/function/random_boolean.txt b/doc/function/random_boolean.txt new file mode 100644 index 00000000..54c131e2 --- /dev/null +++ b/doc/function/random_boolean.txt @@ -0,0 +1,22 @@ +Function: random_boolean + +DOC_MSE_VERSION: since 0.3.8 + +--Usage-- +> random_boolean(probability) + +Returns a random [[type:bool]], either @true@ or @false. +The parameter is the probability of returning @true@, so @random_boolean(0.0)@ always returns @true@, @random_boolean(1.0)@ always returns @false@ and @random_boolean(0.5)@ simulates a fair coin toss. + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Default Description +| @input@ [[type:double]] @0.5@ Probability of returining true + +--Examples-- +> random_boolean(0.5) == true +> random_boolean(0.5) == false + +--See also-- +| [[fun:random_real]] Generate a random [[type:double]]. diff --git a/doc/function/random_int.txt b/doc/function/random_int.txt index 2f9af862..8d7e7e50 100644 --- a/doc/function/random_int.txt +++ b/doc/function/random_int.txt @@ -23,3 +23,4 @@ Since the result is random, calling the function twice will give a different ans --See also-- | [[fun:random_real]] Generate a random [[type:double]]. +| [[fun:random_boolean]] Generate a random [[type:boolean]]. diff --git a/doc/function/random_real.txt b/doc/function/random_real.txt index 9d2d6179..94a93a13 100644 --- a/doc/function/random_real.txt +++ b/doc/function/random_real.txt @@ -22,3 +22,4 @@ Since the result is random, calling the function twice will give a different ans --See also-- | [[fun:random_int]] Generate a random [[type:int|integer number]]. +| [[fun:random_boolean]] Generate a random [[type:boolean]]. diff --git a/doc/function/random_select.txt b/doc/function/random_select.txt index 43362908..e2f87a0e 100644 --- a/doc/function/random_select.txt +++ b/doc/function/random_select.txt @@ -5,28 +5,18 @@ DOC_MSE_VERSION: since 0.3.7 --Usage-- > random_select(some_list, count: some_number, replace: some_boolean) -Randomly select a number of items from a list. - -If the @count@ parameter is not given, then a single item is picked at random. - -Otherwise @count@ ''different'' items are selected (selection without replacment). -Setting the @replace@ parameter allows the same item to occur more than once in the result (selection with replacment). +Randomly select an items from a list. Since the result is random, calling the function twice will give a different answer. --Parameters-- ! Parameter Type Description | @input@ [[type:list]] List to shuffle. -| @count@ [[type:int]] Number of items to select. -| @replace@ [[type:boolean]] Select with replacement? --Examples-- > random_select([1,2,3,4]) == 4 > random_select([1,2,3,4]) == 2 -> random_select([1,2,3,4], count:3) == [2,3,1] -> random_select([1,2,3,4], count:3) == [3,1,4] -> random_select([1,2,3,4], count:3, replace: true) == [2,3,2] -> random_select([1,2,3,4], count:3, replace: false) == [1,3,4] --See also-- +| [[fun:random_select_many]] Pick multiple random elements from a list. | [[fun:random_shuffle]] Randomly shuffle a list. diff --git a/doc/function/random_select_many.txt b/doc/function/random_select_many.txt new file mode 100644 index 00000000..2da407c6 --- /dev/null +++ b/doc/function/random_select_many.txt @@ -0,0 +1,29 @@ +Function: random_select_many + +DOC_MSE_VERSION: since 0.3.8 + +--Usage-- +> random_select(some_list, count: some_number, replace: some_boolean) + +Randomly select a number of items from a list. + +By default @count@ ''different'' items are selected (selection without replacment). +Setting the @replace@ parameter allows the same item to occur more than once in the result (selection with replacment). + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:list]] List to shuffle. +| @count@ [[type:int]] Number of items to select. +| @replace@ [[type:boolean]] Select with replacement? + +--Examples-- +> random_select_many([1,2,3,4], count:3) == [2,3,1] +> random_select_many([1,2,3,4], count:3) == [3,1,4] +> random_select_many([1,2,3,4], count:3, replace: true) == [2,3,2] +> random_select_many([1,2,3,4], count:3, replace: false) == [1,3,4] + +--See also-- +| [[fun:random_select]] Pick a single random element from a list. +| [[fun:random_shuffle]] Randomly shuffle a list. diff --git a/doc/function/random_shuffle.txt b/doc/function/random_shuffle.txt index 5a92daf1..f49c42a7 100644 --- a/doc/function/random_shuffle.txt +++ b/doc/function/random_shuffle.txt @@ -18,4 +18,5 @@ Since the result is random, calling the function twice will give a different ans > random_shuffle([1,2,3,4]) == [2,3,4,1] --See also-- -| [[fun:random_select]] Pick random elements from a list. +| [[fun:random_select]] Pick a single random element from a list. +| [[fun:random_select_many]] Pick multiple random elements from a list. diff --git a/src/script/functions/basic.cpp b/src/script/functions/basic.cpp index f25da1aa..d854b952 100644 --- a/src/script/functions/basic.cpp +++ b/src/script/functions/basic.cpp @@ -232,6 +232,11 @@ SCRIPT_FUNCTION(random_int) { SCRIPT_RETURN( rand() % (end - begin) + begin ); } +SCRIPT_FUNCTION(random_boolean) { + SCRIPT_PARAM_DEFAULT_C(double, input, 0.5); + SCRIPT_RETURN( rand() < RAND_MAX * input ); +} + // ----------------------------------------------------------------------------- : String stuff // convert a string to upper case @@ -521,40 +526,43 @@ SCRIPT_FUNCTION(random_shuffle) { SCRIPT_FUNCTION(random_select) { SCRIPT_PARAM_C(ScriptValueP, input); - SCRIPT_OPTIONAL_PARAM(int, count) { - // pick a single one - int itemCount = input->itemCount(); - if (itemCount == 0) { - throw ScriptError(String::Format(_("Can not select a random item from an empty collection"), count)); - } - return input->getIndex( rand() % itemCount ); - } else { - // pick many - SCRIPT_PARAM_DEFAULT_C(bool, replace, false); - ScriptCustomCollectionP ret(new ScriptCustomCollection); - int itemCount = input->itemCount(); - if (replace) { - if (itemCount == 0) { - throw ScriptError(String::Format(_("Can not select %d items from an empty collection"), count)); - } - for (int i = 0 ; i < count ; ++i) { - ret->value.push_back( input->getIndex( rand() % itemCount ) ); - } - } else { - if (count > itemCount) { - throw ScriptError(String::Format(_("Can not select %d items from a collection conaining only %d items"), count, input->itemCount())); - } - // transfer all to ret and shuffle - ScriptValueP it = input->makeIterator(input); - while (ScriptValueP v = it->next()) { - ret->value.push_back(v); - } - random_shuffle(ret->value.begin(), ret->value.end()); - // keep only the first 'count' - ret->value.resize(count); - } - return ret; + // pick a single one + int itemCount = input->itemCount(); + if (itemCount == 0) { + throw ScriptError(_("Can not select a random item from an empty collection")); } + return input->getIndex( rand() % itemCount ); +} + +SCRIPT_FUNCTION(random_select_many) { + SCRIPT_PARAM_C(ScriptValueP, input); + SCRIPT_PARAM(int, count) ; + SCRIPT_OPTIONAL_PARAM_C_(ScriptValueP, replace); + bool with_replace = replace && replace->type() != SCRIPT_FUNCTION && (bool)*replace; + // pick many + ScriptCustomCollectionP ret(new ScriptCustomCollection); + int itemCount = input->itemCount(); + if (with_replace) { + if (itemCount == 0) { + throw ScriptError(String::Format(_("Can not select %d items from an empty collection"), count)); + } + for (int i = 0 ; i < count ; ++i) { + ret->value.push_back( input->getIndex( rand() % itemCount ) ); + } + } else { + if (count > itemCount) { + throw ScriptError(String::Format(_("Can not select %d items from a collection conaining only %d items"), count, input->itemCount())); + } + // transfer all to ret and shuffle + ScriptValueP it = input->makeIterator(input); + while (ScriptValueP v = it->next()) { + ret->value.push_back(v); + } + random_shuffle(ret->value.begin(), ret->value.end()); + // keep only the first 'count' + ret->value.resize(count); + } + return ret; } // ----------------------------------------------------------------------------- : Keywords @@ -640,8 +648,9 @@ void init_script_basic_functions(Context& ctx) { ctx.setVariable(_("to code"), script_to_code); // math ctx.setVariable(_("abs"), script_abs); - ctx.setVariable(_("random_real"), script_random_real); - ctx.setVariable(_("random_int"), script_random_int); + ctx.setVariable(_("random real"), script_random_real); + ctx.setVariable(_("random int"), script_random_int); + ctx.setVariable(_("random boolean"), script_random_boolean); // string ctx.setVariable(_("to upper"), script_to_upper); ctx.setVariable(_("to lower"), script_to_lower); @@ -670,6 +679,7 @@ void init_script_basic_functions(Context& ctx) { ctx.setVariable(_("sort list"), script_sort_list); ctx.setVariable(_("random shuffle"), script_random_shuffle); ctx.setVariable(_("random select"), script_random_select); + ctx.setVariable(_("random select many"), script_random_select_many); // keyword ctx.setVariable(_("expand keywords"), script_expand_keywords); ctx.setVariable(_("expand keywords rule"), new_intrusive1(script_expand_keywords)); diff --git a/tools/website/drupal/mse-drupal-modules/highlight.inc b/tools/website/drupal/mse-drupal-modules/highlight.inc index 45170a71..654fb594 100644 --- a/tools/website/drupal/mse-drupal-modules/highlight.inc +++ b/tools/website/drupal/mse-drupal-modules/highlight.inc @@ -15,6 +15,7 @@ $built_in_functions = array( 'abs' =>'', 'random_int' =>'', 'random_real' =>'', + 'random_boolean' =>'', // text 'to_upper' =>'', 'to_lower' =>'', @@ -43,6 +44,7 @@ $built_in_functions = array( 'filter_list' =>'', 'random_shuffle' =>'', 'random_select' =>'', + 'random_select_many' =>'', // keywords 'expand_keywords' =>'', 'expand_keywords_rule'=>'expand_keywords', 'keyword_usage' =>'',