-1

I have 6 players, each player has a field called Karma. It can go from -1000 to 1000. If the player has 0 karma, their chances are normal, 1000 is very likely. Here is my current method of picking a special player.

List<String> players = new ArrayList<String>();
for (Player p : getOnlinePlayers() {
    players.add(p.getName());
}
Player p = getPlayer(players.get(new Random().nextInt(players
        .size())));
while (sherrifs.contains(p.getName())) {
    p = Bukkit.getPlayer(players.get(new Random().nextInt(players
            .size())));
}
special = p;

This currently does not include the karma but I was thinking of adding the player 1 time for each karma they have, but that would be really inefficient if all 6 players had 1000 karma which would mean, each name is entered 1000 times. Also this wouldn't work with -1000 karma since the name has to be entered at least once. How can I increase and decreasing the chances of a player being picked depending on their karma?

InfIV
  • 15
  • 6

2 Answers2

0

Take a look here. It should be helpful enough. If you would do Usman Ismali's method I would recommend you to add 1001 karma to each player (only when selecting random player). Else it would be impossible for a player with -980 karma to be selected. Example:

class Player {
    int prob;
}

class RandomPlayer {
    List<Player> players;

    RandomPlayer(List<Player> players) {
        this.players = players;
    }

    public Player getPlayer() {
        int sum = 0;

        for (Player p : players)
            sum += p.prob + 1001;

        int random = new Random().nextInt(sum);

        int i = 0;
        int sum2 = 0;

        while(sum2 < index) 
             sum2 = sum2 + players.get(i++).prob;

        return players.get(Math.max(0,i-1));
    }
}
Mibac
  • 8,990
  • 5
  • 33
  • 57
0

Create a List<Double> with numbers computed by adding the relative chances. Picking a player is done by locating the interval or "share" of a player.

// code for creating the list
private List<Player> players = ...;
private List<Double> chances = new ArrayList<>();
private double acc;

public void createChances(){
    acc = 0.0;
    for( Player player: players ){
        acc += (player.getKarma() + 1001)/2000.0;
        chances.add( acc );
    }
}

// code for using the list
private Random random = new Random();

// pick a player
public Player pick(){
    Player picked;
    double rc = random.nextDouble()*acc;
    for( int ic = 0; ic < chances.size(); ++ic ){
        if( rc < chance.get(ic) ){
            picked = players.get(ic);
            break;
        }
    return picked;
}
laune
  • 31,114
  • 3
  • 29
  • 42
  • I think that the need of computing a (relative) probability from the funny Karma values warrants at least part of a new answer, but I'm willing to delete my answer if folks think that this is marginal. – laune Jun 20 '15 at 13:30