Sei il collegamento più debole, arrivederci


50

Questa sfida si basa sul gioco show, Weakest Link . Per coloro che non hanno familiarità con lo spettacolo, il punto cruciale di questa sfida riguarda chi si vota :

  • Se gli altri giocatori sono più intelligenti di te, allora hai meno possibilità di ottenere il piatto.
  • Se gli altri giocatori sono più stupidi di te, allora hai meno di un piatto da ottenere.

All'inizio di ogni round, il piatto inizia con $ 0. Si forma un gruppo di 9 giocatori e ad ogni giocatore viene assegnata una Smartness unica da 1 a 9.

All'inizio di ogni turno, Pot += Smartnessper ogni giocatore ancora nel round. Quindi, i giocatori votano il giocatore che desiderano rimuovere. Il giocatore con il maggior numero di voti viene rimosso. In caso di pareggio, il giocatore più intelligente viene mantenuto.

Quando rimangono solo 2 giocatori nel round, si affrontano in una battaglia di ingegno. La possibilità che il giocatore vinca è Smartness/(Smartness+OpponentSmartness). Il giocatore vincitore riceve quindi l'intero piatto.

Vince il giocatore che ha ricevuto più soldi alla fine della partita.

Input Output

Ad ogni turno, riceverai l'elenco attuale degli avversari. Avrai accesso alla tua intelligenza e all'intera cronologia dei voti di tutti i giocatori per il round tramite le funzioni della classe Player.

Come output, devi restituire un singolo intero, che rappresenta il giocatore per il quale desideri votare (che rappresenta la loro intelligenza). Il voto per te è permesso (ma non raccomandato).

I round da 9 si ripetono fino a quando tutti i giocatori hanno giocato almeno 1000 10000 round e tutti i giocatori hanno giocato nello stesso numero di round.

Puoi trovare il controller qui: https://github.com/nathanmerrill/WeakestLink

Per creare un giocatore, è necessario estendere la classe Player e aggiungere il giocatore alla classe PlayerFactory. La tua classe deve seguire le seguenti regole:

  1. La comunicazione o l'interferenza con qualsiasi altro giocatore (inclusi gli altri giocatori dello stesso tipo) è severamente vietata.

  2. La riflessione e le variabili statiche (ad eccezione delle costanti) non sono consentite.

  3. Se vuoi usare la casualità, ho fornito una getRandom()funzione nella classe Player. Usalo, quindi le simulazioni possono essere deterministiche.

Ho fornito molte funzioni nella classe Player per un facile accesso ai dati. Puoi trovarli online su Github . Il tuo giocatore verrà istanziato ad ogni nuovo round. Sono ammessi giocatori "stupidi / suicidi" (ma non giocatori con la stessa strategia).

I punteggi

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
non capisco: "All'inizio di ogni round ... Si forma un gruppo di 9 giocatori e ogni giocatore riceve una Smartness unica" non all'inizio del gioco?
CSᵠ

1
@ CSᵠ corretto. La tua intelligenza cambia da un round all'altro (altrimenti sarebbe ingiusto).
Nathan Merrill il

2
deve essere lo stress e la gioia
CSᵠ

1
Dovrei aspettarmi una configurazione di formica o qualcosa del genere? Sono un po 'nuovo di Java e non sono sicuro di come la gente di solito organizzi piccoli progetti come questo.
Dale Johnson,

4
Dall'interno src\WeakestLinkero solito javac Game\*.java Players\*.java Main.javacompilare ed java -cp .. WeakestLink.Maineseguire.
Linus,

Risposte:


22

Cecchino

L'idea generale è quella di mantenere uno degli stupidi giocatori (cioè quelli che è più probabile che sconfiggiamo in faccia) per cercare i punti. Successivamente cerchiamo di rimuovere gli altri giocatori di basso valore per aumentare il piatto. Ma quando arriviamo ai giocatori intelligenti, scegliamo di rimuovere quelli più pericolosi nel caso in cui il nostro stupido giocatore venga rimosso. In questo modo, se non abbiamo qualcuno da beccare, dovremmo trovare qualcuno contro cui almeno abbiamo una possibilità. Inoltre, dal momento che votiamo sempre con un giocatore minimo o massimo, mi aspetto che siamo abbastanza efficaci nel nostro cammino.

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

