Eres el eslabón más débil, adiós


50

Este desafío del se basa en el programa de juegos, Weakest Link . Para aquellos que no están familiarizados con el programa, el quid de este desafío es con quién votar :

  • Si los otros jugadores son más inteligentes que tú, entonces tienes menos posibilidades de obtener el bote.
  • Si los otros jugadores son más tontos que tú, entonces tienes menos bote para conseguir.

Al comienzo de cada ronda, el bote comienza con $ 0. Se forma un grupo de 9 jugadores, y cada jugador recibe una Inteligencia única del 1 al 9.

Al comienzo de cada turno, Pot += Smartnesspara cada jugador aún en la ronda. Luego, los jugadores votan sobre el jugador que desean eliminar. El jugador con más votos es eliminado. En caso de empate, se mantiene al jugador más inteligente.

Cuando solo quedan 2 jugadores en la ronda, se enfrentan en una batalla de ingenio. La posibilidad de que el jugador gane es Smartness/(Smartness+OpponentSmartness). El jugador ganador recibe el bote completo.

El jugador que ha recibido la mayor cantidad de dinero al final del juego gana.

De entrada y salida

Cada turno, recibirás la lista actual de oponentes. Tendrá acceso a su inteligencia y al historial de votación completo de todos los jugadores para la ronda a través de funciones en la clase Jugador.

Como resultado, debe devolver un número entero único, que represente al jugador por el que desea votar (que representa su inteligencia). Votar por ti mismo está permitido (pero no recomendado).

Las rondas de 9 se repetirán hasta que todos los jugadores hayan jugado al menos 1000 10000 rondas, y todos los jugadores hayan jugado en la misma cantidad de rondas.

Puede encontrar el controlador aquí: https://github.com/nathanmerrill/WeakestLink

Para crear un jugador, debe extender la clase Player y agregar su jugador a la clase PlayerFactory. Su clase debe seguir las siguientes reglas:

  1. La comunicación o interferencia con cualquier otro jugador (incluidos sus otros jugadores del mismo tipo) está estrictamente prohibida.

  2. La reflexión y las variables estáticas (excepto las constantes) no están permitidas.

  3. Si desea utilizar la aleatoriedad, he proporcionado una getRandom()función en la clase Player. Úselo, por lo que las simulaciones pueden ser deterministas.

He proporcionado muchas funciones en la clase Player para facilitar el acceso a los datos. Puede encontrarlos en línea en Github . Su jugador será instanciado en cada nueva ronda. Se permiten jugadores "tontos / suicidas" (pero no jugadores con la misma estrategia).

Puntuaciones

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
no entiendas esto: "Al comienzo de cada ronda ... Se forma un grupo de 9 jugadores, y cada jugador recibe una Inteligencia única" ¿no al comienzo del inicio del juego?
CSᵠ

1
@ CSᵠ correcto. Su inteligencia cambia de ronda en ronda (de lo contrario, sería injusto).
Nathan Merrill

2
debe ser el estrés y la alegría
CSᵠ

1
¿Debo esperar una configuración de compilación de hormigas o algo así? Soy un poco nuevo en Java, y no estoy seguro de cómo la gente suele configurar pequeños proyectos como este.
Dale Johnson

44
Desde dentro src\WeakestLinksolía javac Game\*.java Players\*.java Main.javacompilar y java -cp .. WeakestLink.Maincorrer.
Linus

Respuestas:


22

Francotirador

La idea general es mantenerse cerca de uno de los jugadores estúpidos (es decir, los que tenemos más probabilidades de vencer en el enfrentamiento) para obtener los puntos. Después de eso tratamos de eliminar a los otros jugadores de bajo valor para aumentar el bote. Pero cuando llegamos a los jugadores inteligentes, optamos por eliminar a los más peligrosos en caso de que eliminen a nuestro estúpido jugador . De esa manera, si no tenemos a alguien a quien atacar, deberíamos encontrar a alguien contra quien al menos tengamos una oportunidad. Además, dado que siempre votamos con un jugador mínimo o máximo, espero que seamos bastante efectivos para saludarnos.

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

Aparentemente, la reversión no elimina las ediciones. Si es posible, me gustaría que se eliminen las ediciones para que quede bastante claro, esta es la versión original.
Linus

12

Francotirador Prudente

