Vous êtes le lien le plus faible, au revoir


50

Ce défi est basé sur le jeu télévisé Weakest Link . Pour ceux qui ne sont pas familiarisés avec le spectacle, le cœur de ce défi concerne le vote de votre choix :

  • Si les autres joueurs sont plus intelligents que vous, alors vous avez moins de chance de gagner le pot.
  • Si les autres joueurs sont plus stupides que vous, vous avez moins de pot à gagner.

Au début de chaque tour, le pot commence avec 0 $. Un groupe de 9 joueurs est formé et chaque joueur reçoit une Smartness unique allant de 1 à 9.

Au début de chaque tour, Pot += Smartnesspour chaque joueur encore dans le tour. Ensuite, les joueurs votent sur le joueur qu’ils souhaitent supprimer. Le joueur avec le plus de votes est supprimé. En cas d'égalité, le joueur le plus intelligent est gardé.

Lorsqu'il ne reste plus que 2 joueurs dans la ronde, ils s'affrontent dans une bataille d'esprits. La chance de gagner le joueur est Smartness/(Smartness+OpponentSmartness). Le joueur gagnant reçoit alors le pot entier.

Le joueur qui a reçu le plus d’argent à la fin de la partie gagne.

Entrée sortie

À chaque tour, vous recevrez la liste actuelle des adversaires. Vous aurez accès à votre intelligence et à l' historique de vote complet de tous les joueurs pour le tour via des fonctions de la classe Player.

En sortie, vous devez renvoyer un entier unique représentant le joueur pour lequel vous souhaitez voter (représentant son intelligence). Voter pour vous - même est autorisé (mais non recommandé).

Les tours de 9 se répètent jusqu'à ce que tous les joueurs aient joué au moins 1000 10000 tours et que tous les joueurs aient joué le même nombre de tours.

Vous pouvez trouver le contrôleur ici: https://github.com/nathanmerrill/WeakestLink

