SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Filterscripts

Reply
 
Thread Tools Display Modes
Old 05/10/2017, 08:12 PM   #4661
BigETI
Gangsta
 
BigETI's Avatar
 
Join Date: Mar 2010
Location: Germany
Posts: 923
Reputation: 208
Default Re: Useful Functions

Why "CallLocalFunction"? Why not just call the function itself (recursion) or better make a non recursive function from that?
BigETI is online now   Reply With Quote
Old 09/10/2017, 03:28 AM   #4662
pabloalber84ban
Little Clucker
 
Join Date: Jun 2016
Posts: 35
Reputation: 0
Default Re: Useful Functions

Quote:
Originally Posted by RoW001 View Post
About that RandomPlayer function you can use this.
Code:
GetRandomPlayer()
{
    new iPlayer = -1, iID = random(GetPlayerPoolSize());
    for(new i = 0; i < GetPlayerPoolSize(); i++){
        if(!IsPlayerConnected(i)) continue;
        if(iID == i){
            iPlayer = i;
        } else {
            CallLocalFunction("GetRandomPlayer", "");
        }
    }
    return iPlayer;
}
Code:
GetRandomPlayer(loop=3)
{
    RandomCase:
    loop--;
    if(loop < 0)return -1;
    new iID = random(GetPlayerPoolSize());
    if(IsPlayerConnected(iID))return iID;
    else goto RandomCase;
}
pabloalber84ban is offline   Reply With Quote
Old 09/10/2017, 09:02 AM   #4663
[HLF]Southclaw
High-roller
 
[HLF]Southclaw's Avatar
 
Join Date: Apr 2009
Location: England
Posts: 4,713
Reputation: 1255
Default Re: Useful Functions

Or, with y_iterate/foreach: Iter_Random(Player);
[HLF]Southclaw is offline   Reply With Quote
Old 22/10/2017, 10:10 AM   #4664
Admireal
Little Clucker
 
Join Date: Sep 2016
Posts: 46
Reputation: 0
Default Re: Useful Functions

Code:
new randomplayer = random(GetPlayerPoolSize());
Admireal is offline   Reply With Quote
Old 22/10/2017, 11:20 AM   #4665
RIDE2DAY
Big Clucker
 
RIDE2DAY's Avatar
 
Join Date: Jul 2015
Location: Sicily, Italy
Posts: 124
Reputation: 234
Default Re: Useful Functions

Quote:
Originally Posted by pabloalber84ban View Post
Code:
GetRandomPlayer(loop=3)
{
    RandomCase:
    loop--;
    if(loop < 0)return -1;
    new iID = random(GetPlayerPoolSize());
    if(IsPlayerConnected(iID))return iID;
    else goto RandomCase;
}
It should be like this tho:
PHP Code:
new iID randomGetPlayerPoolSize() + 1); 
random returns values between 0 and "max - 1", GetPlayerPoolSize returns the highest player ID in use on the server.

EDIT - @OneDay:
Try to compile it, you'll get a nice error. I tried to give an answer in context, anyway, [HLF]Southclaw mentioned Iter_Random just a few comments above!

