Você é o elo mais fraco, adeus


50

Este desafio do é baseado no game show, Weakest Link . Para aqueles que não estão familiarizados com o programa, o cerne desse desafio lida com quem você vota :

  • Se os outros jogadores são mais espertos que você, você tem menos chances de ganhar o pote.
  • Se os outros jogadores são mais burros que você, você tem menos pote para ganhar.

No início de cada rodada, o pote começa com $ 0. Um grupo de 9 jogadores é formado e cada jogador recebe uma Inteligência única de 1 a 9.

No início de cada turno, Pot += Smartnesspara cada jogador ainda na rodada. Em seguida, os jogadores votam no jogador que desejam remover. O jogador com mais votos é removido. Em caso de empate, o jogador mais esperto é mantido.

Quando restam apenas 2 jogadores na rodada, eles se enfrentam em uma batalha de inteligência. A chance do jogador vencer é Smartness/(Smartness+OpponentSmartness). O jogador vencedor recebe o pote inteiro.

O jogador que recebeu mais dinheiro no final do jogo vence.

Entrada / Saída

A cada turno, você receberá a lista atual de oponentes. Você terá acesso à sua inteligência e a todo o histórico de votação de todos os jogadores da rodada por meio de funções na classe Player.

Como saída, você deve retornar um único número inteiro, representando o jogador no qual deseja votar (representando sua inteligência). Votar em si mesmo é permitido (mas não recomendado).

As rodadas de 9 serão repetidas até que todos os jogadores tenham jogado pelo menos 1000 10000 rodadas, e todos os jogadores tenham jogado no mesmo número de rodadas.

Você pode encontrar o controlador aqui: https://github.com/nathanmerrill/WeakestLink

Para criar um jogador, você precisa estender a classe Player e adicioná-lo à classe PlayerFactory. Sua turma deve seguir as seguintes regras:

  1. É estritamente proibida a comunicação ou interferência com qualquer outro jogador (incluindo outros jogadores do mesmo tipo).

  2. Variáveis ​​de reflexão e estáticas (exceto constantes) não são permitidas.

  3. Se você deseja usar a aleatoriedade, forneci uma getRandom()função na classe Player. Use-o para que as simulações possam ser determinísticas.

Eu forneci muitas funções na classe Player para facilitar o acesso aos dados. Você pode encontrá-los online no Github . Seu jogador será instanciado a cada nova rodada. Jogadores "burros / suicidas" são permitidos (mas não jogadores com a mesma estratégia).

Pontuações

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

1
Não entenda o seguinte: "No início de cada rodada ... Um grupo de 9 jogadores é formado e cada jogador recebe uma Inteligência única", não no início do jogo?
CSᵠ

1
@ CSᵠ correto. Sua inteligência muda de rodada para rodada (seria injusto caso contrário).
Nathan Merrill

2
deve ser o estresse e a alegria
CSᵠ

1
Devo esperar uma configuração de compilação de formigas ou algo parecido? Sou um pouco iniciante em java e não tenho certeza de como as pessoas geralmente criam pequenos projetos como este.
Dale Johnson

4
De dentro src\WeakestLinkeu costumava javac Game\*.java Players\*.java Main.javacompilar e java -cp .. WeakestLink.Mainexecutar.
Linus

Respostas:


22

Franco atirador

A idéia geral é manter um dos jogadores estúpidos (ou seja, aqueles com maior probabilidade de derrotar no confronto) para roubar os pontos. Depois disso, tentamos remover os outros jogadores de baixo valor para aumentar o pote. Mas quando chegamos aos jogadores inteligentes, optamos por remover os mais perigosos, caso nosso jogador estúpido seja removido. Dessa forma, se não temos alguém para furtar, devemos arranjar alguém com quem pelo menos tenhamos uma chance. Além disso, como sempre votamos com um jogador mínimo ou máximo, espero que sejamos razoavelmente eficazes em conseguir o que queremos.

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;
    }
}

Então, aparentemente, a reversão não remove as edições. Se possível, gostaria que as edições fossem removidas para deixar bem claro que esta é a versão original.
Linus

12

PrudentSniper

