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.