Quindi apparentemente il rollback non rimuove le modifiche. Se possibile, vorrei che tutte le modifiche fossero rimosse per chiarire abbondantemente questa è la versione originale.
Linus,

12

PrudentSniper

Sniper , ma con due comportamenti speciali. Uno è che se restano tre robot e PrudentSniper è il più intelligente, voterà per il bot centrale anziché il meno intelligente. Ciò gli consente di vincere alcuni altri showdown. L'altro comportamento è che se il bot più intelligente lo spara (votato per esso o il bot analogo l'ultima volta) e il meno intelligente non lo è, voterà per il più intelligente in autodifesa.

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

Non sono sicuro che entrambi i progressi abbiano lo stesso valore. Li hai provati separatamente?
Linus,

L'ho fatto, e mentre il caso dei tre robot è un miglioramento inequivocabile (almeno rispetto ai robot attualmente in master sul pronti contro termine), la punizione è quasi neutra, in rete. L'ho lasciato come una sorta di vago deterrente, una precauzione contro gli assassini.
istocratico,


Di recente ho corretto un bug in cui la smartness era 0-8 anziché 1-9. Questo ha rotto il tuo codice, quindi l'ho corretto (puoi trovare il codice aggiornato sul repository): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

12

Il culto

I giocatori di culto hanno uno schema di voto leggermente esoterico con il quale tentano di identificarsi a vicenda e votare come un gruppo, usando solo il record di voto. Poiché ogni membro del culto sa votare, chiunque voti in modo diverso viene rivelato come non membro e alla fine viene preso di mira per l'eliminazione.

Lo schema di voto a colpo d'occhio:

  • al primo turno vota per il concorrente più debole, lavorare in concerto con min & cecchino aiuta il culto a guadagnare potere
  • nei turni successivi vota i non membri noti fino a quando rimane solo il culto (votiamo il non membro di valore più basso per accumulare punti fintanto che pensiamo di avere il controllo).
  • quando rimangono solo membri, vota i membri di scarso valore per i punti (sacrificandoti per il bene del culto).

Il codice:

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

Pensieri finali:

Il culto ora passa al voto per i giocatori più pericolosi quando sono rimasti solo due o meno membri del culto per il confronto. L'ho provato più volte con cult_cnt>1e cult_cnt>2condizioni e il successivo vince più spesso.

Tuttavia, questa è una precauzione e il culto in realtà non è progettato per funzionare come giocatore solitario, quindi poiché il numero di nuovi giocatori aumenta il culto dovrebbe comunque perdere alla fine.


Non sarebbe meglio votare prima i non membri più intelligenti?
agweber,

Ho aggiornato il codice del controller in modo che la variabile casuale sia statica (e vi si possa accedere tramite Game.random). Ho anche preso la libertà di aggiornare il codice su github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill il

1
@NathanMerrill Grazie, ma mi sembra di ottenere risultati migliori se permetto al culto di essere più tollerante (vai alla figura) per i non membri sconosciuti che votano nel suo interesse.
Linus,

@agweber, grazie per il suggerimento. Questo probabilmente rende il giocatore un giocatore unico migliore, ma fintanto che ha i numeri dovrebbe cercare di aumentare il piatto. Penso che la mia nuova versione sia la migliore di entrambi.
Linus,

2
TheCult mi ha chiesto di richiedere che unusedPlayers.addAll(allPlayers);in Game.java sia duplicato circa nove volte, in modo che tutti i giocatori possano presentarsi in una molteplicità varia (come mescolare insieme più mazzi di carte) ... no, ovviamente non è una richiesta parziale ma è interessante vedere quanto può essere potente la strategia basata su team se hanno anche una piccola possibilità di essere messi insieme.
Linus,