Atirador de elite , mas com dois comportamentos de casos especiais. Uma é que, se restarem três bots, e o PrudentSniper for o mais inteligente, ele votará no bot do meio em vez do menos inteligente. Isso permite ganhar mais alguns confrontos. O outro comportamento é que, se o bot mais inteligente está buscando por ele (votou nele ou no bot análogo da última vez) e o menos inteligente, não votará no mais inteligente em defesa pessoal.

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;
    }
}

Não tenho certeza de que ambos os avanços tenham o mesmo valor. Você já experimentou cada um separadamente?
Linus

Sim, e embora o caso dos três bots seja uma melhoria inequívoca (pelo menos contra os bots atualmente em master no repo), a retribuição é quase neutra, na rede. Deixei-o como uma espécie de dissuasão vaga, uma precaução contra assassinos.
histocrat


Corrigi recentemente um bug em que a inteligência era 0-8 em vez de 1-9. Isso quebrou seu código, então eu o corrigi
Nathan Merrill

12

O culto

Os jogadores de culto têm um esquema de votação levemente esotérico, pelo qual tentam se identificar e votar como um grupo, usando apenas o registro de votação. Como cada membro do culto sabe votar, qualquer pessoa que vote de forma diferente é revelada como não-membro e, por fim, alvo de eliminação.

Resumo do esquema de votação:

  • no voto do primeiro turno do participante mais fraco, trabalhar em conjunto com o min & sniper ajuda o culto a ganhar poder
  • nos turnos subsequentes, votam os não-membros conhecidos até que apenas o culto permaneça (votamos o não-membro de menor valor para acumular pontos, desde que pensemos que estamos no controle).
  • quando restarem apenas membros, vote em membros de baixo valor por pontos (na verdade, sacrificando-se pelo bem do culto).

O código:

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;
    }
}

Pensamentos finais:

O culto agora passa a votar nos jogadores mais perigosos quando há apenas dois ou menos membros do culto restantes no confronto. Eu testei várias vezes com cult_cnt>1e cult_cnt>2condições e as vitórias posteriores com mais freqüência.

Ainda assim, isso é uma precaução e o culto realmente não foi projetado para funcionar como um jogador solitário, portanto, à medida que o número de novos jogadores aumenta, o culto ainda deve perder eventualmente.


Não seria melhor votar primeiro nos não membros mais inteligentes?
#

Atualizei o código do controlador para que a variável aleatória seja estática (e possa ser acessada via Game.random). Também tomei a liberdade de atualizar o código no github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

1
@NathanMerrill Obrigado, mas parece-me que obtive melhores resultados se eu permitir que o culto seja mais tolerante (vá entender) a não-membros desconhecidos que votam no seu interesse.
Linus

@agweber, Obrigado pela sugestão. Provavelmente isso faz do cult um único jogador melhor, mas contanto que ele tenha os números, ele deve tentar aumentar o pote. Eu acho que minha nova versão é a melhor do mundo.
Linus

2
TheCult me pediu para solicitar que unusedPlayers.addAll(allPlayers);no Game.java fosse duplicado cerca de nove vezes, para que todos os jogadores pudessem ocorrer em multiplicidade variada (como embaralhar vários baralhos) ... não, é claro, é uma solicitação totalmente tendenciosa, mas é interessante ver o quão poderosa a estratégia baseada em equipe ainda pode ser se eles tiverem uma pequena chance de ficarem juntos.
Linus

7

BridgeBurner

Não é um lugar onde eu possa testar isso agora, e isso saiu como um código realmente feio / idiota, mas deve funcionar.

Este bot só quer ser odiado. Ele vota em quem menos votou contra . Em caso de empate, ele escolhe quem ficou mais tempo sem votar a favor. No caso de outro empate, ele escolhe o mais inteligente (provavelmente porque eles serão o pior inimigo). Ele não vai votar em si mesmo, porque ninguém realmente odeia quando não está por perto.

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));
        }
    }
}

Não consegui fazer esse bot funcionar. Corrigi vários bugs, e agora ele está votando em um jogador inexistente. A única alteração que eu não tinha certeza se estava certa era que "last_round_voted" não está definido, então mudei para "last_voted_against". Você pode encontrar minhas alterações aqui: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@ NathanMerrill Este código foi aparentemente ainda pior do que eu pensava. Agora que posso testá-lo, examinarei as duas versões e tentarei fazê-lo funcionar.
SnoringFrog