Francotirador , pero con dos comportamientos de casos especiales. Una es que si quedan tres bots y PrudentSniper es el más inteligente, votará por el bot del medio en lugar del menos inteligente. Esto le permite ganar algunos enfrentamientos más. El otro comportamiento es que si el robot más inteligente lo está disparando (votó por él o el bot análogo la última vez) y el menos inteligente no lo es, votará por el más inteligente en defensa propia.

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

No estoy seguro de que ambos avances tengan el mismo valor. ¿Los has probado cada uno por separado?
Linus

Lo hice, y aunque el caso de los tres bots es una mejora inequívoca (al menos en contra de los bots actualmente en master en el repositorio), la retribución es neutral, en la red. Lo dejé como una especie de disuasivo vago, una precaución contra los asesinos.
histocrat


Recientemente arreglé un error donde la inteligencia era 0-8 en lugar de 1-9. Esto rompió su código, así que lo arreglé (puede encontrar el código actualizado en el repositorio): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

12

El culto

Los jugadores de culto tienen un esquema de votación levemente esotérico mediante el cual intentan identificarse entre sí y votar en grupo, utilizando solo el registro de votación. Dado que cada miembro del culto sabe votar, cualquiera que vote de manera diferente se revela como no miembro y eventualmente es objetivo de eliminación.

El esquema de votación de un vistazo:

  • en el primer turno, vote por el concursante más débil, trabajar en concierto con min & sniper ayuda al culto a ganar poder
  • en turnos posteriores, vote a los no miembros conocidos hasta que solo quede el culto (votamos por el no miembro de menor valor para acumular puntos mientras creamos que tenemos el control).
  • cuando solo queden miembros, vote por los miembros de bajo valor por los puntos (de hecho, sacrificándose por el bien del culto).

El código:

package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Iterator;
import java.util.Set;
public class TheCult extends Player {
    private int cult_vote;
    private boolean[] isMember = null;
    @Override
    public int vote(Set<Integer> currentOpponents) {
        //on first turn, vote the code
        if(isMember == null){
            isMember = new boolean[10];
            for(int i=10; --i!=0;) isMember[i]=true; //runs 9-1
            return cult_vote = 1;
        }
        //on all other turn, assess who is not voting with the cult
        Vote opp_vote;
        int cult_cnt=0;
        Iterator<Vote> votes = getRecentVotes().iterator();
        while(votes.hasNext()){
            opp_vote = votes.next();
            if(opp_vote.getVoted() != cult_vote)
                isMember[opp_vote.getVoter()] = false;
            else
                cult_cnt++;
        }
        //find weakest and stongest non-members, and weakest members
        Iterator<Integer> opps = currentOpponents.iterator();
        int opp_smrt, min_mem=10, min_non=10, max_non=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(isMember[opp_smrt]){
                if(opp_smrt < min_mem) min_mem = opp_smrt;
            }else{
                if(opp_smrt < min_non) min_non = opp_smrt;
                if(opp_smrt > max_non) max_non = opp_smrt;
            }
        }
        if(cult_cnt>2 && min_non!=10) cult_vote = min_non;
        else if(max_non!=0)           cult_vote = max_non;
        else                          cult_vote = min_mem;
        return cult_vote;
    }
}

Pensamientos finales:

El culto ahora cambia a votar por los jugadores más peligrosos cuando solo quedan dos o menos miembros del culto para el enfrentamiento. Lo probé varias veces con cult_cnt>1y cult_cnt>2condiciones y el último gana con más frecuencia.

Aún así, esto es una precaución y el culto realmente no está diseñado para funcionar como un jugador solitario, por lo que a medida que aumenta el número de nuevos jugadores, el culto aún debería perder con el tiempo.


¿No sería mejor votar primero a los no miembros más inteligentes?
agweber

He actualizado el código del controlador para que la variable aleatoria sea estática (y se puede acceder a través de Game.random). También me he tomado la libertad de actualizar el código en github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

1
@NathanMerrill Gracias, pero parece que obtengo mejores resultados si permito que el culto sea más tolerante (imagínense) a los no miembros desconocidos que votan en su interés.
Linus

@agweber, gracias por la sugerencia. Esto probablemente hace que el culto sea un mejor jugador único, pero siempre que tenga los números, debería intentar subir el bote. Creo que mi nueva versión es la mejor del mundo.
Linus

