AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   [HELP] Stock select random players without repeating (https://forums.alliedmods.net/showthread.php?t=342960)

MeliMeli 06-01-2023 19:03

[HELP] Stock select random players without repeating
 
Hello, can someone give me an example of how I can create a stock that selects random players without repeating them? For example, Player 1 cannot be Player 2, and if they are, the stock should find another player who is not Player 1. It would be useful to create an array and add the IDs of these players to that array. If any of them disconnect from the server, their ID should be removed from the array.

EFFx 06-02-2023 00:41

Re: [HELP] Stock select random players without repeating
 
Needs some testing.

PHP Code:

#include <amxmodx>

#define PLUGIN "A stock that selects random players without repeating them"
#define VERSION "1.0"
#define AUTHOR "author"

new bool:g_bAlreadySelected[MAX_PLAYERS 1]

public 
plugin_init() 
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
    
register_clcmd("say /find""getRandomPlayer")
}

public 
client_disconnected(idg_bAlreadySelected[id] = false

public getRandomPlayer(id)
{
    new 
iPlayer findRandomPlayer(1)
    
log_amx("Debug: Random player selected: %n"iPlayer)
}

findRandomPlayer(iIncludeBots)
{
    new 
iPlayers[MAX_PLAYERS], iNumiPlayersNotSelected[MAX_PLAYERS], iPlayersFoundiRandomPlayer
    get_players
(iPlayersiNumiIncludeBots "h" "ch")
    for(new 
iiPlayer;iNum;i++)
    {
        if(!
g_bAlreadySelected[(iPlayer iPlayers[i])])
        {
            
iPlayersNotSelected[iPlayersFound++] = iPlayer
        
}
    }
    
    
// At this point, all players must have been selected already
    // If so, select a random player to restart the cicle
    
if(!iPlayersFound)
    {
        
g_bAlreadySelected[(iRandomPlayer iPlayers[random(iNum)])]
        
resetAllPlayers(iIncludeBots)
        return 
iRandomPlayer
    
}
    
    
g_bAlreadySelected[(iRandomPlayer iPlayersNotSelected[random(iPlayersFound)])] = true
    
return iRandomPlayer
}

resetAllPlayers(iIncludeBots)
{
    new 
iPlayers[MAX_PLAYERS], iNum
    get_players
(iPlayersiNumiIncludeBots "h" "ch")
    for(new 
i;iNum;i++)
    {
        
g_bAlreadySelected[i] = false
    
}



fysiks 06-02-2023 01:50

Re: [HELP] Stock select random players without repeating
 
I would probably use the functions provided by Bugsy here. Doing something like this:

PHP Code:

#include <amxmodx>

new const Version[] = "0.1";

//Set this to the absolute max random number that you will attempt to generate.
const MaxRandom 32;

new 
AllNumbers[ ( MaxRandom >> ) + ];

public 
plugin_init()
{
    
register_plugin"Random Number No Dupes" Version "bugsy/fysiks" );
    
register_concmd("randplayers""cmdGetRandomPlayers", .info=" - <number of random players>")
}

public 
cmdGetRandomPlayers(id)
{
    new 
iPlayers[32], iPlayerCountszName[32]
    
get_players(iPlayersiPlayerCount)

    new 
szArg[3], iCount
    read_argv
(1szArgcharsmax(szArg))
    
iCount min(str_to_num(szArg), iPlayerCount)
    
    
PrepRandom(iPlayerCount 1);

    for( new 
iCount i++ )
    {
        
get_user_name(GetRandom(0iPlayerCount 1), szNamecharsmax(szName))
        
console_print(id"Random player: %s"szName);
    }
}

// Source:  https://forums.alliedmods.net/showpost.php?p=2417667&postcount=7
PrepRandomiRanMin iRanMax )
{
    for ( new 
iRanMin <= iRanMax i++ )
        
AllNumbers>> ] |= ( << );
}

public 
GetRandomiRanMin iRanMax )
{
    static 
UsedNumbers[ ( MaxRandom >> ) + ];
    new 
iRandom bool:bAllUsed=true;

    if ( 
iRanMax MaxRandom )
        
set_fail_state"Must increase MaxRandom value: %d > %d" iRanMax MaxRandom );

    
//Check if all numbers have already bee nused, if so this will reset the 'used' variable.
    
for ( new sizeofUsedNumbers ) ; i++ )
    {
        if ( 
AllNumbers] && ( AllNumbers] != UsedNumbers] ) )
        {
            
bAllUsed false;
            break;
        }
    }

    
//If all random numbers have already been used, reset variable so they can be re-used.
    
if ( bAllUsed )
        
arraysetUsedNumbers sizeofUsedNumbers ) );

    
//Find random number
    
do
    {
        
iRandom random_numiRanMin iRanMax );
    }
    while ( ( 
UsedNumbersiRandom >> ] & ( << iRandom ) ) )

    
//Set current random number as used
    
UsedNumbersiRandom >> ] |= ( << iRandom );

    
//Return random number
    
return iRandom;


I'm not able to test it but I think it's mostly there.


All times are GMT -4. The time now is 10:23.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.