Pour créer un lecteur, vous devez étendre la classe Player et ajouter votre lecteur à la classe PlayerFactory. Votre classe doit suivre les règles suivantes:

  1. Toute communication ou interférence avec un autre joueur (y compris vos autres joueurs du même type) est strictement interdite.

  2. Les variables de réflexion et statiques (à l'exception des constantes) ne sont pas autorisées.

  3. Si vous souhaitez utiliser le caractère aléatoire, j'ai fourni une getRandom()fonction dans la classe Player. Utilisez-le pour que les simulations puissent être déterministes.

J'ai fourni de nombreuses fonctions dans la classe Player pour un accès facile aux données. Vous pouvez les trouver en ligne sur Github . Votre joueur sera instancié à chaque nouveau tour. Les joueurs "stupides / suicidaires" sont autorisés (mais pas les joueurs avec la même stratégie).

Les 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

1
ne comprenez pas ceci: "Au début de chaque tour ... Un groupe de 9 joueurs est formé, et chaque joueur reçoit une Smartness unique" et non au début du jeu?
CSᵠ

1
@ CSᵠ correct. Votre intelligence change de tour en tour (sinon, ce serait injuste).
Nathan Merrill

2
doit être le stress et la joie
CSᵠ

1
Devrais-je m'attendre à une config ou à une telle configuration? Je suis un peu novice en Java, et je ne suis pas sûr de la façon dont les gens mettent généralement en place de petits projets comme celui-ci.
Dale Johnson

4
De l'intérieur, src\WeakestLinkj'avais l'habitude javac Game\*.java Players\*.java Main.javade compiler et java -cp .. WeakestLink.Mainde courir.
Linus

Réponses:


22

Tireur d'élite

L’idée générale est de garder l’un des joueurs stupides (c’est-à-dire ceux que nous sommes plus susceptibles de vaincre lors de la mise au jeu) afin de récolter les points. Après cela, nous essayons de supprimer les autres joueurs de faible valeur pour augmenter le pot. Mais lorsque nous en arrivons aux joueurs intelligents, nous décidons d’enlever les plus dangereux au cas où notre stupide joueur serait enlevé. De cette façon, si nous n'avons pas quelqu'un à qui tirer, nous devrions trouver quelqu'un contre qui nous avons au moins une chance. De plus, comme nous votons toujours avec un joueur min ou max, je pense que nous sommes assez efficaces pour obtenir notre chemin.

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

Donc, apparemment, la restauration ne supprime pas les modifications. Dans la mesure du possible, j'aimerais que toutes les modifications soient supprimées pour bien préciser qu'il s'agit de la version originale.
Linus

12

Prudent Sniper

Sniper , mais avec deux comportements spéciaux. La première est que s'il reste trois robots, et que Prudent Sniper est le plus intelligent, il votera pour le bot du milieu au lieu du moins intelligent. Cela lui permet de gagner encore quelques épreuves de force. L’autre comportement est que si le bot le plus intelligent se bat pour lui (voté pour cela ou le bot analogue la dernière fois) et que le moins malin ne l’est pas, il votera pour le plus intelligent en légitime défense.

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

Je ne suis pas sûr que les deux avancées ont la même valeur. Les avez-vous essayés séparément?
Linus

Je l’ai fait, et bien que l’affaire des trois robots constitue une amélioration sans ambiguïté (du moins par rapport aux robots actuellement en référent), la rétribution est à peu près neutre, sur le net. Je l'ai laissé comme une sorte de vague dissuasion, une précaution contre les assassins.
histocrat


J'ai récemment corrigé un bug où l'intelligence était 0-8 au lieu de 1-9. Cela a cassé votre code, donc je l'ai corrigé (vous pouvez trouver le code mis à jour sur le référentiel): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

12

Le culte

Les joueurs cultes ont un système de vote légèrement ésotérique qui leur permet de s’identifier et de voter en tant que groupe, en utilisant uniquement le registre de vote. Étant donné que chaque membre de la secte sait voter, toute personne votant différemment est révélée en tant que non-membre et finit par être éliminée.

Le schéma de vote en un coup d'œil:

  • au premier tour, votez pour le concurrent le plus faible, travailler de concert avec min & sniper aide le culte à acquérir du pouvoir
  • lors des tournois ultérieurs, éliminez les non-membres connus jusqu'à ce qu'il ne reste plus que la secte (nous rejetons le non-membre ayant la valeur la plus basse pour accumuler des points tant que nous pensons être en contrôle).
  • quand il ne reste que des membres, éliminez des points pour les membres de faible valeur (en vous sacrifiant pour le bien de la secte).

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

Dernières pensées:

La secte passe maintenant au vote pour les joueurs les plus dangereux lorsqu'il ne reste plus que deux membres de la secte ou moins pour la mise au jeu. Je l' ai testé plusieurs fois avec cult_cnt>1et les cult_cnt>2conditions et les victoires plus tard plus souvent.

Néanmoins, il s’agit d’une précaution et le culte n’est pas conçu pour fonctionner en solo, alors, à mesure que le nombre de nouveaux joueurs augmentera, le culte devrait tout de même finir par disparaître.


Ne serait-il pas préférable d'éliminer les non-membres les plus intelligents en premier?
agweber

J'ai mis à jour le code du contrôleur pour que la variable aléatoire soit statique (et accessible via Game.random). J'ai également pris la liberté de mettre à jour le code sur github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

1
@NathanMerrill Merci, mais je semble obtenir de meilleurs résultats si je permets à la secte d'être plus tolérante (voir chiffre) à des non-membres inconnus qui votent pour son intérêt.
Linus

@ agweber, merci pour la suggestion. Cela fait probablement du joueur solitaire un meilleur joueur unique, mais tant qu'il a les chiffres, il devrait essayer de monter le pot. Je pense que ma nouvelle version est le meilleur des deux mondes.
Linus

2
Le Culte m'a demandé de demander que unusedPlayers.addAll(allPlayers);dans Game.java soit dupliqué environ neuf fois, de sorte que tous les joueurs puissent apparaître dans une multiplicité variée (comme mélanger plusieurs jeux de cartes) ... non bien sûr, c'est une demande totalement biaisée mais Il est intéressant de voir à quel point la stratégie basée sur les équipes peut encore être puissante si elle a même une petite chance d'être mise sur pied.
Linus

7

BridgeBurner

Ce n'est pas un endroit où je peux tester cela pour le moment, et cela est apparu comme un code vraiment moche / idiot, mais cela devrait fonctionner.

Ce bot veut juste être détesté. Il vote pour celui qui a le moins voté contre . En cas d'égalité des voix, il choisit celui qui a passé le plus de temps sans voter pour. En cas d'égalité, il choisit le plus intelligent (probablement parce qu'il fera le pire ennemi). Il ne votera pas pour lui-même, car personne ne le déteste vraiment quand il n'est pas là.

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

Je n'ai pas réussi à faire fonctionner ce bot. J'ai corrigé plusieurs bugs, et il vote maintenant pour un lecteur inexistant. Le seul changement dont je n'étais pas sûr si c'était juste, c'est que "last_round_voted" n'est pas défini, je l'ai donc remplacé par "last_voted_against". Vous pouvez trouver mes modifications ici: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Ce code était apparemment encore pire que je ne le pensais. Maintenant que je peux le tester, je vais regarder les deux versions et essayer de le faire fonctionner.
SnoringFrog

@NathanMerrill a trouvé quelques problèmes. À savoir, je n'ai pas ignoré les joueurs qui n'étaient pas dans la découverte et qui n'ont jamais voté pour le bot, c'est pourquoi il a toujours essayé de voter pour eux. Également utilisé la mauvaise liste pour obtenir un index à un moment donné, entraînant le -1vote du joueur . Mais cela devrait être corrigé maintenant.
SnoringFrog

1
Eh bien, cela fonctionne, mais fait terrible. Félicitations pour avoir battu un joueur au hasard!
Nathan Merrill

1
@NathanMerrill pour avoir parfois
SnoringFrog

6

Mouvement

Suit la foule en votant, à moins que ce ne soit celui qui est ciblé.

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

Je suppose que celui-ci rendra les tireurs d'élite plus forts en les suivant, mais évitera également d'être pris pour cible par la secte et les aides-tireurs d'élite de manière légèrement efficace. Cela peut aussi bien être un bouclier à viande pour les tueurs de tireurs d’élite ou les aider s’il y en a plus. (Besoin de tester avec les dernières mises à jour).

Utilisation de java 8 car le jeu en a besoin de toute façon.


1
C'est bien de voir du code bien écrit :)
Nathan Merrill

6

RevengePlayer

Ce bot votera pour celui qui votera pour lui le plus souvent, le départage sera le joueur le plus intelligent. La théorie est qu'un joueur qui a voté pour vous dans le passé votera probablement pour vous à nouveau.

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

J'ai récemment corrigé un bug où l'intelligence était 0-8 au lieu de 1-9. Cela a cassé votre code, donc je l'ai corrigé (vous pouvez trouver le code mis à jour sur le référentiel): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill votre correctif pour mon code avait un petit bug. J'ai édité mon code pour le rendre meilleur.
MegaTom

5

MeanPlayer

Ne votez ni pour les joueurs les plus stupides ni pour les plus intelligents, et il porte une arme à feu

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

Je ne comprends pas pourquoi ce joueur est plus méchant que le reste / sarc
Nathan Merrill

Attention @NathanMerrill, il a une arme à feu! Je choisirais mes mots avec soin si j'étais toi ...
CSᵠ

10
@ CSᵠ Je ne suis pas inquiet. Quand il est le joueur moyen, il utilise le pistolet sur lui-même.
Quintopia

14
Cette joueuse est moins méchante qu'elle ne pourrait l'être. Elle semble être plus médiane que moyenne.
Yakk

7
Hah .... m'a pris une minute
Réintégrer Monica

5

Anti-extrémiste

Ce socialiste extrémiste croit que tous les gens devraient faire preuve de la même intelligence. Il essaie de tuer ceux qui sont beaucoup plus intelligents ou plus stupides que lui. Il considère les deux mais il favorise la bêtise en général. Il favorise les gens stupides au début et intelligents à la fin, mais cela dépend de l'extrême extrême de ces gens.

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;

    }

}