2
TheCult me pidió que solicite que unusedPlayers.addAll(allPlayers);en Game.java se duplique unas nueve veces, para que todos los jugadores puedan ocurrir en una multiplicidad variada (como barajar varias barajas de cartas) ... no, por supuesto, es una solicitud totalmente sesgada, pero Es interesante ver cuán poderosa puede ser la estrategia basada en el equipo si tienen incluso una pequeña posibilidad de ponerse juntos.
Linus

7

BridgeBurner

No en un lugar donde pueda probar esto en este momento, y salió como un código realmente feo / tonto, pero debería funcionar.

Este bot solo quiere ser odiado. Se vota por el que ha votado en contra del menos . En caso de empate, elige a quien haya pasado más tiempo sin votar por él. En caso de otro empate, elige al más inteligente de ellos (presumiblemente porque serán el peor enemigo). No votará por sí mismo, porque nadie realmente lo odiará cuando no esté cerca.

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

No pude hacer que este bot funcione. Solucioné varios errores, y ahora está votando por un jugador inexistente. El único cambio del que no estaba seguro si era correcto fue que "last_round_voted" no está definido, así que lo cambié a "last_voted_against". Puede encontrar mis cambios aquí: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Este código aparentemente fue incluso peor de lo que pensaba. Ahora que puedo probarlo, miraré ambas versiones e intentaré que esto funcione.
SnoringFrog

@NathanMerrill Encontró un par de problemas. Es decir, no ignoré a los jugadores que no estaban en el hallazgo que nunca votaron por el bot, por lo que siempre trató de votar por ellos. También usé la lista incorrecta para obtener un índice en un punto, lo que resultó en que el jugador -1fuera votado. Pero debería ser arreglado ahora.
SnoringFrog

1
Bueno, funciona, pero es terrible. ¡Felicidades por vencer al jugador aleatorio!
Nathan Merrill

1
@NathanMerrill sobre vencer a jugadores aleatorios a veces
SnoringFrog

6

Carro

Sigue a la multitud en la votación, a menos que él sea el objetivo.

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

Supongo que este solo hará que los francotiradores sean más fuertes al seguirlos, pero también evitará que el culto y los ayudantes de francotiradores sean el objetivo de una manera ligeramente efectiva. También podría ser un escudo de carne para los asesinos de francotiradores o ayudarlos si hay más de ellos. (Necesita probar con las últimas actualizaciones).

Uso de las funciones de Java 8 porque el juego necesita que se ejecute de todos modos.


1
Es agradable ver un código bien escrito :)
Nathan Merrill

6

VenganzaJugador

Este bot votará por quien haya votado por él la mayoría de las veces, siendo el desempate el jugador más inteligente. La teoría es que un jugador que votó por ti en el pasado probablemente volverá a votar por ti.

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

Recientemente arreglé un error donde la inteligencia era 0-8 en lugar de 1-9. Esto rompió su código, así que lo arreglé (puede encontrar el código actualizado en el repositorio): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill su solución para mi código tenía un pequeño error. Edité mi código para mejorarlo.
MegaTom

5

MeanPlayer

No vote ni a los jugadores más estúpidos ni a los más inteligentes, y él lleva una pistola (se escapó de la seguridad)

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

No entiendo por qué este jugador es más malo que el resto / sarc
Nathan Merrill

Cuidado @NathanMerrill, ¡tiene un arma! Elegiría mis palabras con cuidado si fuera tú ...
CSᵠ

10
@ CSᵠ No estoy preocupado. Cuando es el jugador promedio, usa el arma contra sí mismo.
quintopia

14
Este jugador es menos malo de lo que podría ser. Ella parece ser más mediana que mala.
Yakk

77
Hah ... me tomó un minuto
Restablecer a Monica el

5

AntiExtremista

Este socialista extremo cree que todas las personas deberían ser de igual inteligencia. Intenta matar a aquellos que son mucho más inteligentes o más tontos que él. Considera ambos, pero en general prefiere los tontos. Favorece a las personas tontas al principio e inteligentes al final, pero está ponderado en función de cuán extremas son esas personas.

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: Según Linus, esto votará igual que el francotirador la gran mayoría de las veces (525602: 1228).


Voy a mantener la carrera actual a 10K por ahora (para pruebas más rápidas). Cuando haga el recorrido final, probablemente lo haga más grande.
Nathan Merrill

