Add range option to PseudoRandom:next()
authorPerttu Ahola <celeron55@gmail.com>
Wed, 28 Mar 2012 18:16:47 +0000 (21:16 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 28 Mar 2012 19:01:23 +0000 (22:01 +0300)
doc/lua_api.txt
src/scriptapi.cpp

index ae6771be50d3db9afbdea700b6bb719e4200086f..68fbcee8c2f2f8dfdc74cb2381bf4a8dfd0cb63a 100644 (file)
@@ -632,7 +632,10 @@ methods:
 PseudoRandom: A pseudorandom number generator
 - Can be created via PseudoRandom(seed)
 methods:
-- next(): return next random number [0...32767]
+- next(): return next integer random number [0...32767]
+- next(min, max): return next integer random number [min...max]
+                  (max - min) must be 32767 or <= 6553 due to the simple
+                  implementation making bad distribution otherwise.
 
 Registered entities
 --------------------
index 944b81a5e28e1cca621090c79680284f32aa2442..70ca6c86af07ff992c6898fa3651d8a8b9a0a659 100644 (file)
@@ -3157,12 +3157,23 @@ private:
                return 0;
        }
 
-       // next(self) -> get next value
+       // next(self, min=0, max=32767) -> get next value
        static int l_next(lua_State *L)
        {
                LuaPseudoRandom *o = checkobject(L, 1);
+               int min = 0;
+               int max = 32767;
+               lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
+               if(!lua_isnil(L, 2))
+                       min = luaL_checkinteger(L, 2);
+               if(!lua_isnil(L, 3))
+                       max = luaL_checkinteger(L, 3);
+               if(max - min != 32767 && max - min > 32767/5)
+                       throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make.");
                PseudoRandom &pseudo = o->m_pseudo;
-               lua_pushinteger(L, pseudo.next());
+               int val = pseudo.next();
+               val = (val % (max-min+1)) + min;
+               lua_pushinteger(L, val);
                return 1;
        }