REMARQUE: Selon Linus, le vote sera identique à celui du tireur d’élite dans l’immense majorité du temps (525602: 1228).


Je vais garder la course actuelle à 10K pour l'instant (pour des tests plus rapides). Quand je ferai le dernier passage, je le ferai probablement plus gros.
Nathan Merrill

Je n'essaie pas de vous accuser de quoi que ce soit, mais cela se passe comme le tireur d'élite dans environ 99,7% des cas. Il s'agira en fait de jouer qui gagne, car ils sont si proches de la même stratégie.
Linus

Où avez-vous obtenu cette statistique? J'admets que sa stratégie est à peu près similaire, mais mon objectif était d'essayer d'améliorer quelque chose d'aussi simple que le vôtre en choisissant de voter pour des personnes très intelligentes si elles sont nettement plus intelligentes que moi (autrement dit, il est peu probable que je remporte le prix. pot s'ils survivent)
csga5000

1
J'ai donné à votre classe un static Sniper S = new Sniper()et static long agrees=0, disagrees=0;. Dans votre méthode de vote, j'ajoute S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);une formule qui calcule comment un tireur d'élite votera à votre poste, puis place votre réponse dans une variable pour déterminer s'il est d'accord ou pas avant de renvoyer sa réponse. Une fois le jeu terminé, vous pouvez imprimer: accord: 525602: 1228.
Linus

