[Question]
  [
This [king-of-the-hill](/questions/tagged/king-of-the-hill "show questions tagged 'king-of-the-hill'") challenge is based off of the game show, [Weakest Link](https://en.wikipedia.org/wiki/Weakest_Link). For those unfamiliar with the show, **the crux of this challenge deals with who you vote off**:
* If the other players are smarter than you, then you have less of a chance of getting the pot.
* If the other players are dumber than you, then you have less of a pot to get.
At the start of each round, the *Pot* starts out with $0. A group of 9 players is formed, and each player is given a unique *Smartness* from 1 to 9.
At the start of each turn, `Pot += Smartness` for each player still in the round. Then, players vote on the player they wish to remove. The player with the most votes is removed. In case of a tie, the smarter player is kept.
When there are only 2 players are left in the round, they face off in a battle of wits. The chance of the player winning is `Smartness/(Smartness+OpponentSmartness)`. The winning player then receives the entire pot.
The player who has received the most money at the end of the game wins.
# Input / Output
Each turn, you will receive the current list of opponents. You will have access to your smartness and **all players' entire voting history** for the round via functions in the Player class.
As output, you must return a single integer, representing the player you wish to vote for (representing their smartness). Voting for yourself *is* allowed (but not recommended).
Rounds of 9 will repeat until all players have played at least ~~1000~~10000 rounds, and all players have played in the same number of rounds.
You can find the controller here: <https://github.com/nathanmerrill/WeakestLink>
To create a player, you need to extend the Player class, and add your player to the PlayerFactory class. Your class must follow the following rules:
1. Communication or interference with any other player (include your other players of the same type) is strictly prohibited.
2. Reflection and static variables (except for constants) are not allowed.
3. If you want to use randomness, I have provided a `getRandom()` function in the Player class. Use it, so simulations can be deterministic.
I have provided many functions in the Player class for easy access to data. You can find them online [on Github](https://github.com/nathanmerrill/WeakestLink/blob/master/src/WeakestLink/Players/Player.java). Your player will be instantiated each new round. "Dumb/suicidal" players are allowed (but not players with the same strategy).
# Scores
```
377195  WeakestLink.Players.PrudentSniper
362413  WeakestLink.Players.Sniper
353082  WeakestLink.Players.VengefulSniper
347574  WeakestLink.Players.AntiExtremist
298006  WeakestLink.Players.BobPlayer
273867  WeakestLink.Players.MedianPlayer
247881  WeakestLink.Players.TheCult
240425  WeakestLink.Players.Leech
235480  WeakestLink.Players.SniperAide
223128  WeakestLink.Players.Guard
220760  WeakestLink.Players.Anarchist
216839  WeakestLink.Players.RevengePlayer
215099  WeakestLink.Players.IndependentVoter
213883  WeakestLink.Players.SniperKiller
210653  WeakestLink.Players.MaxPlayer
210262  WeakestLink.Players.Bandwagon
209956  WeakestLink.Players.MeanPlayer
208799  WeakestLink.Players.Coward
207686  WeakestLink.Players.Spy
204335  WeakestLink.Players.Hero
203957  WeakestLink.Players.MiddleMan
198535  WeakestLink.Players.MinPlayer
197589  WeakestLink.Players.FixatedPlayer
197478  WeakestLink.Players.HighOrLowNotSelf
181484  WeakestLink.Players.RandomPlayer
165160  WeakestLink.Players.BridgeBurner
```
  
[Answer]
## Sniper
The general idea is to keep around one of the *stupid players* (i.e. ones we are more likely to beat in the face-off) to snipe for the points. After that we try to remove the other low-value players to raise the pot. But when we get to the intelligent players we opt to remove for the most dangerous ones in case our *stupid player* gets removed. That way if we don't have someone to snipe we should get someone we at least stand a chance against. Also, since we always vote with either a min or max player, I expect we are fairly effective in getting our way.
```
package WeakestLink.Players;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class Sniper extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        //count number of players smarter/stupider than me
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=10, max_smrt=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > smrt){
                cnt_smrt++;
                if(opp_smrt > max_smrt) max_smrt = opp_smrt;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
                if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            }
        }
        //remove low-value, then dangerous players
        if(cnt_stpd>1)
            return min_stpd;
        else
            return max_smrt;
    }
}
```
[Answer]
# PrudentSniper
[Sniper](https://codegolf.stackexchange.com/a/65427/6828), but with two special-case behaviors. One is that if there are three bots left, and PrudentSniper is the smartest, it will vote for the middle bot instead of the least smart. This allows it to win a few more showdowns. The other behavior is that if the smartest bot is gunning for it (voted for it or the analogous bot last time) and the least smart isn't, it will vote for the smartest in self defense.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class PrudentSniper extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        //count number of players smarter/stupider than me, find max/min
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=10, max_smrt=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > max_smrt) max_smrt = opp_smrt;
            if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            if(opp_smrt > smrt){
                cnt_smrt++;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
            }
        }
        //identify enemies
        Iterator<Vote> votes = getRecentVotes().iterator();
        boolean[] voted_for_me = new boolean[9];
        while(votes.hasNext()) {
          Vote opp_vote = votes.next();
          voted_for_me[opp_vote.getVoter()] = (opp_vote.getVoted() == getSmartness() ||
                                              (opp_vote.getVoted() < getSmartness() && cnt_stpd < 1) ||
                                              (opp_vote.getVoted() > getSmartness() && cnt_smrt < 1));
        }
        if (currentOpponents.size() < 3 || cnt_stpd < 2 || (voted_for_me[max_smrt] && !voted_for_me[min_stpd] && cnt_smrt > 0) )
          return max_smrt;
        else
          return min_stpd;
    }
}
```
[Answer]
## TheCult
The cult players have a mildly esoteric voting scheme by which they attempt to identify each other and vote as a group, using only the voting record. Since each member of the cult knows how to vote, anyone who votes differently is revealed as a non-member and eventually targeted for elimination.
**The voting scheme at a glance:**
* on the first turn vote for weakest contestant, working in concert with min & sniper helps the cult gain power
* on subsequent turns vote off known non-members until only the cult remains (we vote off the lowest-value non-member to rack up points as long as we think we are in control).
* when only members remain, vote off low-value members for points (indeed sacrificing yourself for the good of the cult).
**The Code:**
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Iterator;
import java.util.Set;
public class TheCult extends Player {
    private int cult_vote;
    private boolean[] isMember = null;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        //on first turn, vote the code
        if(isMember == null){
            isMember = new boolean[10];
            for(int i=10; --i!=0;) isMember[i]=true; //runs 9-1
            return cult_vote = 1;
        }
        //on all other turn, assess who is not voting with the cult
        Vote opp_vote;
        int cult_cnt=0;
        Iterator<Vote> votes = getRecentVotes().iterator();
        while(votes.hasNext()){
            opp_vote = votes.next();
            if(opp_vote.getVoted() != cult_vote)
                isMember[opp_vote.getVoter()] = false;
            else
                cult_cnt++;
        }
        //find weakest and stongest non-members, and weakest members
        Iterator<Integer> opps = currentOpponents.iterator();
        int opp_smrt, min_mem=10, min_non=10, max_non=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(isMember[opp_smrt]){
                if(opp_smrt < min_mem) min_mem = opp_smrt;
            }else{
                if(opp_smrt < min_non) min_non = opp_smrt;
                if(opp_smrt > max_non) max_non = opp_smrt;
            }
        }
        if(cult_cnt>2 && min_non!=10) cult_vote = min_non;
        else if(max_non!=0)           cult_vote = max_non;
        else                          cult_vote = min_mem;
        return cult_vote;
    }
}
```
**Final Thoughts:**
The cult now switch's to voting for the most dangerous players when there are only two or fewer cult-members remaining for the face-off. I tested it several times with `cult_cnt>1` and `cult_cnt>2` conditions and the later wins more often.
Still, this is a precaution and the cult really isn't designed to work as lone player, so as the number of new players increase the cult should still lose eventually.
[Answer]
# BridgeBurner
Not somewhere where I can test this right now, and this came out feeling like really ugly/dumb code, but it *should* work.
This bot just wants to be hated. It votes for whoever has voted against it the *least*. In the event of a tie, it picks whoever has gone the longest without voting for it. In the event of another tie, it picks the smartest of those (presumably because they will make the worst enemy). It will not vote for itself, because no one will really hate it when it's not around.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BridgeBurner extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        List<Integer> votes_against = Stream.generate(() -> 0).limit(9).collect(Collectors.toList());
        List<Integer> last_voted_against = Stream.generate(() -> 0).limit(9).collect(Collectors.toList());
        Iterator<Vote> votes_against_me = getVotesForSelf().iterator();
        
        for (int c = 0; c < 9; c++){
            if (!currentOpponents.contains(c)){
                votes_against.set(c,-1);
                last_voted_against.set(c,-1);
            }
        }
        
        while(votes_against_me.hasNext()){
            Vote vote = votes_against_me.next();
            int voter = vote.getVoter();
            int round = vote.getRound();
            if (currentOpponents.contains(voter)){
                votes_against.set(voter, votes_against.get(voter)+1);
                last_voted_against.set(voter, Math.max(round, last_voted_against.get(voter)));
            } else {
                votes_against.set(voter, -1);
                last_voted_against.set(voter, -1);
            }
        }
        int min_tally = Collections.max(votes_against);
        for (int c = 0; c < 9; c++){
            int current_tally = votes_against.get(c);
            if (current_tally != -1 && current_tally < min_tally){
                min_tally = current_tally;
            }
        }
        
        if (Collections.frequency(votes_against, min_tally) == 1){
            return votes_against.indexOf(min_tally);
        } else {
            List<Integer> temp_last_against = new ArrayList<>();
            for (int c = 0; c < 9; c++){
                if (votes_against.get(c) == min_tally){
                    temp_last_against.add(last_voted_against.get(c));
                }
            }
            return last_voted_against.lastIndexOf(Collections.min(temp_last_against));
        }
    }
}
```
[Answer]
# Bandwagon
Follows the crowd in voting, unless he's the one being targeted.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Map;
import java.util.Set;
/**
 * Votes for the currently most voted bot in the game. Or the lowest one.
 */
public class Bandwagon
        extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int self = getSmartness(), vote = -1;
        java.util.Map<Integer, Integer> votes = new java.util.TreeMap<>();
        getVotingHistory().stream().map((Vote v)-> v.getVoted()).filter((Integer i)-> !i.equals(self)).forEach((Integer tgt)-> {
            if(!votes.containsKey(tgt)) {
                votes.put(tgt, 1);
            } else {
                votes.put(tgt, votes.get(tgt) + 1);
            }
        });
        do {
            if(votes.entrySet().isEmpty()) {
                vote = currentOpponents.stream().filter((Integer i)-> !i.equals(self)).sorted().findFirst().get();
            } else {
                if(votes.containsKey(vote)) {
                    votes.remove(vote);
                    vote = -1;
                }
                for(Map.Entry<Integer, Integer> vv: votes.entrySet()) {
                    Integer key = vv.getKey();
                    Integer value = vv.getValue();
                    if((vote == -1) || (value > votes.get(vote))) {
                        vote = key;
                    }
                }
            }
        } while(!currentOpponents.contains(vote));
        return vote;
    }
}
```
I'm guessing this one will just make snipers stronger by following them, but also avoids being targeted by the cult and sniper-aides in a slightly effective manner. It may as well be a meatshield for sniper killers or aid them if there's more of them. (Need to test with the latest updates).
Using java 8 features because the game needs that to run anyway.
[Answer]
# RevengePlayer
This bot will vote for whoever voted for him the most times, tiebreaker being the smartest player. The theory is that a player that voted for you in the past will likely vote for you again.
```
package WeakestLink.Players;
import java.util.Collections;
import java.util.Set;
import java.util.Iterator;
import WeakestLink.Game.Vote;
public class RevengePlayer extends Player{
    @Override
    public int vote(Set<Integer> opponents) {
        int[] A;
        A = new int[10];
        for(int i = 1;i < 10;i++)
            A[i] = opponents.contains(i)? i+1 : 0;
        Set<Vote> H = getVotingHistory();
        Iterator<Vote> I = H.iterator();
        while(I.hasNext()){
            Vote v = I.next();
            if(v.getVoted() == getSmartness())
                A[v.getVoter()] += A[v.getVoter()] != 0?10:0;
        }
        int maxI = 0;
        for(int i = 1;i < 10;i++)
            if(A[i] > A[maxI])
                maxI = i;
        return maxI;
    }
}
```
[Answer]
# MeanPlayer
Vote neither the stupidest nor the smartest players, and he's carrying a gun (sneaked it past security)
```
public class MeanPlayer extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int mid = currentOpponents.size() / 2;
        Object[] sortedOpponents = currentOpponents.toArray();
        Arrays.sort(sortedOpponents);
        return (int) sortedOpponents[mid];
    }
}
```
[Answer]
# AntiExtremist
This extreme socialist believes that all people should be of equal smartness. He tries to kill those who are much smarter or dumber than he is. He considers both but he favors dumb in general. He favors dumb people in the beginning and smart in the end, but it's weighted based on how extreme those people are.
```
package WeakestLink.Players;
import java.util.Arrays;
import java.util.Set;
public class AntiExtremist extends Player {
    Object[] currentPlayers;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        currentPlayers = (Object[]) currentOpponents.toArray();
        Arrays.sort(currentPlayers);
        int smartness = getSmartness();
        int turns = getTurnNumber();
        //// Lets get an idea of who's smart and who's dumb ////
        int smarter = 0, dumber = 0;
        int max_smart = 0, min_smart = 10;
        currentOpponents.toArray();
        for (int i = 0; i < currentPlayers.length; i++) {
            int osmart = (int)currentPlayers[i];
            if (osmart == smartness)
                continue;
            if (osmart > smartness) {
                smarter++;
                if (osmart > max_smart)
                    max_smart = osmart;
            }
            else if (osmart < smartness) {
                dumber++;
                if (osmart < min_smart)
                    min_smart = osmart;
            }
        }
        // int total = smarter+dumber;
        double smarter_ratio = smarter > 0 ? (max_smart-smartness)/4.5 : 0; 
        double dumber_ratio = dumber > 0 ? (smartness-min_smart)/3.0 : 0;//Favor dumber
        smarter_ratio*=.25+(turns/9.0*.75);
        dumber_ratio*=1-(turns/8.0*.75);
        return smarter_ratio > dumber_ratio ? max_smart : min_smart;
    }
}
```
**NOTE:** According to Linus this will vote the same as sniper the vast majority of the time (525602:1228).
[Answer]
# MedianPlayer
This player attempt to be the meanest (well, medianness) one left.
It votes to eliminate the smartest and dumbest opponents (with a slight bias towards voting off the smartest), depending on if there are more or less smarter/dumber than themself.
```
package WeakestLink.Players;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class MedianPlayer extends Player {
  @Override
  public int vote(Set<Integer> currentOpponents) {
    int smrt = getSmartness();
    //count number of players smarter/stupider than me
    Iterator<Integer> opps = currentOpponents.iterator();
    int cnt_smrt=0, cnt_stpd=0, min_stpd=10, max_smrt=0;
    while(opps.hasNext()){
      int opp_smrt = opps.next().intValue();
      if(opp_smrt > smrt){
        cnt_smrt++;
        if(opp_smrt > max_smrt)
          max_smrt = opp_smrt;
      } else if(opp_smrt < smrt){
        cnt_stpd++;
        if(opp_smrt < min_stpd)
          min_stpd = opp_smrt;
      }
    }
    // the middle must hold
    if(cnt_stpd>cnt_smrt)
      return min_stpd;
    else
      return max_smrt;
  }
}
```
framework blatantly stolen from @Linus above.
[Answer]
# Coward
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class Coward extends Player {
  @Override
  public int vote(Set<Integer> currentOpponents) {
    boolean[] currentOpponent = new boolean[10];
    Iterator<Integer> opps = currentOpponents.iterator();
    while(opps.hasNext()){
      currentOpponent[opps.next().intValue()] = true;
    }
    int[] voteCounts = new int[9];
    for(int i=0; i<9; i++) {
        voteCounts[i] = 0;
    }
    Iterator<Vote> votes = getRecentVotes().iterator();
    while(votes.hasNext()){
      Vote opp_vote = votes.next();
      if(currentOpponent[opp_vote.getVoter()])
        voteCounts[opp_vote.getVoted()] += 1;
      else
        voteCounts[opp_vote.getVoter()] += 100;
    }
    int previous_weakest = -1;
    int max_votes_gotten = 0;
    for(int i=0;i<9;i++){
      if (voteCounts[i] > max_votes_gotten) {
        max_votes_gotten = voteCounts[i];
        previous_weakest = i;
      }
    }
    int min_closeness = 10;
    int to_vote = -1;
    int opp;
    int closeness;
    opps = currentOpponents.iterator();
    while(opps.hasNext()){
      opp = opps.next();
      closeness = Math.abs(opp - previous_weakest);
      if(closeness <= min_closeness) {
        to_vote = opp;
        min_closeness = closeness;
      }
    }
    return to_vote;
  }
}
```
Just doesn't want to get voted off, so votes for the opponent most similar to the player that got voted off last round in order to maximize the chance of being on the winning team.
Doesn't do particularly well right now, but might as well throw it in the mix.
[Answer]
# Hero
Votes off those who pick on the weak ... or annoy him.
```
package WeakestLink.Players;
import WeakestLink.Game.Game;
import WeakestLink.Game.Vote;
import java.util.*;
/**
 * Created by thenumberone on 12/2/15.
 * @author thenumberone
 */