No estoy tratando de acusarlo de nada, pero esto vota de la manera en que Sniper lo haría ~ 99.7% del tiempo, básicamente será un lanzamiento de moneda en cuanto a quién gana, ya que están muy cerca de la misma estrategia.
Linus

¿De dónde sacaste esa estadística? Admito que tiene una estrategia semi-similar, pero mi objetivo era tratar de mejorar algo tan simple como el tuyo eligiendo votar por personas que son muy inteligentes si son significativamente más inteligentes que yo (alias, no es probable que gane el olla si sobreviven)
csga5000

1
Le di a tu clase un static Sniper S = new Sniper()y static long agrees=0, disagrees=0;. En tu método de votación agregoS.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents); que calcula cómo votaría un francotirador en su posición, luego pongo su respuesta en una variable para contar si estuvo de acuerdo o en desacuerdo antes de devolver su respuesta. Una vez que el juego ha terminado, puede imprimir acepta: desacuerdo que era 525602: 1228.
Linus

1
@Linus Eso tiene sentido, suena legítimo. Agregaré una nota sobre eso.
csga5000

5

Espía

El espía está reservado. No le gusta disparar a las personas más inteligentes. Del mismo modo, no le gusta meterse con idiotas indefensos quartata . Entonces, le gusta eliminar a los más cercanos a él en inteligencia.

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

Te acaban de apuñalar por la espalda, mes amis . No le importa si gana. Simplemente le gusta el sonido del cuchillo en tu espalda mientras te vota con éxito.

Te acaban de apuñalar por la espalda.


44
Esa imagen, sin embargo. +1
Addison Crump

Creo que esto tiene un error. Math.abs(enemyIntel - selfIntel) < closestInteldebería ser Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@MegaTom Creo que tienes razón. Comprobaré esto más adelante cuando tenga Java disponible. Gracias por la posible captura!
Conor O'Brien

4

Jugador mediano

Este jugador intenta ser el más malo (bueno, la mediana) que queda.

Vota para eliminar a los oponentes más inteligentes y tontos (con un ligero sesgo hacia la votación de los más inteligentes), dependiendo de si hay más o menos más inteligentes / tontos que ellos mismos.

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

marco robado descaradamente de @Linus arriba.


¡Hiciste que mi IDE se quejara por código duplicado!
Nathan Merrill

@NathanMerrill ¡Copiar el ataque de pasta! Tenga en cuenta que cambié el nombre de la clase desde que publiqué. Como supongo, duplicar el nombre de la clase de otra persona para asegurarse de que no pueda ir en contra de ellos estaría en contra del espíritu de las reglas.
Yakk

2
Gracias por robar descaradamente mi trabajo, o por lo menos admitirlo.
Linus

2
@Linus ¡De nada! La imitación es la mejor adulación, espero.
Yakk

2
@ csga5000 robó descaradamente fue su broma, y ​​yo solo estaba jugando. Cualquier codificador medio competente (por ejemplo, yo mismo) escribiría el bucle de la misma manera, por lo que todo lo que realmente hizo fue robar mis nombres de variables. Si hubiera pensado en protegerlos, tal vez podría cobrar regalías; )
Linus

4

Cobarde

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;

  }
}

Simplemente no quiere ser votado, por lo que vota por el oponente más similar al jugador que fue votado en la última ronda para maximizar las posibilidades de estar en el equipo ganador.

No le va particularmente bien en este momento, pero también podría incluirlo en la mezcla.


Recientemente arreglé un error donde la inteligencia era 0-8 en lugar de 1-9. Esto rompió su código, así que lo arreglé (puede encontrar el código actualizado en el repositorio): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

4

Héroe

Vota a los que molestan al débil ... o lo molestan.

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

Recientemente arreglé un error donde la inteligencia era 0-8 en lugar de 1-9. Esto rompió su código, así que lo arreglé (puede encontrar el código actualizado en el repositorio): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Gracias :)
TheNumberOne

4

Mover

Bob es el tipo promedio que piensa que es más inteligente de lo que realmente es. No puedo ganar la familia de francotiradores, pero obtengo el top 5 en mis simulaciones la mayor parte del tiempo.

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

Elige un objetivo aleatorio, luego vota por ellos hasta que se hayan ido. Sin embargo, no votará por sí mismo.

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