1
@ Linus Cela a du sens, semble légitime. Je vais ajouter une note à ce sujet.
csga5000

5

Espion

Spy est réservé. Il n'aime pas utiliser les armes pour les personnes les plus intelligentes. De même, il n'aime pas s'attaquer aux idiots sans défense de quartata . Ainsi, il aime éliminer les plus proches de lui avec intelligence.

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

Vous venez d'être poignardé, mes amis . Il s'en fiche s'il gagne. Il aime le son du couteau dans votre dos alors qu'il vous vote avec succès.

Vous venez d'être poignardé.


4
Cette image, cependant. +1
Addison Crump

Je pense que cela a un bug. Math.abs(enemyIntel - selfIntel) < closestInteldevrait être Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@ MegaTom Je pense que vous avez raison. Je vérifierai cela davantage quand j’aurai Java disponible. Merci pour la prise possible!
Conor O'Brien

4

MedianPlayer

Ce joueur tente d’être le plus méchant (bien, la médiane) qui reste.

Il vote pour éliminer les opposants les plus intelligents et les plus stupides (avec un léger parti pris pour le vote du plus intelligent), selon qu’il existe plus ou moins d'intelligent / plus stupide que lui-même.

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

cadre volé de manière flagrante à @ Linus ci-dessus.


Vous avez fait mon IDE se plaindre de code dupliqué!
Nathan Merrill

@NathanMerrill Attaque Copie-Pâtes! Notez que j'ai changé le nom de la classe depuis que j'ai posté. Comme je suppose, dupliquer le nom de classe de quelqu'un d'autre pour s'assurer que vous ne pouvez pas aller contre eux irait à l'encontre de l'esprit des règles.
Yakk

2
Merci de voler mon travail de façon flagrante, ou de l'admettre au moins.
Linus

2
@ Linus vous êtes les bienvenus! L’imitation est la meilleure flatterie, j’espère.
Yakk

2
@ csga5000 a volé sa blague de manière flagrante et je ne faisais que jouer. Tout codeur à moitié compétent (par exemple, moi-même) écrivait la boucle de la même manière. Il n'a donc volé que mes noms de variables. Si j'avais pensé les protéger, je pourrais peut-être percevoir des redevances; )
Linus

4

lâche

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;

  }
}

Veut simplement ne pas être voté, donc votez pour l'adversaire qui ressemble le plus au joueur qui a été voté lors du dernier tour afin de maximiser les chances de faire partie de l'équipe gagnante.

Ne fait pas particulièrement bien en ce moment, mais pourrait tout aussi bien le jeter dans le mélange.


J'ai récemment corrigé un bug où l'intelligence était 0-8 au lieu de 1-9. Cela a cassé votre code, donc je l'ai corrigé (vous pouvez trouver le code mis à jour sur le référentiel): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

4

héros

Vole ceux qui s'en prennent au faible ... ou le dérangent.

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

J'ai récemment corrigé un bug où l'intelligence était 0-8 au lieu de 1-9. Cela a cassé votre code, donc je l'ai corrigé (vous pouvez trouver le code mis à jour sur le référentiel): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Merci :)
TheNumberOne

4

Bob

Bob est juste le gars moyen qui pense qu'il est plus intelligent, alors il l'est vraiment. Impossible de gagner la famille de tireurs d’élite , mais d’être la plupart du temps top 5 de mes simulations

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

Choisit une cible au hasard, puis vote pour eux jusqu'à ce qu'ils soient partis. Ne votera pas pour lui-même cependant.

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

Ce code ne fonctionnait pas non plus, mais était une solution facile. Votre passe-temps n'est en réalité pas nécessaire, car je ne vous donne pas votre intelligence lorsque je vous transmets vos suppléments actuels. Le code fixe peut être trouvé ici: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill J'ai inséré le code corrigé dans ma réponse afin que tous ceux qui l'aperçoivent ici voient ce qui se passe réellement
SnoringFrog

4

Statistiques

Ce n'est pas une inscription au concours. C'est simplement un moyen d'obtenir des statistiques utiles sur un match. Ces statistiques indiquent le pourcentage de probabilité qu'un joueur en particulier soit éliminé lors d'un tour.