public class Hero extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int me = getSmartness();
        Set<Vote> history = getVotingHistory();
        history.removeIf(vote -> !currentOpponents.contains(vote.getVoter()) || vote.getVoter() == me);
        int[] evilnessLevel = new int[Game.NUMBER_PLAYERS_PER_ROUND];
        for (Vote vote : history){
            evilnessLevel[vote.getVoter()] += vote.getVoted() == me ? 1_000_000 : Game.NUMBER_PLAYERS_PER_ROUND - vote.getVoted();
        }
        int mostEvilOpponent = -1;
        for (int opponent : currentOpponents){
            if (mostEvilOpponent == -1 || evilnessLevel[opponent] > evilnessLevel[mostEvilOpponent]){
                mostEvilOpponent = opponent;
            }
        }
        return mostEvilOpponent;
    }
}
```
[Answer]
## Bob
Bob is just the average guy that thinks he is smarter then he really is. 
Cannot win the *sniper* family but get top 5 in my simulations most of the time.
```
package WeakestLink.Players;
import java.util.Collections;
import java.util.Set;
import WeakestLink.Game.Vote;
public class BobPlayer extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smartness;
        // Bob sometimes thinks he is smarter than he really is
        if (getRandom().nextInt(10) == 0) {
            smartness = 10;
        } else {
            smartness = getSmartness();
        }
        // If there is still some competition
        if (currentOpponents.size() > 3) {
            // And Bob is the dumbest
            if (smartness < Collections.min(currentOpponents)) {
                // Go for the smartest one
                return Collections.max(currentOpponents);
                // But if he is the smartest
            } else if (smartness > Collections.max(currentOpponents)) {
                // Go for the weak link
                return Collections.min(currentOpponents);
            } else {
                // Else revenge!
                for (Vote v : getRecentVotes()) {
                    if (v.getVoted() == smartness && currentOpponents.contains(v.getVoter())) {
                        return v.getVoter();
                    }
                }
            }
            return Collections.min(currentOpponents);
        } else {
            //If there are few opponents just revenge!
            for (Vote v : getRecentVotes()) {
                if (v.getVoted() == smartness && currentOpponents.contains(v.getVoter())) {
                    return v.getVoter();
                }
            }
            return Collections.max(currentOpponents);
        }
    }
}
```
[Answer]
# FixatedPlayer
Picks a random target, then votes for them until they're gone. Won't vote for himself though.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.*;
public class FixatedPlayer extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int self = getSmartness();
        Vote previous_vote = getLastVote();
        if (previous_vote == null || !currentOpponents.contains(previous_vote.getVoted())){
            return (int) currentOpponents.toArray()[getRandom().nextInt(currentOpponents.size())];
        }
        else {
            return previous_vote.getVoted();
        }
    }
}
```
[Answer]
# Spy
Spy is reserved. He doesn't like to gun for the smartest people. Likewise, he doesn't like picking on ~~quartata~~ defenseless idiots. So, he likes to eliminate those closest to him in smartness.
```
package WeakestLink.Players;
import java.util.Iterator;
import java.util.Set;
public class Spy extends Player{
  @Override
  public int vote(Set<Integer> currentOpponents) {
    int selfIntel = getSmartness();
    int closestIntel = 100; // default
    // get closest player
    Iterator<Integer> enemies = currentOpponents.iterator();
    while(enemies.hasNext()){
      int enemyIntel = enemies.next().intValue();
      if(Math.abs(enemyIntel - selfIntel) < closestIntel) closestIntel = enemyIntel;
    }
    return closestIntel;
  }
}
```
You've just been backstabbed, *mes amis*. He doesn't care if he wins. He just like the sound of the knife in your back as he votes you off successfully.
[![You've just been backstabbed.](https://i.stack.imgur.com/RRBpO.jpg)](https://i.stack.imgur.com/RRBpO.jpg)
[Answer]
# Statistics
This is not an entry to the contest. This is merely a way to get useful statistics of a game. These statistics print off the percentage likelihood that a particular player will be voted off in a round.
To do this add the following lines to `Round.java` so that the top of the file looks like this:
```
package WeakestLink.Game;
import WeakestLink.Players.Player;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Round {
    private static int[][] statistics = new int[Game.NUMBER_PLAYERS_PER_ROUND - 2][Game.NUMBER_PLAYERS_PER_ROUND + 1];
    private static int[] counts = new int[Game.NUMBER_PLAYERS_PER_ROUND - 2];
    static {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            for (int i = 0; i < Game.NUMBER_PLAYERS_PER_ROUND - 2; i++){
                System.out.println();
                System.out.println("For " + (i+1) + "th round:");
                for (int j = 1; j <= Game.NUMBER_PLAYERS_PER_ROUND; j++){
                    System.out.println(String.format("%f%% voted for %d", 100.0*statistics[i][j]/counts[i], j));
                }
            }
        }));
    }
...
```
Then modify the vote method to look like this:
```
private Vote vote(Player player){
    player.setVotingHistory(new HashSet<>(votes));
    player.setTurnNumber(currentTurn);
    player.setPot(pot);
    Set<Integer> players = currentPlayers.stream()
            .filter(p -> p != player)
            .map(playerToSmartness::get)
            .collect(Collectors.toSet());
    int vote = player.vote(players);
    if (!currentPlayers.contains(smartnessToPlayer.get(vote))){
        throw new RuntimeException(player.getClass().getSimpleName()+" voted off non-existent player");
    }
    Vote v = new Vote(playerToSmartness.get(player), vote, currentTurn);
    counts[v.getRound()]++;
    statistics[v.getRound()][v.getVoted()]++;
    return v;
}
```
Example Output:
```
For 1th round:
55.554756% voted for 1
4.279166% voted for 2
1.355189% voted for 3
1.778786% voted for 4
3.592771% voted for 5
3.952368% voted for 6
1.779186% voted for 7
6.427149% voted for 8
21.280630% voted for 9
For 2th round:
2.889877% voted for 1
34.080927% voted for 2
6.826895% voted for 3
4.990010% voted for 4
5.914753% voted for 5
4.985510% voted for 6
3.302524% voted for 7
11.304360% voted for 8
25.705144% voted for 9
For 3th round:
2.152783% voted for 1
13.005153% voted for 2
21.399772% voted for 3
7.122286% voted for 4
6.122008% voted for 5
6.761774% voted for 6
11.687049% voted for 7
19.607500% voted for 8
12.141674% voted for 9
For 4th round:
2.122183% voted for 1
10.105719% voted for 2
11.917105% voted for 3
17.547460% voted for 4
8.626131% voted for 5
12.079103% voted for 6
18.819449% voted for 7
11.065111% voted for 8
7.717738% voted for 9
For 5th round:
1.689826% voted for 1
7.364821% voted for 2
9.681763% voted for 3
11.704946% voted for 4
20.336237% voted for 5
20.691914% voted for 6
13.062855% voted for 7
9.332565% voted for 8
6.135071% voted for 9
For 6th round:
1.456188% voted for 1
6.726546% voted for 2
10.154619% voted for 3
16.355569% voted for 4
22.985816% voted for 5
17.777558% voted for 6
11.580207% voted for 7
7.757938% voted for 8
5.205558% voted for 9
For 7th round:
1.037992% voted for 1
6.514748% voted for 2
15.437876% voted for 3
22.151823% voted for 4
17.015864% voted for 5
14.029088% voted for 6
11.907505% voted for 7
7.957136% voted for 8
3.947968% voted for 9
```
[Answer]
# MaxPlayer
A know-it-all. Prefers to remove anybody with high-intelligence (who can therefore challenge his unmatched intellect)
```
public class MaxPlayer extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        return Collections.max(currentOpponents);
    }
}
```
[Answer]
# Guard
Votes off those that pick on the strong ... or those that annoy him.
```
package WeakestLink.Players;
import WeakestLink.Game.Game;
import WeakestLink.Game.Vote;
import java.util.Set;
/**
 * Created by thenumberone on 12/2/15.
 * @author thenumberone
 */
public class Guard extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int me = getSmartness();
        Set<Vote> history = getVotingHistory();
        history.removeIf(vote -> !currentOpponents.contains(vote.getVoter()) || vote.getVoter() == me);
        int[] evilnessLevel = new int[Game.NUMBER_PLAYERS_PER_ROUND];
        for (Vote vote : history){
            evilnessLevel[vote.getVoter()] += vote.getVoted() == me ? 1_000_000 : vote.getVoted();
        }
        int mostEvilOpponent = -1;
        for (int opponent : currentOpponents){
            if (mostEvilOpponent == -1 || evilnessLevel[opponent] > evilnessLevel[mostEvilOpponent]){
                mostEvilOpponent = opponent;
            }
        }
        return mostEvilOpponent;
    }
}
```
[Answer]
# Leech
Relies on other bots to vote the smartest and dumbest guys off.. sort of.
He is satisfied with turning up somewhere in the middle and eventually splitting the pot with the winner (since he is actually a really decent ~~guy~~ bot).
```
package WeakestLink.Players;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
public class Leech extends Player {
    /**
     * Copyrighted (not really, use this however you want friends) by Sweerpotato :~)!
     */
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int mySmartness = getSmartness();
        
        ArrayList<Integer> opponentSmartness = new ArrayList<Integer>();
        opponentSmartness.addAll(currentOpponents);
        opponentSmartness.add(mySmartness);
        Collections.sort(opponentSmartness);
        
        if(mySmartness > 4 && mySmartness > Collections.min(opponentSmartness)) {
            //There's somebody dumber than me, vote that dude off
            return opponentSmartness.get(opponentSmartness.indexOf(mySmartness) - 1);
        }
        else {
            //Vote off the smartest guy, so we have a better chance to win
            if(mySmartness == Collections.max(opponentSmartness)) {
                //Apparently, we're the smartest guy
                return opponentSmartness.get(opponentSmartness.indexOf(mySmartness) - 1);
            }
            else {
                return Collections.max(opponentSmartness);
            }
        }
    }
}
```
[Answer]
# SniperKiller
[Another](https://codegolf.stackexchange.com/a/65479/31203) answer shamelessly stolen from [Linus's code](https://codegolf.stackexchange.com/a/65595/31203). This one in will kill all snipers, not protect them. If it knows that no snipers are left it will act like a sniper itself.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class SniperKiller extends Player {
    boolean[] sniperish;
    int[] sniperwouldvote;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        currentOpponents.add(smrt);
        if(sniperish==null){
            sniperish = new boolean[10];
            sniperwouldvote = new int[10];
            for(int i=10;--i!=0;){
                sniperish[i] = true;
                sniperwouldvote[i] = 1;
            }
            sniperish[smrt]=false; //knows we are not the sniper
            return 1;
        }
        //figure out who isn't a sniper
        Vote opp_vote;
        int opp_smrt;
        Iterator<Vote> votes = getRecentVotes().iterator();
        while(votes.hasNext()){
            opp_vote = votes.next();
            opp_smrt = opp_vote.getVoter();
            if(opp_vote.getVoted() != sniperwouldvote[opp_smrt])
                sniperish[opp_smrt] = false;
        }
        //figure out how snipers would vote this round
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_opp=0, min_opp=10, max_opp=0;
        int[] snpr_votes = new int[10];
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(smrt == opp_smrt) continue;
            sniperwouldvote[opp_smrt] = hypothetically(opp_smrt, currentOpponents);
            cnt_opp++;
            if(sniperish[opp_smrt]){
                snpr_votes[sniperwouldvote[opp_smrt]]++;
            }
            if(opp_smrt<min_opp) min_opp=opp_smrt;
            if(opp_smrt>max_opp) max_opp=opp_smrt;
        }
        for(int i = 1;i<10;i++){//hit the weakest sniper.
            if(sniperish[i] && currentOpponents.contains(i))
                return i;
        }
        return hypothetically(smrt, currentOpponents);
    }
    private int hypothetically(int smrt, Set<Integer> currentOpponents) {
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=10, max_smrt=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > smrt){
                cnt_smrt++;
                if(opp_smrt > max_smrt) max_smrt = opp_smrt;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
                if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            }
        }
        if(cnt_stpd>1) return min_stpd;
        return max_smrt;
    }
}
```
[Answer]
# RandomPlayer
```
public class RandomPlayer extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        return (int) currentOpponents.toArray()[getRandom().nextInt(currentOpponents.size())];
    }
}
```
[Answer]
# MinPlayer
An Elitist. Prefers to remove anybody with low intelligence.
```
public class MinPlayer extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        return Collections.min(currentOpponents);
    }
}
```
[Answer]
## HighOrLowNotSelf
Removes randomly lowest or highest intelligence player (but not self).
```
public class HighOrLowNotSelf extends Player{
    @Override
    public int vote(Set<Integer> ops) {
        int b=Math.round(Math.random()*1);
        int p;
        if(b==1) p=Collections.max(ops) else p=Collections.min(ops);
        if(p==getSmartness()) {
            return vote(ops);
        }
        return p;
    }
}
```
[Answer]
# VengefulSniper
This started as something I *thought* was original called `StupidBuffering` (a name I hated to give up), then ended up being just a PrudentSniper who didn't care if he was being targeted. This also seemed to be the only reason he couldn't beat PrudentSniper, so I tweaked things around a bit to make that his focus.
Now, this is basically a sniper, but if the smartest or dumbest bot targets him, he will target whichever one got the most votes last round. If they both got the same number of votes and both targeted him, he goes back to normal sniper-y behavior. In my tests, this actual beats PrudentSniper on occasion.
```
package WeakestLink.Players;
import java.util.*;
import WeakestLink.Game.Vote;
public class VengefulSniper extends Player{
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int me = getSmartness();
        int smartOpp = Collections.max(currentOpponents);
        int dumbOpp = Collections.min(currentOpponents);
        int votesAgainstSmart=0, votesAgainstDumb=0;
        Boolean targetedBySmart = false, targetedByDumb = false;
        