Este código tampoco funcionó, pero fue una solución fácil. Tu do-while no es realmente necesario, porque no te doy tu inteligencia cuando te paso tus oponentes actuales. El código fijo se puede encontrar aquí: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Edité el código corregido en mi respuesta para que cualquiera que lo vea aquí vea lo que realmente se está ejecutando
SnoringFrog el

4

Estadística

Esta no es una entrada al concurso. Esta es simplemente una forma de obtener estadísticas útiles de un juego. Estas estadísticas imprimen el porcentaje de probabilidad de que un jugador en particular sea votado en una ronda.

Para hacer esto, agregue las siguientes líneas para Round.javaque la parte superior del archivo se vea así:

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

...

Luego modifique el método de votación para que se vea así:

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

Salida de ejemplo:

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º? Sugeriría cambiarlo para imprimir "Para la ronda 1", etc.
Skyler

3

MaxPlayer

Un sabelotodo. Prefiere eliminar a cualquiera con alta inteligencia (que por lo tanto puede desafiar su intelecto sin igual)

public class MaxPlayer extends Player{

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

3

Guardia

Vota a los que molestan al fuerte ... o a los que lo molestan.

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

Recientemente arreglé un error donde la inteligencia era 0-8 en lugar de 1-9. Esto rompió su código, así que lo arreglé (puede encontrar el código actualizado en el repositorio): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

3

Sanguijuela

Se basa en otros robots para votar a los tipos más inteligentes y tontos ... más o menos.

Está satisfecho con aparecer en algún lugar en el medio y, finalmente, dividir el bote con el ganador (ya que en realidad es un chico bot realmente 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
Me gusta. Sin embargo, me preocupa que no le vaya bien porque no muchos votarán igual que usted. Esa es una falla con esta competencia: me parece que los otros bots te obligan a ajustarte a un cierto tipo de estrategia.
csga5000

3
Aunque sigue siendo divertido! Ganar no lo es todo: ~)!
sweerpotato

3

SniperKiller

Otra respuesta robada descaradamente del código de Linus . Este en matará a todos los francotiradores, no los protegerá. Si sabe que no quedan francotiradores, actuará como un francotirador.

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
Me gusta la idea, pero parece haber una cultura de votar por el jugador mínimo o máximo. votar por alguien más podría estar descartando tu voto . Tal vez si comprueba si el máximo es francotirador antes de votar por otra persona, se pondrá al día un poco ... (no puedo comprobarlo por teléfono)
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 elitista. Prefiere eliminar a cualquiera con poca inteligencia.

public class MinPlayer extends Player {

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

2

Francotirador vengativo

Esto comenzó como algo que pensé que era original llamadoStupidBuffering (un nombre que odié renunciar), y luego terminó siendo solo un PrudentSniper a quien no le importaba si estaba siendo atacado. Esta también parecía ser la única razón por la que no podía vencer a PrudentSniper, por lo que modifiqué un poco las cosas para centrarme en eso.

Ahora, esto es básicamente un francotirador, pero si el robot más inteligente o más tonto se dirige a él, apuntará al que tenga más votos en la última ronda. Si ambos obtuvieron el mismo número de votos y ambos lo atacaron, él vuelve al comportamiento normal de francotirador. En mis pruebas, esto realmente supera a PrudentSniper en ocasiones.

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

El MiddleMan hace todo lo posible para maximizar las ganancias mientras se mantiene cauteloso de que no está excluido del juego. Se mantiene cerca de los concursantes menores para mejorar sus posibilidades de llegar a la siguiente ronda (y dejar un final fácil). Votará a alguien más inteligente que él solo si hay concursantes más inteligentes que concursantes menores. Cualquiera de los dos grupos, siempre vota por el más bajo del grupo para mantener la olla subiendo.

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

PD: espero que se compile, no soy un chico de Java.

Tenía este esquema en mente antes de leer las otras entradas. Luego me sorprendió lo cerca que estaba (pero críticamente diferente) de Sniper , así que seguí adelante y lo usé como punto de partida ya que no conozco la sintaxis de Java. Gracias @Linus


1
Por favor prueba tu código. no intente escribir respuestas en idiomas que no conoce
TanMath

@TanMath - Gracias por tu aporte. Tengo mucha experiencia en lenguajes similares a C / Java, sin embargo, no específicamente en Java, así que estoy bastante seguro de que mi código es correcto y funcionará. Dicho esto, si hay un error y no se ejecutará, no me ofenderá si el maestro del juego descalifica la entrada.
tbernard

Tienes razón. Gracias @Linus. Editado
tbernard

1
@tbernard Estoy feliz de corregir errores, pero su código no tenía ninguno :)
Nathan Merrill

Ay. No me fue tan bien como esperaba. Sin embargo, parecía ayudar a los francotiradores, así que eso es algo que supongo jaja.
tbernard

2

Posición aproximada

Este bot está tratando de disparar aproximadamente en torno a los valores de inteligencia faltantes, suponiendo que el grupo continuará con el mismo patrón, lo que significa que apuntará al mismo tipo de objetivo. Siempre vota por el más inteligente de los dos jugadores cuando hay una opción.

Hace mucho tiempo que no uso Java, y actualmente estoy en el trabajo, así que ... No puedo probarlo, espero que no sea demasiado defectuoso, sé amable, por favor :).