Pour ce faire, ajoutez les lignes suivantes à Round.javaafin que le haut du fichier ressemble à ceci:

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

...

Puis modifiez la méthode de vote pour qu'elle ressemble à ceci:

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

Exemple de sortie:

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? Je suggérerais de le changer pour imprimer "Pour le tour 1" etc.
Skyler

3

MaxPlayer

Un je-sais-tout. Préfère enlever toute personne à haute intelligence (qui peut donc défier son intellect inégalé)

public class MaxPlayer extends Player{

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

3

Garde

Votez ceux qui s'en prennent au fort ... ou ceux qui l'ennuient.

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

J'ai récemment corrigé un bug où l'intelligence était 0-8 au lieu de 1-9. Cela a cassé votre code, donc je l'ai corrigé (vous pouvez trouver le code mis à jour sur le référentiel): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

3

Sangsue

S'appuie sur d'autres robots pour voter les types les plus intelligents et les plus stupides… en quelque sorte.

Il se contente de tourner quelque part au milieu et éventuellement diviser le pot avec le gagnant (puisqu'il est en fait un vraiment décent gars 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);
            }
        }
    }
}

2
J'aime. Je crains que cela ne marche pas bien car peu de personnes voteront de la même manière que vous. C'est l'un des défauts de cette compétition, il me semble que les autres robots vous obligent à vous conformer à un certain type de stratégie.
csga5000

3
Toujours amusant quand même! Gagner n'est pas tout: ~)!
sweerpotato

3

SniperKiller

Une autre réponse volée sans vergogne dans le code de Linus . Celui-ci va tuer tous les tireurs d’élite, pas les protéger. S'il sait qu'il ne reste plus aucun tireur d'élite, il agira comme un tireur d'élite.

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
J'aime l'idée, mais il semble y avoir une culture de vote pour les joueurs min ou max. voter pour quelqu'un d'autre pourrait bien jeter votre vote . Peut-être que si tu vérifies si le max est sniper avant de voter pour quelqu'un d'autre, tu en rattraperas un peu ... (Je ne peux pas vérifier, au téléphone)
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

Un élitiste. Préfère retirer toute personne peu intelligente.

public class MinPlayer extends Player {

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

2

VengefulSniper

Cela a commencé comme quelque chose que je pensais être appelé à l'origine StupidBuffering(un nom que je détestais abandonner), pour finalement devenir un Prudent Sniper qui ne se souciait pas de savoir s'il était ciblé. Cela semblait aussi être la seule raison pour laquelle il ne pouvait pas battre Prudent Sniper, alors j'ai peaufiné un peu les choses pour en faire son objectif.

Il s’agit en réalité d’un tireur d’élite, mais si le bot le plus intelligent ou le plus stupide le cible, il ciblera celui qui aura obtenu le plus de votes au dernier tour. S'ils ont tous deux obtenu le même nombre de voix et qu'ils l'ont tous deux pris pour cible, il revient au comportement normal du tireur d'élite. Dans mes tests, cette réalité bat parfois Prudent Sniper.

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

Intermédiaire

Le MiddleMan fait de son mieux pour maximiser ses profits tout en gardant un œil prudent sur le fait qu’il n’est pas exclu du jeu. Il garde moins de concurrents pour améliorer ses chances de se qualifier pour le tour suivant (et pour laisser une finition facile). Il votera contre quelqu'un de plus intelligent que s'il existe plus de candidats plus intelligents qu'il n'y a de moins de candidats. Quel que soit l’un des deux groupes, il vote toujours pour le plus bas du groupe afin que le pot continue de grimper.

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 espère que ça compile, je ne suis pas un gars de Java.

Avait ce schéma en tête avant de lire les autres entrées. Ensuite, j'ai été surpris de voir à quel point Sniper était proche (mais très différent), alors j'ai décidé de l'utiliser et de l'utiliser comme point de départ, car je ne connais pas la syntaxe Java. Merci @ Linus


1
S'il vous plaît tester votre code. n'essayez pas d'écrire des réponses dans des langues que vous ne connaissez pas
TanMath

@TanMath - Merci pour votre contribution. J’ai beaucoup d’expérience dans les langages de type C / Java, mais pas tout à fait avec Java. Je suis donc tout à fait sûr que mon code est correct et qu’il fonctionnera. Cela étant dit, s'il y a une erreur dans le fichier et qu'il ne fonctionnera pas, je ne serai pas offensé si le maître du jeu annule la participation.
tbernard

Vous avez raison. Merci @ Linus. Édité.
tbernard

1
@tbernard Je suis heureux de corriger les bugs, mais votre code n'en avait aucun :)
Nathan Merrill

Aie. N'a pas fait aussi bien que je l'espérais. J'ai semblé aider les tireurs d'élite, donc c'est quelque chose que je suppose haha.
tbernard

2

Position approximative

Ce bot tente d’envisager approximativement les valeurs d’intelligence manquantes, en supposant que le groupe continue à suivre le même schéma, ce qui signifie qu’il ciblera le même type de cible. Il vote toujours pour le plus intelligent des deux joueurs quand il y a un choix.

Cela fait longtemps que je n’utilise pas Java et que je suis actuellement au travail.

À propos, il utilise awt.Point uniquement parce que je suis trop paresseux pour implémenter un 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;
    }

}