@NathanMerrill Encontrou alguns problemas. Nomeadamente, eu não ignorei os jogadores que não estavam no grupo que nunca votaram no bot, e é por isso que ele sempre tentou votar neles. Também usou a lista errada para obter um índice a partir de um ponto, resultando na -1votação do jogador . Mas deve ser corrigido agora.
SnoringFrog

1
Bem, funciona, mas é terrível. Parabéns por vencer o jogador aleatório!
Nathan Merrill

1
@NathanMerrill em bater em jogadores aleatórios algumas vezes
SnoringFrog 3/15/15

6

Bandwagon

Segue a multidão na votação, a menos que ele seja o alvo.

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;
    }
}

Suponho que este apenas tornará os franco-atiradores mais fortes, seguindo-os, mas também evita ser alvo dos cultos e auxiliares de franco-atirador de uma maneira ligeiramente eficaz. Também pode ser um campo de manufatura para assassinos de atiradores de elite ou ajudá-los se houver mais deles. (Precisa testar com as atualizações mais recentes).

Usando os recursos do java 8, porque o jogo precisa ser executado de qualquer maneira.


1
É bom para ver algum código bem escrito :)
Nathan Merrill

6

RevengePlayer

Este bot votará em quem votou nele mais vezes, sendo o desempate o jogador mais inteligente. A teoria é que um jogador que votou em você no passado provavelmente votará em você novamente.

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;
    }
}

Corrigi recentemente um bug em que a inteligência era 0-8 em vez de 1-9. Isso quebrou seu código, então eu o corrigi
Nathan Merrill

@ NathanMerrill sua correção para o meu código teve um pequeno bug. Editei meu código para torná-lo melhor.
MegaTom

5

MeanPlayer

Não vote nem nos jogadores mais estúpidos nem nos mais inteligentes, e ele está carregando uma arma (passou pela segurança)

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];
    }
}

Eu não entendo por que este jogador é qualquer fraco do que o resto / SARC
Nathan Merrill

Cuidado @NathanMerrill, ele tem uma arma! Eu escolheria minhas palavras com cuidado se fosse você ...
CSᵠ

10
@ CSᵠ Eu não estou preocupado. Quando ele é o jogador médio, ele usa a arma em si mesmo.
quintopia 01/12/2015

14
Este jogador é menos mau do que ela poderia ser. Ela parece ser mais mediana do que média.
Yakk 01/12/2015

7
Hah .... demorei um minuto
Reinstate Monica

5

AntiExtremist

Esse socialista extremo acredita que todas as pessoas devem ter igual inteligência. Ele tenta matar aqueles que são muito mais espertos ou mais burros do que ele. Ele considera os dois, mas prefere o burro em geral. Ele prefere pessoas burras no começo e inteligentes no final, mas é ponderado com base no quão extremas são essas pessoas.

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;

    }

}

NOTA: De acordo com Linus, ele votará da mesma forma que o atirador de elite na grande maioria das vezes (525602: 1228).


Vou manter a corrida atual em 10K por enquanto (para testes mais rápidos). Quando eu fizer a execução final, provavelmente a aumentarei.
Nathan Merrill

Não estou tentando acusá-lo de nada, mas isso vota da maneira que o Sniper faria ~ 99,7% das vezes, basicamente será uma troca de moeda quem ganha, já que eles estão tão próximos da mesma estratégia.
Linus

De onde você tirou essa estatística? Admito que tenha uma estratégia semi-semelhante, mas meu objetivo era tentar melhorar algo tão simples quanto o seu, optando por votar em pessoas que são muito inteligentes se forem significativamente mais inteligentes do que eu (ou seja, não sou provável que ganhe o prêmio). pote se eles sobreviverem)
csga5000

1
Eu dei a sua classe um static Sniper S = new Sniper()e static long agrees=0, disagrees=0;. No seu método de votação, acrescento S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);que calcula como um atirador votaria em sua posição e, em seguida, coloque sua resposta em uma variável para contar se concordou ou discordou antes de retornar sua resposta. Quando o jogo terminar, você pode imprimir concorda: desagregar, que era 525602: 1228.
Linus

1
@ Linus Isso faz sentido, parece legítimo. Vou adicionar uma nota sobre isso.
csga5000

