.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   Random_long(0, ??) (http://forums.bots-united.com/showthread.php?t=223)

Pierre-Marie Baty 07-01-2004 15:01

Re: Random_long(0, ??)
 
the frame time reported by the engine is unreliable, that was one of the problems.

Rob, I don't know at all how to use clock() nor generic timers - at all, but I would be very interested in doing something similar. Would you mind posting the code you are using for this (hopefully it will be simple enough for me to understand it all) or am I just a bugger and do you honestly think I need to search on my own ? :D (might be, too)

koraX 07-01-2004 15:57

Re: Random_long(0, ??)
 
AFAIK clock() function http://msdn.microsoft.com/library/de..._crt_clock.asp returns processor time used by calling process, so you can't get real time.

For high precision timing, I would use QueryPerformanceCounter http://msdn.microsoft.com/library/de...ncecounter.asp which is btw used in such time sensitive programs as midi sequencers

Pierre-Marie Baty 07-01-2004 16:11

Re: Random_long(0, ??)
 
I don't care about microseconds, really... I just want to find a convenient, self-contained replacement for gpGlobals->time :)

koraX 07-01-2004 16:21

Re: Random_long(0, ??)
 
Quote:

Originally Posted by Pierre-Marie Baty
I don't care about microseconds, really... I just want to find a convenient, self-contained replacement for gpGlobals->time :)

the question is what gpGlobals->time should do, measure 'real time' or 'game time' (pause game, alt-tab, server laggging, how should gpGlobals->time behave)

Pierre-Marie Baty 07-01-2004 16:56

Re: Random_long(0, ??)
 
AFAIK, gpGlobals->time returns the time in seconds since the server booted on a new map, no kludges...

BTW, for the original question, I found a very sophisticated random number generator on the net ! The problem with rand() is that it can only return 16-bit integers, you can't do real 32-bit number generation using rand() ; however some sound libraries use extremely well shaped random number generators for generating sound noise, they are definitely worth a look.

botmeister 07-01-2004 18:29

Re: Random_long(0, ??)
 
PMB, you are correct, a 16 bit random value may not be enough for some applications. For better random number generation, I found this library GNU licensed http://www.agner.org/random/ I have not tried it yet, but it looked pretty good on first glance.

As for gpGlobals->time I once tried using it to get the remaining time of a map with no luck, so it is not even good for doing that. If anyone knows how to get a reliable "timeleft" value (engine side, not client) let me know.

For many apps, clock( ) gives sufficient resolution which is about 1/1000 of a second. But I can see some apps needing a lot more resolution.

The QueryPerformanceCounter is very interesting - thanks for mentioning this one. I'm trying to find out how it is implemented. It appears to be based on CPU frequency, or it could be based on a hardware frequency counter. If you can point me to a document that describes how the value is generated I'd appreciate it.

NOTE: I'm mostly interested in protable code using ANSI C++ because whatever timer I use has to be made portable at least to Linux.

PBM, I have a lot of code for doing my timer class - too much for a post in here I think. I'll post this main function to give you an idea what I'm doing.

Code:

tinTicks tclCPUClock::finGetTickCount( )
{
// On error clock returns -1;
tinTicks vinCurTickCount = clock( );
if ( vinRollOverCount < 0 )
vinRollOverCount = 0;
if ( vinPrevTickCount < 0 )
goto locExitPoint;
 
if ( vinPrevTickCount > vinCurTickCount )
// the clock has rolled over;
{
if ( vinRollOverCount == cinMaxRollOverCount )
// NOTE: This condition will NEVER happen because the roll over period is
// at least 24 days, which adds up to 5 million years by the time the
// maximum rollover count is exceeded;
        vinRollOverCount = 0;
else
        ++vinRollOverCount;
}
locExitPoint:
{
vinPrevTickCount = vinCurTickCount;
return vinCurTickCount;
}
} // tclCPUClock::finGetTickCount

tinTicks is of type 32 bit integer. To calculate how many ticks in a second, you divide your clock tick count by the constant CLK_TCK which should be found in time.h

I added a rollover check to make sure I don't get a bad hicup if my code is left running for more than 24 days.

Pierre-Marie Baty 07-01-2004 19:03

Re: Random_long(0, ??)
 
Quote:

Originally Posted by botmeister
PMB, you are correct, a 16 bit random value may not be enough for some applications. For better random number generation, I found this library GNU licensed http://www.agner.org/random/ I have not tried it yet, but it looked pretty good on first glance.

...and I have posted something new in this forum too *hint* *hint* ;)