        Set<Vote> votesForMe = getRecentVotes();
        Iterator<Vote> votes = votesForMe.iterator();
        while(votes.hasNext()){
            Vote vote = votes.next();
            int voter = vote.getVoter();
            int voted = vote.getVoted();
            
            if(voted == me){
                if(voter == smartOpp){
                    targetedBySmart = true;
                }
                if(voter == dumbOpp){
                    targetedByDumb = true;
                }
            } else if (voted == smartOpp){
                votesAgainstSmart++;
            } else if (voted == dumbOpp){
                votesAgainstDumb++;
            }
        }
        // If being targeted by smartest or dumbest, take them out
        // Try to go with the rest of the crowd if they both targeted me
        if(targetedBySmart ^ targetedByDumb){
            return targetedBySmart ? smartOpp : dumbOpp;
        } else if (targetedBySmart && targetedByDumb){
            if (votesAgainstSmart > votesAgainstDumb){
                return smartOpp;
            } else if (votesAgainstDumb > votesAgainstSmart){
                return dumbOpp;
            }
        }
        
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_stpd=0;
        while(opps.hasNext()){
            int opp_smrt = opps.next().intValue();
            if(opp_smrt < me){
                cnt_stpd++;
            }
        }
        
        if (cnt_stpd < 2 || (currentOpponents.size() < 4)){ //buffer is small, protect myself
            return smartOpp;
        } else {
            return dumbOpp;
        }
    }
}
```
[Answer]
# MiddleMan
The MiddleMan trys his best to maximize profits while keeping a wary eye that he's not cut from the game. He keeps around lesser contestants to improve his chance of making it to the next round (and to leave an easy finish). He will vote off someone smarter than him only if there are more smarter contestants than there are lesser contestants. Whichever of the two groups, he always votes for the lowest of the group to keep the pot climbing.
```
package WeakestLink.Players;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class MiddleMan extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        //count number of players smarter/stupider than me
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=9, min_smrt=9;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > smrt){
                cnt_smrt++;
                if(opp_smrt < min_smrt) min_smrt = opp_smrt;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
                if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            }
        }
        //Keep myself in the middle of the pack, favoring the point earners
        if(cnt_stpd>cnt_smrt)
            return min_stpd;
        else
            return min_smrt;
    }
}
```
P.S. hope it compiles, I'm not a Java guy.
Had this scheme in mind before reading the other entries. Then I was surprised how close (but critically different) [Sniper](https://codegolf.stackexchange.com/a/65427/47078) was so I went ahead and used that as a jumping off point since I don't know Java syntax. Thanks @Linus
[Answer]
# ApproximatePosition
This bot is trying to shooting approximately around the missing smartness values, assuming that the group will continue with the same pattern, meaning it will target the same type of target. It always vote for the smartest of two player when there's a choice.
Long time I didn't use Java, and currently at work so... Can't test it, hope it's not too buggy, be gentle please :).
By the way, it uses awt.Point only because I'm too lazy to implement a tuple n\_n.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.*;
import java.awt.Point;
public class ApproximatePosition extends Player
{
    @Override
    public int vote(Set<Integer> currentOpponent)
    {
        List<Integer> present = new ArrayList<>(currentOpponent);
        List<Integer> emptyPosition = new ArrayList<Integer>();
        Collections.sort(present);
        //If it is the first round, vote for the smartest buddy
        if(present.size()==8)
            return present.get(present.size()-1);
        int lastCheck=present.get(0);
        if(lastCheck>0)
            for(int i=0;i<lastCheck;i++)
                if(i!=getSmartness()&&!emptyPosition.contains(i))
                    emptyPosition.add(i);
        for(int i=1;i<present.size();i++)
        {
            if(present.get(i)-lastCheck>1)
                for (int j=lastCheck+1;j<present.get(i);j++)
                    if(j!=getSmartness()&&!emptyPosition.contains(j))
                        emptyPosition.add(j);
            lastCheck=present.get(i);
        }
        //untill there's at least 3 excluded members, we continue with this behaviour
        if(emptyPosition.size()<=2)
        {
            if(emptyPosition.isEmpty()) return present.get(present.size()-1);
            return decide(emptyPosition.get(0),present.get(present.size()-1),present.get(0),present);
        }
        Point maxRangeOfBlank=new Point(present.get(present.size()-1),present.get(present.size()-1));
        for (int i=0;i<emptyPosition.size()-1;i++)
            if(emptyPosition.get(i+1)-emptyPosition.get(i)==1)
            {
                int size=0;
                while(i+size+1<emptyPosition.size() && emptyPosition.get(i+size+1)-emptyPosition.get(i+size)==1)
                    size++;
                if(size>=sizeOfRange(maxRangeOfBlank))
                    maxRangeOfBlank=new Point(emptyPosition.get(i),emptyPosition.get(size));
                i+=size;
            }
        return decide(maxRangeOfBlank,present.get(present.size()-1),present.get(0),present);
    }
    private int decide(int blankSeat, int smartest,int dumbest,List<Integer> present)
    {
        return decide(new Point(blankSeat,blankSeat),smartest,dumbest,present);
    }
    private int decide(Point rangeBlankSeat, int smartest,int dumbest,List<Integer> present)
    {
        int target= smartest;
        if (rangeBlankSeat.getY()==smartest||((int)rangeBlankSeat.getY()+1)==getSmartness()){
            if ((rangeBlankSeat.getX()==dumbest||(int)rangeBlankSeat.getX()-1==getSmartness())){
                target= smartest; //should not happen
            } else {
                target= (int) rangeBlankSeat.getX()-1; //Vote for dumber than the missing
            }
        } else {
            target= (int) rangeBlankSeat.getY() +1; //Vote for smarter than the missing, default comportment
        }
        if(present.contains(target))
            return target;
        return smartest;
    }
    //Return the number of consecutive values between X and Y (included)
    private int sizeOfRange(Point range)
    {
        return (int)(range.getY()-range.getX())+1;
    }
}
```
[Answer]
## SniperAide
Before the addition of [PrudentSniper](https://codegolf.stackexchange.com/questions/65420/you-are-the-weakest-link-goodbye#65587) I wrote a bot to help [Sniper](https://codegolf.stackexchange.com/questions/65420/you-are-the-weakest-link-goodbye#65427) beat [AntiExtremist](https://codegolf.stackexchange.com/questions/65420/you-are-the-weakest-link-goodbye#65499) and other *frauds* (I use the word with love). The bot, SniperAide, looks for players who vote like snipers and votes as it thinks they would when there is a consensuses. If all players look like snipers he votes for the max, protecting lower Snipers (who would also switch to the max at this point), even if it is himself.
**The Code**:
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class SniperAide extends Player {
    boolean[] sniperish;
    int[] sniperwouldvote;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        if(sniperish==null){
            sniperish = new boolean[10];
            sniperwouldvote = new int[10];
            for(int i=10;--i!=0;){
                sniperish[i] = true;
                sniperwouldvote[i] = 1;
            }
            sniperish[smrt]=false; //knows we are not the sniper
            return 1;
        }
        //figure out who might isn't a sniper
        Vote opp_vote;
        int opp_smrt;
        Iterator<Vote> votes = getRecentVotes().iterator();
        while(votes.hasNext()){
            opp_vote = votes.next();
            opp_smrt = opp_vote.getVoter();
            if(opp_vote.getVoted() != sniperwouldvote[opp_smrt])
                sniperish[opp_smrt] = false;
        }
        //include ourself in the simulation of other snipers.
        currentOpponents.add(smrt);
        //figure out how snipers would vote this round
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_snpr=0, cnt_opp=0, min_opp=10, max_opp=0;
        int[] snpr_votes = new int[10];
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(smrt == opp_smrt) continue;
            sniperwouldvote[opp_smrt] = hypothetically(opp_smrt, currentOpponents);
            cnt_opp++;
            if(sniperish[opp_smrt]){
                cnt_snpr++;
                snpr_votes[sniperwouldvote[opp_smrt]]++;
            }
            if(opp_smrt<min_opp) min_opp=opp_smrt;
            if(opp_smrt>max_opp) max_opp=opp_smrt;
        }
        //figure out how to vote in sniper's intrest when not identified
        if(cnt_snpr == cnt_opp)
            return max_opp;
        if(cnt_snpr == 0)
            return hypothetically(smrt, currentOpponents);
        //if multiple hypothetical snipers only vote how they agree
        int onlyvote = -1;
        for(int i=10; --i!=0;){
            if(onlyvote>0 && snpr_votes[i]!=0) onlyvote=-2;
            if(onlyvote==-1 && snpr_votes[i]!=0) onlyvote=i;
        }
        if(onlyvote>0) return onlyvote;
        return max_opp;
    }
    private int hypothetically(int smrt, Set<Integer> currentOpponents) {
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=10, max_smrt=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > smrt){
                cnt_smrt++;
                if(opp_smrt > max_smrt) max_smrt = opp_smrt;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
                if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            }
        }
        if(cnt_stpd>1) return min_stpd;
        return max_smrt;
    }
}
```
He currently is not much help against PrudentSniper.
[Answer]
# IndependentVoter
This bot knows that the general population is always wrong! So it votes for whoever is getting the least votes.
Code is nearly Identical to SolarAaron's "Bandwagon", but the end logic is flipped.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Map;
import java.util.Set;
/**
 * Votes for the currently lest voted bot in the game.
 * Or the lowest one.
 */
public class IndependentVoter
        extends Player {
    @Override
    public int vote(Set<Integer> currentOpponents) {
        int self = getSmartness(), vote = -1;
        java.util.Map<Integer, Integer> votes = new java.util.TreeMap<>();
        getVotingHistory().stream().map((Vote v)-> v.getVoted()).filter((Integer i)-> !i.equals(self)).forEach((Integer tgt)-> {
            if(!votes.containsKey(tgt)) {
                votes.put(tgt, 1);
            } else {
                votes.put(tgt, votes.get(tgt) + 1);
            }
        });
        do {
            if(votes.entrySet().isEmpty()) {
                vote = currentOpponents.stream().filter((Integer i)-> !i.equals(self)).sorted().findFirst().get();
            } else {
                if(votes.containsKey(vote)) {
                    votes.remove(vote);
                    vote = -1;
                }
                for(Map.Entry<Integer, Integer> vv: votes.entrySet()) {
                    Integer key = vv.getKey();
                    Integer value = vv.getValue();
                    if((vote == -1) || (value < votes.get(vote))) {
                        vote = key;
                    }
                }
            }
        } while(!currentOpponents.contains(vote));
        return vote;
    }
}
```
[Answer]
# Anarchist
The anarchist doesn't like regimes.  
The anarchist will try to kill the current president.  
If the anarchist is president, he decides to abuse his power and kill useless peagents. Unless he was targeted by one of his inferiors, for they should burn instead.
```
package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.LinkedList;
import java.util.Set;
public class Anarchist extends Player {
    LinkedList<Integer> opponents;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        opponents = new LinkedList();
        opponents.addAll(currentOpponents);
        opponents.sort(Integer::compare);
        int me = getSmartness();
        if (getPresident() != me) {
            return getPresident();
        } else {
            // treason ?
            Vote voteForMe = getRecentVotes().stream().filter(v -> v.getVoted() == me).findAny().orElse(null);
            if (voteForMe == null) {
                // No treason ! Hurray. Kill the peagants.
                return getPeagant();
            } else {
                // TREASON!
                return opponents.get(opponents.indexOf(voteForMe.getVoter()));
            }
        }
    }
    private int getPresident() {
        return opponents.getLast();
    }
    private int getPeagant() {
        return opponents.getFirst();
    }
}
```
]