5

Espião

O espião é reservado. Ele não gosta de atirar nas pessoas mais inteligentes. Da mesma forma, ele não gosta de pegar idiotas indefesos do quartata . Então, ele gosta de eliminar as pessoas mais próximas a ele em inteligência.

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;
  }
}

Você acabou de ser apunhalado, mes amis . Ele não se importa se ele ganha. Ele gosta do som da faca nas suas costas enquanto ele vota com sucesso.

Você acabou de receber uma facada nas costas.


4
Essa imagem, no entanto. +1
Addison Crump

Eu acho que isso tem um bug. Math.abs(enemyIntel - selfIntel) < closestInteldeveria ser Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@MegaTom Acho que você está certo. Vou verificar isso ainda mais quando tiver Java disponível. Obrigado pela possível captura!
Conor O'Brien

4

MedianPlayer

Este jogador tenta ser o pior (bem, mediano) que resta.

Ele vota para eliminar os oponentes mais inteligentes e burros (com um leve viés para votar nos mais inteligentes), dependendo se há mais ou menos mais esperto / mais burro do que eles.

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;
  }
}

estrutura flagrantemente roubada do @Linus acima.


Você fez meu IDE reclamar de código duplicado!
Nathan Merrill

@NathanMerrill Copy-pasta attack! Nota: alterei o nome da turma desde que publiquei. Como suponho que duplicar o nome da classe de outra pessoa para garantir que você não possa ir contra ela, seria contrário ao espírito das regras.
Yakk 01/12/2015

2
Obrigado por roubar descaradamente meu trabalho, ou pelo menos admitir isso.
Linus

2
@Linus De nada! A imitação é a melhor bajulação, espero.
Yakk 01/12/2015

2
@ csga5000 flagrantemente roubou sua piada, e eu estava apenas brincando. Qualquer codificador semi-competente (por exemplo, eu) escreveria o loop da mesma maneira, então tudo o que ele realmente fez foi roubar meus nomes de variáveis. Se eu tivesse pensado em protegê-los, talvez pudesse cobrar royalties; )
Linus

4

Covarde

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;

  }
}

Como não quer ser eliminado, os votos para o oponente mais parecido com o jogador que foi eliminado na última rodada, a fim de maximizar a chance de estar no time vencedor.

Não está indo muito bem agora, mas pode muito bem misturá-lo.


Corrigi recentemente um bug em que a inteligência era 0-8 em vez de 1-9. Isso quebrou seu código, então eu o corrigi
Nathan Merrill

4

Herói

Vota nos que apanham os fracos ... ou o irritam.

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;
    }
}

Corrigi recentemente um bug em que a inteligência era 0-8 em vez de 1-9. Isso quebrou seu código, então eu o corrigi
Nathan Merrill

@NathanMerrill Obrigado :)
TheNumberOne

4

Prumo

Bob é apenas o cara comum que pensa que é mais esperto do que realmente é. Não é possível vencer a família de atiradores, mas obter o top 5 nas minhas simulações na maioria das vezes.

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);
        }
    }



}

4

FixatedPlayer

Escolhe um alvo aleatório e depois vota neles até que eles desapareçam. Mas não vai votar em si mesmo.

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();
        }
    }
}

Esse código também não funcionou, mas foi uma solução fácil. Seu tempo de espera não é realmente necessário, porque eu não lhe dou esperteza quando passo seus atuais oponentes. O código fixo pode ser encontrado aqui: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill eu editei o código corrigido em minha resposta para que qualquer pessoa olhando para ele aqui ver o que está realmente sendo executados
SnoringFrog

4

Estatisticas

Esta não é uma entrada para o concurso. Esta é apenas uma maneira de obter estatísticas úteis de um jogo. Essas estatísticas mostram a probabilidade percentual de um determinado jogador ser eliminado em uma rodada.

Para fazer isso, adicione as seguintes linhas para Round.javaque a parte superior do arquivo fique assim:

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));
                }
            }
        }));
    }

...

Em seguida, modifique o método de votação para ficar assim:

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;
}

Saída de exemplo:

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

1
1, 2, 3? Eu sugiro alterá-lo para imprimir "Para a rodada 1" etc.
Skyler

3

MaxPlayer