7

BridgeBurner

Non da qualche parte dove posso provarlo adesso, e questo mi è sembrato un codice davvero brutto / stupido, ma dovrebbe funzionare.

Questo bot vuole solo essere odiato. Si vota per chi ha votato contro il minimo . In caso di pareggio, sceglie chi è andato più a lungo senza votarlo. In caso di un altro pareggio, sceglie il più intelligente di quelli (presumibilmente perché diventeranno il peggior nemico). Non voterà da solo, perché nessuno lo odierà davvero quando non ci sarà.

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

Non sono riuscito a far funzionare questo bot. Ho corretto diversi bug e ora vota per un giocatore inesistente. L'unica modifica che non ero sicuro che fosse corretta era che "last_round_voted" non era definito, quindi l'ho cambiato in "last_voted_against". Puoi trovare le mie modifiche qui: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Questo codice apparentemente era anche peggio di quanto pensassi. Ora che posso provarlo, guarderò entrambe le versioni e cercherò di farlo funzionare.
SnoringFrog

@NathanMerrill Trovato un paio di problemi. Vale a dire, non ho ignorato i giocatori che non sono stati trovati e che non hanno mai votato per il bot, motivo per cui ha sempre cercato di votare per loro. Ha anche usato la lista sbagliata per ottenere un indice da un punto, risultando nel -1voto del giocatore . Ma dovrebbe essere risolto ora.
SnoringFrog

1
Bene, funziona, ma fa terribile. Complimenti per aver battuto un giocatore a caso!
Nathan Merrill,

1
@NathanMerrill battendo il giocatore a volte
SnoringFrog

6

carro della banda

Segue la folla nel voto, a meno che non sia lui a essere preso di mira.

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

Immagino che questo renderà più forti i cecchini seguendoli, ma evita anche di essere preso di mira dal culto e dai cecchini in modo leggermente efficace. Potrebbe anche essere uno schermo di carne per i killer di cecchini o aiutarli se ce ne sono altri. (È necessario testare con gli ultimi aggiornamenti).

Utilizzo delle funzionalità di java 8 perché il gioco deve comunque funzionare.


1
È bello vedere un po 'di codice ben scritto :)
Nathan Merrill il

6

RevengePlayer

Questo bot voterà per chiunque abbia votato per lui il più delle volte, il tiebreaker è il giocatore più intelligente. La teoria è che un giocatore che ha votato per te in passato probabilmente voterà di nuovo per te.

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

Di recente ho corretto un bug in cui la smartness era 0-8 anziché 1-9. Questo ha rotto il tuo codice, quindi l'ho corretto (puoi trovare il codice aggiornato sul repository): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill la tua correzione per il mio codice aveva un piccolo bug. Ho modificato il mio codice per renderlo migliore.
MegaTom

5

MeanPlayer

Non votare né i giocatori più stupidi né i più intelligenti, e sta portando una pistola (passò di soppiatto oltre la sicurezza)

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

Non capisco perché questo giocatore sia più cattivo del resto / sarc
Nathan Merrill il

Attenzione @NathanMerrill, ha una pistola! Sceglierei attentamente le mie parole se fossi in te ...
CSᵠ

10
@ CSᵠ Non sono preoccupato. Quando è il giocatore medio, usa la pistola su se stesso.
Quintopia,

14
Questo giocatore è meno cattivo di quello che potrebbe essere. Sembra essere più mediana della media.
Yakk,

7
Ah ... mi ci è voluto un minuto
Ripristina Monica il

5

AntiExtremist

Questo socialista estremo crede che tutte le persone dovrebbero essere della stessa intelligenza. Cerca di uccidere quelli che sono molto più intelligenti o più stupidi di lui. Considera entrambi ma preferisce lo stupido in generale. Preferisce le persone stupide all'inizio e intelligenti alla fine, ma è ponderato in base a quanto siano estreme quelle persone.

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: Secondo Linus questo voterà come il cecchino la stragrande maggioranza delle volte (525602: 1228).