Por cierto, usa awt.Point solo porque soy demasiado vago para implementar 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;
    }

}

Entonces, hubo algunos errores. :) Primero, desafortunadamente, el reparto Integer [] no funciona, tiene que ser un reparto Object [] (que no me gusta). Así que lo envolví todo en una ArrayList en lugar de una matriz. En segundo lugar, esta línea: emptyPosition[emptyPosition.length]=j;siempre te dará una matriz fuera de los límites. Finalmente, no estoy seguro de por qué, pero votará a los jugadores que no están en la ronda.
Nathan Merrill

Ah, también, su bloque ternario estaba devolviendo un doble en lugar de int, y estaba súper enrevesado, lo convertí en un estándar si / si no. Puede encontrar todos mis cambios en Github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill Wow, muchas gracias. Para el emptyPosition[emptyPosition.length], es un error tonto ya que la longitud es siempre una sobre el último índice ^^. Gracias por los cambios, usaré esta nueva versión para corregirlo. Sobre el bloque ternario ... sí, tenía ganas de usarlo, y tal vez demasiado acostumbrado a escribir por mí mismo, no fue útil para leer, supongo. Haciendo las correcciones y actualizándolo.
Katenkyo

2

SniperAide

Antes de la adición de PrudentSniper , escribí un bot para ayudar a Sniper a vencer a AntiExtremist y otros fraudes (uso la palabra con amor). El bot, SniperAide, busca jugadores que voten como francotiradores y vota como cree que lo harían cuando hay consensos. Si todos los jugadores parecen francotiradores, vota por el máximo, protegiendo a los francotiradores inferiores (que también cambiarían al máximo en este punto), incluso si es él mismo.

El código :

package WeakestLink.Players;
import WeakestLink.Game.Vote;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

public class SniperAide extends Player {
    boolean[] sniperish;
    int[] sniperwouldvote;

    @Override
    public int vote(Set<Integer> currentOpponents) {
        int smrt = getSmartness();
        if(sniperish==null){
            sniperish = new boolean[10];
            sniperwouldvote = new int[10];
            for(int i=10;--i!=0;){
                sniperish[i] = true;
                sniperwouldvote[i] = 1;
            }
            sniperish[smrt]=false; //knows we are not the sniper
            return 1;
        }
        //figure out who might isn't a sniper
        Vote opp_vote;
        int opp_smrt;
        Iterator<Vote> votes = getRecentVotes().iterator();
        while(votes.hasNext()){
            opp_vote = votes.next();
            opp_smrt = opp_vote.getVoter();
            if(opp_vote.getVoted() != sniperwouldvote[opp_smrt])
                sniperish[opp_smrt] = false;
        }
        //include ourself in the simulation of other snipers.
        currentOpponents.add(smrt);
        //figure out how snipers would vote this round
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_snpr=0, cnt_opp=0, min_opp=10, max_opp=0;
        int[] snpr_votes = new int[10];
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(smrt == opp_smrt) continue;
            sniperwouldvote[opp_smrt] = hypothetically(opp_smrt, currentOpponents);
            cnt_opp++;
            if(sniperish[opp_smrt]){
                cnt_snpr++;
                snpr_votes[sniperwouldvote[opp_smrt]]++;
            }
            if(opp_smrt<min_opp) min_opp=opp_smrt;
            if(opp_smrt>max_opp) max_opp=opp_smrt;
        }
        //figure out how to vote in sniper's intrest when not identified
        if(cnt_snpr == cnt_opp)
            return max_opp;
        if(cnt_snpr == 0)
            return hypothetically(smrt, currentOpponents);
        //if multiple hypothetical snipers only vote how they agree
        int onlyvote = -1;
        for(int i=10; --i!=0;){
            if(onlyvote>0 && snpr_votes[i]!=0) onlyvote=-2;
            if(onlyvote==-1 && snpr_votes[i]!=0) onlyvote=i;
        }
        if(onlyvote>0) return onlyvote;
        return max_opp;
    }

    private int hypothetically(int smrt, Set<Integer> currentOpponents) {
        Iterator<Integer> opps = currentOpponents.iterator();
        int cnt_smrt=0, cnt_stpd=0, opp_smrt, min_stpd=10, max_smrt=0;
        while(opps.hasNext()){
            opp_smrt = opps.next().intValue();
            if(opp_smrt > smrt){
                cnt_smrt++;
                if(opp_smrt > max_smrt) max_smrt = opp_smrt;
            }
            else if(opp_smrt < smrt){
                cnt_stpd++;
                if(opp_smrt < min_stpd) min_stpd = opp_smrt;
            }
        }
        if(cnt_stpd>1) return min_stpd;
        return max_smrt;
    }
}