Um sabe-tudo. Prefere remover qualquer pessoa com alta inteligência (que pode, portanto, desafiar seu intelecto incomparável)

public class MaxPlayer extends Player{

    @Override
    public int vote(Set<Integer> currentOpponents) {
        return Collections.max(currentOpponents);
    }
}

3

Guarda

Votos para aqueles que atacam os fortes ... ou para aqueles que o irritam.

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;
    }
}

Corrigi recentemente um bug em que a inteligência era 0-8 em vez de 1-9. Isso quebrou seu código, então eu o corrigi
Nathan Merrill

3

Sanguessuga

Confia em outros bots para votar nos caras mais inteligentes e idiotas ... mais ou menos.

Ele está satisfeito em aparecer em algum lugar no meio e, eventualmente, dividir o pote com o vencedor (já que ele é um cara muito decente ).

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);
            }
        }
    }
}

2
Eu gosto. Estou preocupado que não vai dar certo, porque muitos não votam da mesma forma que você. Essa é uma falha nessa competição: parece-me que os outros bots o forçam a se adaptar a um certo tipo de estratégia.
csga5000

3
Ainda divertido! Ganhar não é tudo: ~)!
Sweerpotato

3

SniperKiller

Outra resposta descaradamente roubada do código de Linus . Este aqui matará todos os atiradores, não os protegerá. Se souber que não há atiradores, ele atuará como um atirador de elite.

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;
    }
}

1
Gosto da ideia, mas parece haver uma cultura de votação para o jogador mínimo ou máximo. votar em outra pessoa pode estar descartando seu voto . Talvez se você verificar se os é Max sniperish antes de votar para alguém você vai pegar um pouco ... (i não pode verificar, no telefone)
Linus

2

RandomPlayer

public class RandomPlayer extends Player{

    @Override
    public int vote(Set<Integer> currentOpponents) {
        return (int) currentOpponents.toArray()[getRandom().nextInt(currentOpponents.size())];
    }
}

2

MinPlayer

Um elitista. Prefere remover alguém com pouca inteligência.

public class MinPlayer extends Player {

    @Override
    public int vote(Set<Integer> currentOpponents) {
        return Collections.min(currentOpponents);
    }
}

2

VengefulSniper

Isso começou como algo que eu pensava ser chamado original StupidBuffering(um nome que eu odiava desistir) e acabou sendo apenas um PrudentSniper que não se importava se ele estava sendo alvo. Este também parecia ser o único motivo pelo qual ele não podia vencer o PrudentSniper, então eu mudei um pouco as coisas para fazer desse seu foco.

Agora, isso é basicamente um atirador de elite, mas se o bot mais inteligente ou mais idiota mirar nele, ele mirará o que tiver mais votos na última rodada. Se ambos obtiveram o mesmo número de votos e o atacaram, ele volta ao comportamento normal de atirador de elite. Nos meus testes, isso supera o PrudentSniper de vez em quando.

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;
        }
    }
}

2

Intermediário

O MiddleMan tenta o seu melhor para maximizar os lucros, mantendo um olhar cauteloso para que ele não seja cortado do jogo. Ele mantém competidores menores para melhorar sua chance de chegar à próxima rodada (e deixar um final fácil). Ele votará em alguém mais inteligente do que ele somente se houver mais concorrentes mais inteligentes do que concorrentes menores. Qualquer que seja o grupo, ele sempre vota no mais baixo do grupo para manter o pote subindo.

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;
    }
}

PS espero que compile, eu não sou um cara de Java.

Teve esse esquema em mente antes de ler as outras entradas. Então fiquei surpreso com a proximidade (mas criticamente diferente) do Sniper, então fui em frente e o usei como um ponto de partida, pois não conheço a sintaxe Java. Obrigado @Linus


1
Por favor, teste seu código. não tente respostas escrita em idiomas que você não sabe
TanMath

@ TanMath - Obrigado pela sua contribuição. Tenho muita experiência em linguagens C / Java, mas não especificamente em Java, por isso estou bastante confiante de que meu código esteja correto e funcionará. Dito isto, se houver um erro e ele não funcionar, não ficarei ofendido se o mestre do jogo desqualificar a entrada.
tbernard

Você está certo. Obrigado @Linus. Editado.
tbernard