Per ora continuerò a correre a 10K (per test più rapidi). Quando eseguirò la corsa finale, probabilmente la ingrandirò.
Nathan Merrill,

Non sto provando ad accusarti di nulla, ma questo vota come Sniper avrebbe ~ il 99,7% delle volte, fondamentalmente sarà un lancio di monete su chi vince, dal momento che sono così vicini alla stessa strategia.
Linus,

Da dove hai preso quella statistica? Devo ammettere che ha una strategia semi-simile, ma il mio obiettivo era quello di cercare di migliorare qualcosa di semplice come il tuo scegliendo di votare per le persone che sono molto intelligenti se sono significativamente più intelligenti di me (alias non è probabile che vincerò il piatto se sopravvivono)
csga5000,

1
Ho dato alla tua classe un static Sniper S = new Sniper()e static long agrees=0, disagrees=0;. Nel tuo metodo di voto aggiungo S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);che calcola il modo in cui un cecchino voterebbe nella tua posizione, quindi inserisco la tua risposta in una variabile per calcolare se è stata accettata o meno prima di restituire la risposta. Una volta terminato il gioco, puoi stampare: accetta che era 525602: 1228.
Linus,

1
@Linus Questo ha senso, sembra legittimo. Aggiungerò una nota a riguardo.
csga5000,

5

Spiare

La spia è riservata. Non gli piace sparare per le persone più intelligenti. Allo stesso modo, non gli piace scegliere idioti indifesi di quartata . Quindi, gli piace eliminare quelli più vicini a lui in modo intelligente.

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

Sei appena stato pugnalato alle spalle, mes amis . Non gli importa se vince. Gli piace solo il suono del coltello nella schiena mentre ti vota con successo.

Sei appena stato pugnalato alle spalle.


4
Quell'immagine, però. +1
Addison Crump,

Penso che questo abbia un bug. Math.abs(enemyIntel - selfIntel) < closestInteldovrebbe essere Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@MegaTom Penso che tu abbia ragione. Lo verificherò ulteriormente quando avrò Java disponibile. Grazie per la possibile cattura!
Conor O'Brien,

4

MedianPlayer

Questo giocatore tenta di essere il più cattivo (beh, medianness) rimasto.

Si vota per eliminare gli avversari più intelligenti e più stupidi (con una leggera propensione a votare i più intelligenti), a seconda che ci siano più o meno più intelligenti / più stupidi di loro stessi.

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

quadro palesemente rubato da @Linus sopra.


Hai fatto lamentare il mio IDE per il codice duplicato!
Nathan Merrill,

@NathanMerrill Copy-pasta attack! Nota Ho cambiato il nome della classe da quando ho pubblicato. Suppongo che la duplicazione del nome della classe di qualcun altro per garantire che non si possa andare contro di loro sarebbe contro lo spirito delle regole.
Yakk,

2
Grazie per avermi palesemente rubato il mio lavoro, o almeno ammetterlo.
Linus,

2
@Linus Sei il benvenuto! Spero che l'imitazione sia la migliore adulazione.
Yakk,

2
@ csga5000 ha palesemente rubato il suo scherzo, e stavo solo giocando. Qualsiasi programmatore semi-competente (ad es. Me stesso) avrebbe scritto il ciclo allo stesso modo, quindi tutto ciò che ha fatto è stato rubare i miei nomi di variabili. Se avessi pensato di tutelarli, avrei potuto addebitare i diritti d'autore; )
Linus,

4

codardo

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;

  }
}

Semplicemente non vuole essere votato, quindi voti per l'avversario più simili al giocatore che è stato votato nell'ultimo round al fine di massimizzare le possibilità di far parte della squadra vincente.

Non va particolarmente bene in questo momento, ma potrebbe anche buttarlo nel mix.


Di recente ho corretto un bug in cui la smartness era 0-8 anziché 1-9. Questo ha rotto il tuo codice, quindi l'ho corretto (puoi trovare il codice aggiornato sul repository): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