Actualmente no es de mucha ayuda contra PrudentSniper.


Según su descripción y teoría, no veo cómo esto ayudaría a un robot similar a un francotirador a vencer a otros francotiradores ... en caso de que no protegiera a todos los francotiradores. Lo siento, no tengo más tiempo para profundizar en su código y realmente lo entiendo por mí mismo.
csga5000

@ csga5000, dado que rara vez puede identificar a Sniper votando ahora, los protege a todos un poco. Pero cuando la diferencia es clara, siempre actúa en interés de los francotiradores, por lo que es principalmente una especie de desempate. El objetivo de ganar son los juegos macroscópicos, no las rondas individuales, en la mayoría de las rondas realmente no puede hacer nada más que mantener la situación de lanzar monedas.
Linus

1

HighOrLowNotSelf

Elimina aleatoriamente el jugador de inteligencia más bajo o más alto (pero no uno mismo).

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

Entonces, hay un par de errores con esta presentación. Primero, Math.round () devuelve a long, no int. En segundo lugar, opsno te contengas. (Si quisieras votar por ti mismo, deberías incluirlo explícitamente). Finalmente, el if / else que incluiste no es Java válido. Arreglé
Nathan Merrill

1

Anarquista

Al anarquista no le gustan los regímenes.
El anarquista intentará matar al actual presidente.
Si el anarquista es presidente, decide abusar de su poder y matar a los inútiles. A menos que fuera el objetivo de uno de sus inferiores, ya que deberían quemarse.

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

Votante independiente

¡Este bot sabe que la población general siempre está equivocada! Por lo tanto, vota por quien obtenga la menor cantidad de votos.

El código es casi idéntico al "Bandwagon" de SolarAaron, pero la lógica final es invertida.

package WeakestLink.Players;

import WeakestLink.Game.Vote;
import java.util.Map;
import java.util.Set;

/**
 * Votes for the currently lest voted bot in the game.
 * Or the lowest one.
 */
public class IndependentVoter
        extends Player {

    @Override
    public int vote(Set<Integer> currentOpponents) {
        int self = getSmartness(), vote = -1;
        java.util.Map<Integer, Integer> votes = new java.util.TreeMap<>();
        getVotingHistory().stream().map((Vote v)-> v.getVoted()).filter((Integer i)-> !i.equals(self)).forEach((Integer tgt)-> {
            if(!votes.containsKey(tgt)) {
                votes.put(tgt, 1);
            } else {
                votes.put(tgt, votes.get(tgt) + 1);
            }
        });

        do {
            if(votes.entrySet().isEmpty()) {
                vote = currentOpponents.stream().filter((Integer i)-> !i.equals(self)).sorted().findFirst().get();
            } else {
                if(votes.containsKey(vote)) {
                    votes.remove(vote);
                    vote = -1;
                }

                for(Map.Entry<Integer, Integer> vv: votes.entrySet()) {
                    Integer key = vv.getKey();
                    Integer value = vv.getValue();

                    if((vote == -1) || (value < votes.get(vote))) {
                        vote = key;
                    }
                }
            }
        } while(!currentOpponents.contains(vote));

        return vote;
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.