Donc, il y avait des insectes. :) Tout d'abord, malheureusement, la distribution Integer [] ne fonctionne pas, il doit s'agir d'une distribution Object [] (que je n'aime pas). Donc, j'ai tout enveloppé dans un ArrayList au lieu d'un tableau. Deuxièmement, cette ligne: emptyPosition[emptyPosition.length]=j;vous donnera toujours un tableau hors limites. Enfin, vous ne savez pas pourquoi, mais vous voterez pour des joueurs qui ne font pas partie du tour.
Nathan Merrill

Oh, aussi, votre bloc ternaire retournait un double au lieu d'int, et était très compliqué, je l'ai transformé en standard si / sinon. Vous pouvez trouver tous mes changements sur Github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Wow, merci beaucoup. Pour le emptyPosition[emptyPosition.length], c’est une erreur stupide car la longueur est toujours un sur le dernier index ^^. Merci pour les changements, je vais utiliser cette nouvelle version pour la corriger. À propos du bloc ternaire ... ouais, j'avais envie de l'utiliser, et peut-être trop habitué à écrire pour moi-même, n'était pas pratique pour lire, je suppose. Faire les corrections et le mettre à jour.
Katenkyo

2

SniperAide

Avant l’ajout de PrudentSniper, j’avais écrit un bot pour aider Sniper à vaincre AntiExtremist et d’autres fraudes (j’utilise le mot avec amour). Le bot SniperAide recherche les joueurs qui votent comme des tireurs d’élite et votent comme il le ferait s’il ya consensus. Si tous les joueurs ressemblent à des tireurs d’élite, il vote pour le maximum, protégeant ainsi les Snipers inférieurs (qui passeraient également au maximum à ce stade), même si c’est lui-même.

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

Il n'est actuellement pas d'une grande aide contre Prudent Sniper.


Sur la base de votre description et de votre théorie, je ne vois pas en quoi cela aiderait un bot similaire à un sniper à battre un autre sniper. Désolé, je n'ai plus le temps de fouiller dans votre code et de le comprendre par moi-même.
csga5000

@ csga5000, puisqu'il est rare que vous identifiiez Sniper en enregistrant votre vote maintenant, il les protège tous un peu. Mais quand une différence est évidente, elle agit toujours dans l’intérêt des Snipers, c’est donc plutôt une sorte de bris d’égalité. La priorité est de gagner aux jeux macroscopiques et non aux parties individuelles. Dans la plupart des parties, il ne peut vraiment rien faire d’autre que de maintenir la situation de la monnaie.
Linus

1

HighOrLowNotSelf

Supprime au hasard le joueur le plus faible ou le plus intelligent (mais pas soi-même).

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

Donc, il y a quelques problèmes avec cette soumission. Tout d'abord, Math.round () renvoie a long, not int. Deuxièmement, opsne vous contient pas. (Si vous souhaitez voter pour vous-même, vous devez explicitement l'inclure). Enfin, le if / else que vous avez inclus n'est pas valide en Java. J'ai corrigé votre code et je l'ai ajouté à github
Nathan Merrill

1

Anarchiste

L'anarchiste n'aime pas les régimes.
L'anarchiste va essayer de tuer le président actuel.
Si l'anarchiste est président, il décide d'abuser de son pouvoir et de tuer des peagents inutiles. À moins qu'il ne soit visé par l'un de ses inférieurs, ils devraient brûler à la place.

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

Ce bot sait que la population en général a toujours tort! Donc, il vote pour celui qui obtient le moins de voix.

Le code est presque identique au "Bandwagon" de SolarAaron, mais la logique de fin est inversée.

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;
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.