4

Eroe

Esprime il voto a coloro che prendono di mira i deboli ... o lo infastidiscono.

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

Di recente ho corretto un bug in cui la smartness era 0-8 anziché 1-9. Questo ha rotto il tuo codice, quindi l'ho corretto (puoi trovare il codice aggiornato sul repository): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Grazie :)
TheNumberOne il

4

peso

Bob è solo il ragazzo medio che pensa di essere più intelligente di quanto non sia in realtà. Non riesco a vincere la famiglia di cecchini , ma ottengo la top 5 delle mie simulazioni per la maggior parte del tempo.

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

Seleziona un bersaglio a caso, quindi vota per loro finché non se ne sono andati. Non voterà per se stesso.

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

Anche questo codice non ha funzionato, ma è stata una soluzione semplice. Il tuo agire non è in realtà necessario, perché non ti do la tua intelligenza quando ti passo i tuoi attuali avversari. Il codice fisso può essere trovato qui: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Ho modificato il codice corretto nella mia risposta in modo che chiunque lo guardi qui veda cosa è effettivamente in esecuzione
SnoringFrog

4

statistica

Questa non è un'iscrizione al concorso. Questo è semplicemente un modo per ottenere utili statistiche di un gioco. Queste statistiche stampano la probabilità percentuale che un determinato giocatore venga votato in un round.

Per fare ciò aggiungere le seguenti righe in Round.javamodo che la parte superiore del file sia simile alla seguente:

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

...

Quindi modificare il metodo di voto per assomigliare a questo:

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

Esempio di output:

For 1th round:
55.554756% voted for 1
4.279166% voted for 2
1.355189% voted for 3
1.778786% voted for 4
3.592771% voted for 5
3.952368% voted for 6
1.779186% voted for 7
6.427149% voted for 8
21.280630% voted for 9

For 2th round:
2.889877% voted for 1
34.080927% voted for 2
6.826895% voted for 3
4.990010% voted for 4
5.914753% voted for 5
4.985510% voted for 6
3.302524% voted for 7
11.304360% voted for 8
25.705144% voted for 9

For 3th round:
2.152783% voted for 1
13.005153% voted for 2
21.399772% voted for 3
7.122286% voted for 4
6.122008% voted for 5
6.761774% voted for 6
11.687049% voted for 7
19.607500% voted for 8
12.141674% voted for 9

For 4th round:
2.122183% voted for 1
10.105719% voted for 2
11.917105% voted for 3
17.547460% voted for 4
8.626131% voted for 5
12.079103% voted for 6
18.819449% voted for 7
11.065111% voted for 8
7.717738% voted for 9

For 5th round:
1.689826% voted for 1
7.364821% voted for 2
9.681763% voted for 3
11.704946% voted for 4
20.336237% voted for 5
20.691914% voted for 6
13.062855% voted for 7
9.332565% voted for 8
6.135071% voted for 9

For 6th round:
1.456188% voted for 1
6.726546% voted for 2
10.154619% voted for 3
16.355569% voted for 4
22.985816% voted for 5
17.777558% voted for 6
11.580207% voted for 7
7.757938% voted for 8
5.205558% voted for 9

For 7th round:
1.037992% voted for 1
6.514748% voted for 2
15.437876% voted for 3
22.151823% voted for 4
17.015864% voted for 5
14.029088% voted for 6
11.907505% voted for 7
7.957136% voted for 8
3.947968% voted for 9

1
1o, 2o, 3o? Suggerirei di cambiarlo per stampare "Per il round 1" ecc.
Skyler,

3

MaxPlayer

Un tutto da sapere. Preferisce rimuovere chiunque abbia un'alta intelligenza (che può quindi sfidare il suo intelletto senza eguali)