1
@tbernard Estou feliz de fixar bugs, mas seu código não tem qualquer :)
Nathan Merrill

Ai. Não foi tão bem quanto eu esperava. Eu parecia ajudar o atirador, então isso é algo que eu acho haha.
precisa saber é o seguinte

2

ApproximatePosition

Esse bot está tentando disparar aproximadamente em torno dos valores de inteligência ausentes, assumindo que o grupo continue com o mesmo padrão, o que significa que terá como alvo o mesmo tipo de alvo. Ele sempre vota no mais inteligente dos dois jogadores quando há uma escolha.

Faz tempo que não uso Java, e atualmente estou trabalhando ... Não posso testá-lo, espero que não seja muito complicado, seja gentil, por favor :).

A propósito, ele usa o awt.Point apenas porque tenho preguiça de implementar uma tupla 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;
    }

}

Então, houve alguns erros. :) Primeiro, infelizmente, o elenco de Integer [] não funciona, tem que ser um elenco de Object [] (do qual não gosto). Então, agrupei tudo em um ArrayList em vez de em um array. Em segundo lugar, esta linha: emptyPosition[emptyPosition.length]=j;sempre fornecerá uma matriz fora dos limites. Finalmente, não sei por que, mas você votará nos jogadores que não estão na rodada.
Nathan Merrill

Ah, também, seu bloqueio ternário estava retornando um duplo em vez de int e era super complicado, eu o transformei em um padrão se / else. Você pode encontrar todas as minhas alterações no Github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Wow, muito obrigado. Para emptyPosition[emptyPosition.length]isso, é um erro estúpido, pois o comprimento é sempre um sobre o último índice ^^. Obrigado pelas alterações, vou usar esta nova versão para corrigi-la. Sobre o bloco ternário ... sim, senti vontade de usá-lo, e talvez muito acostumado a escrever para mim, não foi útil para ler, eu acho. Fazendo as correções e atualizando-o.
Katenkyo

2

SniperAide

Antes da adição do PrudentSniper , escrevi um bot para ajudar o Sniper a vencer o AntiExtremist e outras fraudes (eu uso a palavra com amor). O bot, SniperAide, procura jogadores que votam como franco-atiradores e votam como eles pensariam quando há um consenso. Se todos os jogadores parecem atiradores de elite, ele vota no máximo, protegendo atiradores mais baixos (que também mudariam para o máximo neste momento), mesmo que seja ele próprio.

O Código :

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;
    }
}

Atualmente, ele não é de grande ajuda contra o PrudentSniper.


Com base na sua descrição e teoria, não vejo como isso ajudaria um robô parecido com um franco-atirador a vencer outros franco-atiradores. Desculpe, não tenho mais tempo para analisar seu código e realmente entendê-lo.
csga5000

@ csga5000, Como você raramente pode identificar o Sniper votando agora, ele os protege um pouco. Mas quando uma diferença é clara, ela sempre atua no interesse dos franco-atiradores, portanto é uma espécie de desempate. O foco na vitória é nos jogos macroscópicos, não nas rodadas individuais, na maioria das rodadas ele realmente não pode fazer nada além de manter a situação de troca de moedas.
Linus

1

HighOrLowNotSelf

Remove aleatoriamente o jogador de inteligência mais baixo ou mais alto (mas não o próprio).

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;
    }
}

Portanto, existem alguns bugs nessa submissão. Primeiro, Math.round () retorna a long, não int. Em segundo lugar, opsnão se contém. (Se você quiser votar em si mesmo, precisará explicitamente incluí-lo). Finalmente, o if / else que você incluiu não é Java válido. Eu fixo o seu código, e acrescentou que para o GitHub
Nathan Merrill

1

Anarquista

O anarquista não gosta de regimes.
O anarquista tentará matar o atual presidente.
Se o anarquista é presidente, ele decide abusar de seu poder e matar camponeses inúteis. A menos que ele fosse alvejado por um de seus inferiores, pois eles deveriam queimar.

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();
    }

}

1

IndependentVoter

Este bot sabe que a população em geral está sempre errada! Por isso, vota em quem recebe menos votos.

O código é quase idêntico ao "Bandwagon" da SolarAaron, mas a lógica final é invertida.

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;
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.