Renegade Public Forums
C&C: Renegade --> Dying since 2003™, resurrected in 2024!
Home » Tiberian Technologies / Blackhand Studios » Tiberian Technologies Forum » Commands->Get_Random_Int() is of very poor quality
Commands->Get_Random_Int() is of very poor quality [message #473077] Sun, 12 August 2012 12:59 Go to next message
iRANian is currently offline  iRANian
Messages: 4308
Registered: April 2011
Karma: 0
General (4 Stars)
This function is used as the Crates plugin's random number generator, the following code is used for this plugin:

int	Rnd	= Commands->Get_Random_Int(1,101);


I get the following output with this code (output in spoilers):
	for (int i = 0; i < 100; i++)
	{
		int	Rnd	= Commands->Get_Random_Int(1,101);
		Console_Output("Rnd = %d\n", Rnd);
	}


The resulting output is:
Toggle Spoiler


The pattern is very simple, if a number is returned a few calls later a number in a range of less than 10 higher or lower will be returned (seems to average at a range of ~5 higher/lower) around 85-90% of the time.

I reported this issue to Black-Cell in 2005 if I remember correctly and one of the programmers there acknowledged Renegade's random number generator isn't that great.

The result is what you see on SSGM servers with custom crates enabled, you won't see Spy crates for an hour but after someone picks up one in close succession there will be 1-3 other Spy crates. Same with all the other crates but it's the most noticeable with this one as it has such a low probability of showing up.

The random number generator code might be time based, I haven't checked that and I doubt it as I can't see calls to time based code for any of the random number generator classes (quickly scanning over it) and I see them using rand() for stuff like team remix/rebalance.


Long time and well respected Renegade community member, programmer, modder and tester.

Scripts 4.0 private beta tester since May 2011.

My Renegade server plugins releases

[Updated on: Sun, 12 August 2012 13:10]

Report message to a moderator

Re: Commands->Get_Random_Int() is of very poor quality [message #473078 is a reply to message #473077] Sun, 12 August 2012 13:10 Go to previous messageGo to next message
iRANian is currently offline  iRANian
Messages: 4308
Registered: April 2011
Karma: 0
General (4 Stars)
replace it with doom 1's random number "generator"!:

/*
** m_oldrandom.cpp
** Contains Doom's original random number generator.
**
**---------------------------------------------------------------------------
** Copyright 1993-1996 by id Software, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
**    notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
**    derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/

static const char rcsid[] = "$Id: m_random.c,v 1.1 1997/02/03 22:45:11 b1 Exp $";


//
// M_Random
// Returns a 0-255 number
//
unsigned char rndtable[256] = {
	0,	 8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,	66 ,
	74,  21, 211,  47,	80, 242, 154,  27, 205, 128, 161,  89,	77,  36 ,
	95, 110,  85,  48, 212, 140, 211, 249,	22,  79, 200,  50,	28, 188 ,
	52, 140, 202, 120,	68, 145,  62,  70, 184, 190,  91, 197, 152, 224 ,
	149, 104,  25, 178, 252, 182, 202, 182, 141, 197,	4,	81, 181, 242 ,
	145,  42,  39, 227, 156, 198, 225, 193, 219,  93, 122, 175, 249,   0 ,
	175, 143,  70, 239,  46, 246, 163,	53, 163, 109, 168, 135,   2, 235 ,
	25,  92,  20, 145, 138,  77,  69, 166,	78, 176, 173, 212, 166, 113 ,
	94, 161,  41,  50, 239,  49, 111, 164,	70,  60,   2,  37, 171,  75 ,
	136, 156,  11,	56,  42, 146, 138, 229,  73, 146,  77,	61,  98, 196 ,
	135, 106,  63, 197, 195,  86,  96, 203, 113, 101, 170, 247, 181, 113 ,
	80, 250, 108,	7, 255, 237, 129, 226,	79, 107, 112, 166, 103, 241 ,
	24, 223, 239, 120, 198,  58,  60,  82, 128,   3, 184,  66, 143, 224 ,
	145, 224,  81, 206, 163,  45,  63,	90, 168, 114,  59,	33, 159,  95 ,
	28, 139, 123,  98, 125, 196,  15,  70, 194, 253,  54,  14, 109, 226 ,
	71,  17, 161,  93, 186,  87, 244, 138,	20,  52, 123, 251,	26,  36 ,
	17,  46,  52, 231, 232,  76,  31, 221,	84,  37, 216, 165, 212, 106 ,
	197, 242,  98,	43,  39, 175, 254, 145, 190,  84, 118, 222, 187, 136 ,
	120, 163, 236, 249
};

int 	prndindex = 0;

// Which one is deterministic?
int P_Random (void)
{
	prndindex = (prndindex+1)&0xff;
	return rndtable[prndindex];
}

void M_ClearRandom (void)
{
	prndindex = 0;
}


Long time and well respected Renegade community member, programmer, modder and tester.

Scripts 4.0 private beta tester since May 2011.

My Renegade server plugins releases
Re: Commands->Get_Random_Int() is of very poor quality [message #473084 is a reply to message #473077] Sun, 12 August 2012 14:14 Go to previous messageGo to next message
iRANian is currently offline  iRANian
Messages: 4308
Registered: April 2011
Karma: 0
General (4 Stars)
Seems it might be using a look up table internally, Get_Random_Int() calls Random2Class::operator()(void) for the object FreeRandom which in turn uses member data initialized in the Random2Class constructor which calls Random3Class RNG functions to initialize some member data.

There's a check to reset a member variable to 0 if it's higher than 249 in Random2Class::operator()(void) so..

edit: yeah it's using a lookup table

int __cdecl Random2Class__Random2Class(int a1, int a2)
{
  signed int v2; // ebx@1
  int result; // eax@2
  char v4; // [sp+Ch] [bp-14h]@1

  *(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 4) = 103;
  Random3Class__Random3Class(&v4, a2, 0);
  v2 = 0;
  do
  {
    result = Random3Class__operator__(&v4);
    *(_DWORD *)(a1 + 4 * v2++ + 8) = result;
  }
  while ( v2 <= 249 );
  return result;
}


Long time and well respected Renegade community member, programmer, modder and tester.

Scripts 4.0 private beta tester since May 2011.

My Renegade server plugins releases

[Updated on: Sun, 12 August 2012 14:21]

Report message to a moderator

Re: Commands->Get_Random_Int() is of very poor quality [message #473086 is a reply to message #473077] Sun, 12 August 2012 14:25 Go to previous messageGo to next message
Xpert is currently offline  Xpert
Messages: 1588
Registered: December 2005
Location: New York City
Karma: 0
General (1 Star)
Also, crates like DEPOINTS and DEMONEY doesn't work in SSGM 2.0.2 and SSGM 4.0 because if you do something like

int RndGood = Commands->Get_Random_Int(1,2);

The random number will always be "1".


If it was like

int RndGood = Commands->Get_Random_Int(1,3);

Then the result will either be "1" or "2".


I did the above in my crates plugin to get those crates to work.


http://i32.photobucket.com/albums/d42/XpertMaverick/xpertyankee.jpg

Creator of NetGuard, an IRC network regulator.
Developer of the CloudyServ 0.982-X project.
Developer of the CloudyServ Ren-X bot.

Part time streamer - https://twitch.tv/gg_wonder
Re: Commands->Get_Random_Int() is of very poor quality [message #473088 is a reply to message #473077] Sun, 12 August 2012 15:10 Go to previous messageGo to next message
iRANian is currently offline  iRANian
Messages: 4308
Registered: April 2011
Karma: 0
General (4 Stars)
Random2Class consists of:

int FirstIndex;
int SecondIndex;
int NumberArray[249]; 


The constructor sets FirstIndex to 0, SecondIndex to 103 and fills NumberArray with random numbers from Random3Class::operator().

Random2Class::operator() works like:

int Ret = NumberArray[SecondIndex] ^ NumberArray[FirstIndex];
NumberArray[FirstIndex] = Ret;

FirstIndex++;
SecondIndex++;

if (FirstIndex > 249)
{ FirstIndex = 0; }

if (SecondIndex > 249)
{ SecondIndex = 0; }

return Ret;
} 


And Get_Random_Int() works like:

int __cdecl Get_Random_Int(int Low, int High)
{
  RealLow = Low;
  RealHigh = High;
  if ( Low > High )
  {
    RealLow = High;
    RealHigh = Low;
  }
  return RealLow + (Random2Class__operator__(FreeRandom) & 0x7FFFFFFF) % (RealHigh - RealLow);
}


Long time and well respected Renegade community member, programmer, modder and tester.

Scripts 4.0 private beta tester since May 2011.

My Renegade server plugins releases

[Updated on: Sun, 12 August 2012 15:11]

Report message to a moderator

Re: Commands->Get_Random_Int() is of very poor quality [message #473089 is a reply to message #473077] Sun, 12 August 2012 15:14 Go to previous message
iRANian is currently offline  iRANian
Messages: 4308
Registered: April 2011
Karma: 0
General (4 Stars)
RealLow + (Random2Class__operator__(FreeRandom) & 0x7FFFFFFF) % (RealHigh - RealLow);


if RealLow = 1 and RealHigh = 2 we get

 1 + random number % (2 - 1)


Which always returns 1 as anything modulus (2-1) is 0, 0 + 1 = 1.


Long time and well respected Renegade community member, programmer, modder and tester.

Scripts 4.0 private beta tester since May 2011.

My Renegade server plugins releases
Previous Topic: Crash dump
Next Topic: flame tank right click
Goto Forum:
  


Current Time: Sun Dec 22 13:34:50 MST 2024

Total time taken to generate the page: 0.00702 seconds