public class MaxPlayer extends Player{

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

3

Guardia

Esprime il voto a quelli che prendono di mira i forti ... o quelli che lo infastidiscono.

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

Di recente ho corretto un bug in cui la smartness era 0-8 anziché 1-9. Questo ha rotto il tuo codice, quindi l'ho corretto (puoi trovare il codice aggiornato sul repository): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

3

Sanguisuga

Si affida ad altri robot per votare i ragazzi più intelligenti e più stupidi ... in un certo senso.

È soddisfatto di girare da qualche parte nel mezzo e alla fine dividere il piatto con il vincitore (dal momento che è in realtà un ragazzo bot davvero 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
Mi piace. Temo che non andrà bene, perché non molti voteranno come te. Questo è un difetto di questa competizione: mi sembra che gli altri robot ti costringano a conformarti a un certo tipo di strategia.
csga5000,

3
Comunque divertente comunque! Vincere non è tutto: ~)!
sweerpotato,

3

SniperKiller

Un'altra risposta sottratta spudoratamente al codice di Linus . Questo in ucciderà tutti i cecchini, non li proteggerà. Se sa che non sono rimasti cecchini, si comporterà come un cecchino stesso.

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
Mi piace l'idea, ma sembra esserci una cultura del voto per il giocatore minimo o massimo. votare per qualcun altro potrebbe buttare via il tuo voto . Forse se controlli se il massimo è cecchino prima di votare per qualcun altro ti raggiungerai un po '... (non posso controllare, al telefono)
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 elitario. Preferisce rimuovere chiunque abbia poca intelligenza.

public class MinPlayer extends Player {

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

2

VengefulSniper

Questo è iniziato come qualcosa che pensavo fosse chiamato in origine StupidBuffering(un nome che odiavo rinunciare), poi è finito per essere solo un PrudentSniper a cui non importava se veniva preso di mira. Anche questa sembrava essere l'unica ragione per cui non poteva battere PrudentSniper, quindi ho modificato un po 'le cose per focalizzarmi.

Ora, questo è fondamentalmente un cecchino, ma se il bot più intelligente o più stupido lo prende di mira, punterà a chiunque abbia ottenuto il maggior numero di voti nell'ultimo round. Se entrambi hanno ottenuto lo stesso numero di voti ed entrambi lo hanno preso di mira, torna al normale comportamento da cecchino. Nei miei test, questo in realtà batte PrudentSniper a volte.

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

Intermediario

Il MiddleMan fa del suo meglio per massimizzare i profitti mantenendo un occhio diffidente sul fatto che non è tagliato dal gioco. Tiene in giro concorrenti minori per migliorare le sue possibilità di passare al turno successivo (e di lasciare un finale facile). Voterà qualcuno più intelligente di lui solo se ci sono concorrenti più intelligenti di quanti meno concorrenti. Qualunque dei due gruppi, vota sempre per il più basso del gruppo per mantenere il piatto in salita.

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 spero che si compili, non sono un ragazzo Java.

Avevo in mente questo schema prima di leggere le altre voci. Poi sono stato sorpreso di quanto fosse vicino (ma di fondamentale importanza) Sniper, quindi sono andato avanti e l'ho usato come punto di partenza poiché non conosco la sintassi Java. Grazie @Lino


1
Per favore prova il tuo codice. non cercare di scrivere risposte in lingue che non conosci
TanMath il

@TanMath - Grazie per il tuo contributo. Ho molta esperienza in linguaggi simili a C / Java, tuttavia non in modo specifico Java, quindi sono abbastanza sicuro che il mio codice sia effettivamente corretto e funzionerà. Detto questo, se c'è un errore e non funzionerà, non sarò offeso se il maestro del gioco squalifica la voce.
tbernard

Hai ragione. Grazie @Lino. Modificato.
tbernard

1
@tbernard Sono felice di correggere i bug, ma il tuo codice non ne aveva :) :)
Nathan Merrill

Ahia. Non ha funzionato come speravo. Mi è sembrato di dare una mano a cecchino, quindi è qualcosa che immagino ahah.
tbernard

2

ApproximatePosition

