SA-MP Forums Archive
Get a random player in range of position using loops - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+--- Thread: Get a random player in range of position using loops (/showthread.php?tid=462028)



Get a random player in range of position using loops - iJumbo - 04.09.2013

Hi.

Is there a good way to get a random player in range of a position whitout get stuck in infinite loops?


i tryed

pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    Start:
    new randPlayer = Iter_Random(Player);
    randPlayer = (IsPlayerInRangeOfPoint(randPlayer,Range,X,Y,Z) ? randPlayer : 255;
    if(randPlayer == 255) goto Start;
    else return randPlayer;
}
but im not sure what you think?


Re: Good way to - Vince - 04.09.2013

Never, ever, ever use goto. Do-While would be an appropriate structure here.

However, I'd just do a general loop and add all players that are in range to a new iterator. Then pick a random player from the newly created iterator.


Re: Good way to - iJumbo - 04.09.2013

I know that goto is not very well handled by the compiler

You mean something like that ?
pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    new randPlayer;
    do {
        randPlayer = Iter_Random(Player);
        randPlayer = (IsPlayerInRangeOfPoint(randPlayer,Range,X,Y,Z) ? randPlayer : 255;
    }
    while (randPlayer == 255);
    return randPlayer;
}
Never ever used do-while loops


Re: Good way to - Kar - 05.09.2013

Quote:
Originally Posted by Vince
Посмотреть сообщение
Never, ever, ever use goto. Do-While would be an appropriate structure here.
Com'n, don't say that. I use goto alot. It's just how you use it


Re: Good way to - CyNiC - 05.09.2013

Quote:
Originally Posted by iJumbo
Посмотреть сообщение
I know that goto is not very well handled by the compiler

You mean something like that ?
pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    new randPlayer;
    do {
        randPlayer = Iter_Random(Player);
        randPlayer = (IsPlayerInRangeOfPoint(randPlayer,Range,X,Y,Z) ? randPlayer : 255;
    }
    while (randPlayer == 255);
    return randPlayer;
}
Never ever used do-while loops
I think that's need to declare 'randPlayer' as 255 or nothing will happen.


Re: Get a random player in range of position using loops - Pottus - 05.09.2013

It's all about your steps.

1) Get all players into a list that are in range of point
2) Was any players found?
No - Return INVALID_PLAYER_ID;
Yes - Proceed to step 3
3) How many players?
One player - return ID
Two players - return random ID

That gives a basic algorithm of steps to perform.

I didn't test pretty sure I got it right based on the above steps

pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    // List of in range players
    new InRangeList[MAX_PLAYERS] = { INVALID_PLAYER_ID, ... };

    // How many in range players there is
    new InRangeCount;
   
    // Gather in range players (Change this to foreach()
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
        if(IsPlayerConnected(i))
        {
            if(IsPlayerInRangeOfPoint(i, range, X, Y, Z)) InRangeList[InRangeCount++] = i;
        }
    }

    // There are players in range
    if(InRangeCount)
    {
        // Only one? Return that ID
        if(InRangeCount == 1) return InRangeList[0];
        // More than one return a random ID
        else
        {
            new r = Random(InRangeCount);
            return InRangeList[r];
        }
    }
    // No one in range return INVALID_PLAYER_ID
    return INVALID_PLAYER_ID;
}



Re: Get a random player in range of position using loops - iJumbo - 05.09.2013

Quote:
Originally Posted by [uL]Pottus
Посмотреть сообщение
It's all about your steps.

1) Get all players into a list that are in range of point
2) Was any players found?
No - Return INVALID_PLAYER_ID;
Yes - Proceed to step 3
3) How many players?
One player - return ID
Two players - return random ID

That gives a basic algorithm of steps to perform.

I didn't test pretty sure I got it right based on the above steps

pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    // List of in range players
    new InRangeList[MAX_PLAYERS] = { INVALID_PLAYER_ID, ... };

    // How many in range players there is
    new InRangeCount;
   
    // Gather in range players (Change this to foreach()
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
        if(IsPlayerConnected(i))
        {
            if(IsPlayerInRangeOfPoint(i, range, X, Y, Z)) InRangeList[InRangeCount++] = i;
        }
    }

    // There are players in range
    if(InRangeCount)
    {
        // Only one? Return that ID
        if(InRangeCount == 1) return InRangeList[0];
        // More than one return a random ID
        else
        {
            new r = Random(InRangeCount);
            return InRangeList[r];
        }
    }
    // No one in range return INVALID_PLAYER_ID
    return INVALID_PLAYER_ID;
}
I think my version is much smaller than your but yea i can do like that too

Quote:
Originally Posted by CyNiC
Посмотреть сообщение
I think that's need to declare 'randPlayer' as 255 or nothing will happen.
You're right xD


Re: Get a random player in range of position using loops - CaveDweller - 05.09.2013

pawn Код:
stock GetRandomPlayerInRange(Float:x, Float:y, Float:z, Float:range)
{
    // Define a new iterator with a size of MAX_PLAYERS (all players in the server could potentially be in range of the point)
    new Iterator:PlayersNearPoint<MAX_PLAYERS>;

    // Loop through all players in the server
    foreach(new p : Player)
    {
        // If the current player is in range of the point
        if(IsPlayerInRangeOfPoint(p, range, x, y, z)
        {
            // Then add their id (p) to the iterator (PlayersNearPoint)
            Iter_Add(PlayersNearPoint, p);
        }
    }

    // If Iter_Count(PlayersNearPoint) is 0, then return INVALID_PLAYER_ID. If it isn't 0, then return a random value from the iterator
    return (Iter_Count(PlayersNearPoint) == 0) ? INVALID_PLAYER_ID : Iter_Random(PlayersNearPoint);
}
You'll need to download YSI for it to work. I've documented the code so you can understand it easier.


Re: Get a random player in range of position using loops - iJumbo - 05.09.2013

Thanks for your code and i already use YSI as you can see in my post
Iter_Random(Player);
pawn Код:
stock GetRandomPlayerInRange(Float:X,Float:Y,Float:Z,Float:Range)
{
    new randPlayer;
    do {
        randPlayer = Iter_Random(Player);
        randPlayer = (IsPlayerInRangeOfPoint(randPlayer,Range,X,Y,Z) ? randPlayer : 255;
    }
    while (randPlayer == 255);
    return randPlayer;
}



Re: Get a random player in range of position using loops - CaveDweller - 05.09.2013

Quote:
Originally Posted by iJumbo
Посмотреть сообщение
Thanks for your code and i already use YSI as you can see in my post
Iter_Random(Player);
Ah, sorry! I didn't notice that and thought I'd better mention the YSI requirement.