I know y_iterate would be the way to go (I'm using it actually) but as pawnoholic said: not many people use YSI. So, you might use something like this:

PHP Code:
new bool:g_ConnectedPlayers[MAX_PLAYERS char];

public 
OnPlayerConnect(playerid)
{
    
g_ConnectedPlayers{playerid} = true;
    return 
1;
}

public 
OnPlayerDisconnect(playerid)
{
    
g_ConnectedPlayers{playerid} = false;
    return 
1;
}

GetRandomPlayer()
{
    new 
idx;
    new 
true_list[MAX_PLAYERS];

    for(new 
0GetPlayerPoolSize(); tx++)
    {
        if(!
g_ConnectedPlayers{x}) continue;

        
true_list[idx] = x;
        
idx++;
    }

    if(
idx)
    {
        return 
true_list[random(idx)];
    }

    return 
INVALID_PLAYER_ID;

That's just something I wrote here now, I guess there must be a more efficient way for doing it.
__________________

Last edited by RIDE2DAY; 22/10/2017 at 02:09 PM.
RIDE2DAY is offline   Reply With Quote
Old 22/10/2017, 12:15 PM   #4666
[HLF]Southclaw
High-roller
 
[HLF]Southclaw's Avatar
 
Join Date: Apr 2009
Location: England
Posts: 4,713
Reputation: 1255
Default Re: Useful Functions

Stop doing meaningless iterations! Build a list of connected players first then simply randomly choose from that list. Iterating through players then doing a `continue;` if the player isn't connected is possibly the worst way to do it.
[HLF]Southclaw is offline   Reply With Quote
Old 22/10/2017, 12:38 PM   #4667
OneDay
Huge Clucker
 
Join Date: Sep 2015
Posts: 240
Reputation: 65
Default Re: Useful Functions

Quote:
Originally Posted by RIDE2DAY View Post
It should be like this tho:
PHP Code:
new iID randomGetPlayerPoolSize() + 1); 
random returns values between 0 and "max - 1", GetPlayerPoolSize returns the highest player ID in use on the server.
It should be like this tho:

PHP Code:
new iID Iter_Random(Player); 
It is the fastest already.
OneDay is offline   Reply With Quote
Old 22/10/2017, 12:46 PM   #4668
pawnoholic
Little Clucker
 
Join Date: Oct 2017
Posts: 23
Reputation: 0
Default Re: Useful Functions

Quote:
Originally Posted by OneDay View Post
It should be like this tho:

PHP Code:
new iID Iter_Random(Player); 
It is the fastest already.
Not everyone uses y_iterate (foreach)

My not recursive version:

PHP Code:
ReturnRandomPlayer()
{
    new 
        
lastPlayer GetPlayerPoolSize();

    for (new 
random(lastPlayer 1); lastPlayeri++)
    {
        if (
IsPlayerConnected(i))
        {
            return 
i;
        }
    }
    return -
1;

__________________
GitHub: @pawnoholic

Last edited by pawnoholic; 23/10/2017 at 12:12 PM.
pawnoholic is offline   Reply With Quote
Old 27/10/2017, 04:49 PM   #4669
[HLF]Southclaw
High-roller
 
[HLF]Southclaw's Avatar
 
Join Date: Apr 2009
Location: England
Posts: 4,713
Reputation: 1255
Default Re: Useful Functions

Quote:
Originally Posted by pawnoholic View Post
Not everyone uses y_iterate (foreach)

My not recursive version:

PHP Code:
ReturnRandomPlayer()
{
    new 
        
lastPlayer GetPlayerPoolSize();

    for (new 
random(lastPlayer 1); lastPlayeri++)
    {
        if (
IsPlayerConnected(i))
        {
            return 
i;
        }
    }
    return -
1;

Quote:
Originally Posted by [HLF]Southclaw View Post
Stop doing meaningless iterations! Build a list of connected players first then simply randomly choose from that list. Iterating through players then doing a `continue;` if the player isn't connected is possibly the worst way to do it.
Again, same mistake: If player ID 990 is online and no one else is then you could actually hang the server for a meaningful amount of time. (Yes I know this is an extreme example but you should always keep these kinds of scenarios in mind and evaluate whether or not they truly affect your program at runtime!)

The main thing to learn from this is: predictability. I can not effectively predict the performance of the function because there's no way to predict how many times that for loop could run. The solution below is predictable and is simply a linear function of the highest possible player ID (MAX_PLAYERS).

Here's the best way to do it without foreach:

Code:
stock GetRandomPlayer() {
	new
		online[MAX_PLAYERS],
		total;

	for(new i, j = GetPlayerPoolSize(); i < j; ++i) {
		if(IsPlayerConnected(i)) {
			online[total++] = i;
		}
	}

	if(total == 0) {
		return INVALID_PLAYER_ID;
	}

	return online[random(total)];
}

The obvious evolution of this method would be to simply store a global list of online players and only update it when a player connects or disconnects - that's effectively how the foreach Player iterator works. This way you don't need to calculate the entire list every time because it already exists.

But since that would be more of a snippet than a pure function, this is the quick and dirty alternative - which doesn't really matter if both usage frequency of the function and the player count is low.

If your server is highly populated AND you are calling this function a LOT then I'd advise looking into either foreach or simply storing a up-to-date global list of players. But for all other use-cases, this is fine.
[HLF]Southclaw is offline   Reply With Quote
Old 09/11/2017, 05:11 AM   #4670
m1n1vv
Little Clucker
 
m1n1vv's Avatar
 
Join Date: May 2013
Posts: 24
Reputation: 5
Default Re: Useful Functions

strequal Fix

strequal - is a function, which compares string variables and values. Returns non-zero if the strings are equal. Fixed probability of a positive result in one blank line, and negative when it's two.

PHP Code:
stock bool:strequal(const string1[], const string2[], bool:ignorecase falselength cellmax)
{
    new
        
s1 string1[0],
        
s2 string2[0];
            
    if ((
s1 == '\0' || s2 == '\0') && (s1 != s2))
        return 
false;
            
    return 
strcmp(string1string2ignorecaselength) == 0;

Example:

PHP Code:
main()
{
    new
        
str_1[12] = "Hello World",
        
str_2[12] = "Hello World",
        
bool:inequality strequal(str_1str_2);

    
printf("%i"inequality); //inequality = 1

m1n1vv is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Functions? sciman001 Help Archive 7 19/03/2011 04:03 PM
How to get functions? Twain32 Help Archive 4 08/10/2010 08:37 PM
[Include] [INC] SA:MP New Functions 0.4a DKN ipsBruno Lançamentos/Releases 22 17/06/2010 09:38 AM
[Include] [INC] LSF - Lorenc's Simple Functions (w/ gang/clan functions) Lorenc_ Includes 11 03/05/2010 10:47 PM
What this functions do? harrold Help Archive 2 09/05/2009 12:30 AM


All times are GMT. The time now is 03:47 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.