Quote:

As for gpGlobals->time I once tried using it to get the remaining time of a map with no luck, so it is not even good for doing that. If anyone knows how to get a reliable "timeleft" value (engine side, not client) let me know.
The map cycle time is stored in a CVAR, which I don't remember the name. Have you tried to look for it with the "cvarlist" console command ? Once you know this CVAR's name, you can predict the remaining time using gpGlobals->time this way:
  • In ServerActivate(), do something like: gflNextMapChangeTime = gpGlobals->time + CVAR_GET_FLOAT ("sv_mapcycletime"); // assuming sv_mapcycletime is the name of your CVAR
  • Then each time you want to know the remaining time, do something like: flTimeRemaining = gflNextMapChangeTime - gpGlobals->time;
This should give you the remaining time in seconds. Redo the same substraction each time you want to know the remaining time.


Quote:

The QueryPerformanceCounter is very interesting - thanks for mentioning this one. I'm trying to find out how it is implemented. It appears to be based on CPU frequency, or it could be based on a hardware frequency counter. If you can point me to a document that describes how the value is generated I'd appreciate it.
Joe has written a whole in-game, visual, graphical code profiler using QueryPerformanceCounters and such, you should ask him :)


Quote:

NOTE: I'm mostly interested in protable code using ANSI C++ because whatever timer I use has to be made portable at least to Linux.
Unfortunately I believe QueryPerformanceStuff is Win32-specific stuff only.

About the code you posted, your idea to keep track of the rollover count is great ; however I think I'll stick with simpler stuff for now, until I understand exactly how this clock thingy works :) But thanks anyway !

botmeister 07-01-2004 19:55

Re: Random_long(0, ??)
 
Quote:

Originally Posted by Pierre-Marie Baty
The map cycle time is stored in a CVAR, which I don't remember the name. Have you tried to look for it with the "cvarlist" console command ? Once you know this CVAR's name, you can predict the remaining time using gpGlobals->time this way:
  • In ServerActivate(), do something like: gflNextMapChangeTime = gpGlobals->time + CVAR_GET_FLOAT ("sv_mapcycletime"); // assuming sv_mapcycletime is the name of your CVAR
  • Then each time you want to know the remaining time, do something like: flTimeRemaining = gflNextMapChangeTime - gpGlobals->time;
This should give you the remaining time in seconds. Redo the same substraction each time you want to know the remaining time.

The CVAR is mp_timelimit

I thought I tried exactly what your are suggesting, but I messed around with the code so many times I can't be sure anymore. Perhaps I used the engine time function instead of the gpGlobals->time value? I'll give it another try - thanks :)

Quote:

Joe has written a whole in-game, visual, graphical code profiler using QueryPerformanceCounters and such, you should ask him :)


Unfortunately I believe QueryPerformanceStuff is Win32-specific stuff only.
That is why I'm wondering how it is implemented. If we can find out then perhaps a pottable version could possibly be built *edit* pun not intended :)

Quote:

About the code you posted, your idea to keep track of the rollover count is great ; however I think I'll stick with simpler stuff for now, until I understand exactly how this clock thingy works :) But thanks anyway !
Uh? This from the same guy who figured out how to process a BSP tree and compute all walkable surfaces! :) If you need more help with this one just ask, I'll be happy to help out.

The clock() thing is very simple without rollover. It just returns the number of clock ticks (~1000 per second) since the calling process started. To time something, you just get the clock() count for the start time, and later get the clock() end time. Then you compute the difference of the start time with the end time giving you the number of elapsed clock ticks. To get this in seconds, just divide by 1000 (better to use CLK_TCK).

What I did was create a timer class so I could set up multiple independant timers. I do something like vclTimer.fvoStart(10) to start counting up to 10 seconds, and I can check if the timer has timedout or not with a simple boolen function, example if ( vclTimer.fbTimedout() ) { // press the fire button else keep waiting }

From this timing function, you can create a generic system for doing timed events that get triggered after a certain period of time elapses. Doing that will simplify realtime programming by a huge factor.

@$3.1415rin 29-03-2004 18:54

Re: Random_long(0, ??)
 
just got back to this thread by the search function ...

just to mention : QueryPerformanceCounter is based on the hardware clock, running at ~1Mhz I think. so it is _not_ based on the cpu clock


All times are GMT +2. The time now is 08:55.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.