Questo bot sta tentando di sparare approssimativamente attorno ai valori di smartness mancanti, supponendo che il gruppo continuerà con lo stesso modello, il che significa che avrà come target lo stesso tipo di target. Votare sempre per il più intelligente dei due giocatori quando c'è una scelta.

Per molto tempo non ho usato Java, e attualmente al lavoro, quindi ... Non posso provarlo, spero che non sia troppo difettoso, sii gentile per favore :).

A proposito, usa awt.Point solo perché sono troppo pigro per implementare una 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;
    }

}

Quindi, c'erano alcuni bug. :) Per prima cosa, sfortunatamente, il cast di Integer [] non funziona, deve essere un cast di Object [] (che non mi piace). Quindi ho inserito tutto in un ArrayList anziché in un array. In secondo luogo, questa riga: emptyPosition[emptyPosition.length]=j;ti darà sempre array fuori dai limiti. Infine, non so perché, ma voterai i giocatori che non sono presenti nel round.
Nathan Merrill,

Oh, anche, il tuo blocco ternario stava restituendo un doppio invece di int, ed era super contorto, l'ho trasformato in uno standard if / else. Puoi trovare tutte le mie modifiche su Github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Wow, grazie mille. Per il emptyPosition[emptyPosition.length], è un errore stupido in quanto la lunghezza è sempre una rispetto all'ultimo indice ^^. Grazie per le modifiche, userò questa nuova versione per correggerla. A proposito del blocco ternario ... sì, mi andava di usarlo, e forse troppo abituato a scrivere per me stesso, non era utile leggere, credo. Fare le correzioni e aggiornarlo.
Katenkyo,

2

SniperAide

Prima dell'aggiunta di PrudentSniper ho scritto un bot per aiutare Sniper a sconfiggere AntiExtremist e altre frodi (uso la parola con amore). Il bot, SniperAide, cerca i giocatori che votano come cecchini e vota come pensa che farebbero in caso di consensuses. Se tutti i giocatori sembrano cecchini, vota per il massimo, proteggendo i cecchini inferiori (che a questo punto passerebbero anche al massimo), anche se è lui stesso.

Il codice :

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

Attualmente non è di grande aiuto contro PrudentSniper.


Sulla base della tua descrizione e teoria non vedo come questo aiuterebbe qualsiasi robot simile a un cecchino a battere qualsiasi altro cecchino .. se non altro non proteggerebbe solo tutti i cecchini? Mi dispiace non ho più tempo per scavare nel tuo codice e capirlo davvero da solo.
csga5000,

@ csga5000, dal momento che potresti raramente identificare Sniper votando i record ora li protegge un po '. Ma quando una differenza è chiara, agisce sempre nell'interesse dei cecchini, quindi è soprattutto una specie di pareggio. L'attenzione alla vincita sono i giochi macroscopici, non i singoli round, nella maggior parte dei round non può fare altro che mantenere la situazione del lancio della moneta.
Linus,

1

HighOrLowNotSelf

Rimuove il giocatore di intelligenza più basso o più alto in modo casuale (ma non auto).

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

Quindi, ci sono un paio di bug con questa presentazione. Innanzitutto, Math.round () restituisce a long, non int. In secondo luogo, opsnon contiene te stesso. (Se volessi votare per te stesso, dovresti includerlo esplicitamente). Infine, l'if / se incluso non è valido Java. Ho corretto il tuo codice e l'ho aggiunto a github
Nathan Merrill il

1

Anarchico

All'anarchico non piacciono i regimi.
L'anarchico proverà a uccidere l'attuale presidente.
Se l'anarchico è presidente, decide di abusare del suo potere e uccidere i reagenti inutili. A meno che non sia stato preso di mira da uno dei suoi inferiori, perché invece dovrebbero bruciare.

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

Questo bot sa che la popolazione generale ha sempre torto! Quindi vota per chi ottiene il minor numero di voti.

Il codice è quasi identico al "Bandwagon" di SolarAaron, ma la logica finale è invertita.

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;
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.