Anda adalah Tautan Terlemah, Selamat Tinggal

50

Ini tantangan didasarkan dari game show, Weakest Link . Bagi mereka yang tidak terbiasa dengan pertunjukan, inti dari tantangan ini berkaitan dengan siapa yang Anda pilih :

  • Jika pemain lain lebih pintar dari Anda, maka Anda memiliki peluang lebih sedikit untuk mendapatkan pot.
  • Jika pemain lain lebih bodoh dari Anda, maka Anda memiliki pot yang lebih sedikit.

Pada awal setiap putaran, Pot dimulai dengan $ 0. Sekelompok 9 pemain dibentuk, dan masing-masing pemain diberi Smartness unik dari 1 hingga 9.

Di awal setiap belokan, Pot += Smartnessuntuk setiap pemain masih di babak. Kemudian, pemain memberikan suara pada pemain yang ingin mereka hapus. Pemain dengan suara terbanyak dihapus. Dalam kasus seri, pemain yang lebih pintar disimpan.

Ketika hanya ada 2 pemain yang tersisa di babak, mereka berhadapan dalam pertempuran akal. Peluang pemain menang adalah Smartness/(Smartness+OpponentSmartness). Pemain yang menang kemudian menerima seluruh pot.

Pemain yang telah menerima uang paling banyak di akhir pertandingan menang.

Input output

Setiap belokan, Anda akan menerima daftar lawan saat ini. Anda akan memiliki akses ke kecerdasan Anda dan seluruh riwayat pemilihan seluruh pemain untuk putaran melalui fungsi di kelas Player.

Sebagai hasil, Anda harus mengembalikan bilangan bulat tunggal, mewakili pemain yang ingin Anda pilih (mewakili kecerdasannya). Voting untuk diri sendiri adalah diperbolehkan (tapi tidak direkomendasikan).

Babak 9 akan diulang sampai semua pemain bermain setidaknya 1.000 10.000 putaran, dan semua pemain telah bermain dalam jumlah putaran yang sama.

Anda dapat menemukan pengontrol di sini: https://github.com/nathanmerrill/WeakestLink

Untuk membuat pemain, Anda perlu memperluas kelas Player, dan menambahkan pemain Anda ke kelas PlayerFactory. Kelas Anda harus mengikuti aturan berikut:

  1. Komunikasi atau gangguan dengan pemain lain (termasuk pemain lain dengan jenis yang sama) sangat dilarang.

  2. Refleksi dan variabel statis (kecuali untuk konstanta) tidak diperbolehkan.

  3. Jika Anda ingin menggunakan keacakan, saya telah menyediakan getRandom()fungsi di kelas Player. Gunakan itu, sehingga simulasi bisa menjadi deterministik.

Saya telah menyediakan banyak fungsi di kelas Player untuk akses mudah ke data. Anda dapat menemukannya online di Github . Pemain Anda akan dipakai setiap babak baru. Pemain "Bisu / bunuh diri" diperbolehkan (tetapi tidak pemain dengan strategi yang sama).

Skor

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
Nathan Merrill
sumber
1
jangan mengerti ini: "Di awal setiap putaran ... Sekelompok 9 pemain terbentuk, dan setiap pemain diberi Kecerdasan unik" bukan pada awal permulaan pertandingan?
CSᵠ
1
@ CSᵠ benar. Kecerdasan Anda berubah dari satu putaran ke putaran lainnya (itu akan menjadi tidak adil jika tidak).
Nathan Merrill
2
harus menjadi stres dan kegembiraan
CSᵠ
1
Haruskah saya mengharapkan semut membangun konfigurasi atau semacamnya? Saya agak baru di java, dan saya tidak yakin bagaimana orang biasanya mengatur proyek kecil seperti ini.
Dale Johnson
4
Dari dalam src\WeakestLinksaya biasa javac Game\*.java Players\*.java Main.javamengkompilasi dan java -cp .. WeakestLink.Mainmenjalankan.
Linus

Jawaban:

22

Penembak jitu

Gagasan umum adalah mempertahankan salah satu pemain bodoh (yaitu pemain yang lebih mungkin kita kalahkan saat berhadapan) untuk merebut poin. Setelah itu kami mencoba untuk menghapus pemain bernilai rendah lainnya untuk meningkatkan pot. Tetapi ketika kita sampai ke pemain cerdas kita memilih untuk menghapus yang paling berbahaya kalau-kalau pemain bodoh kita dihapus. Dengan begitu, jika kita tidak memiliki seseorang untuk menembak kita harus mendapatkan seseorang yang setidaknya kita punya kesempatan untuk melawan. Juga, karena kami selalu memberikan suara dengan pemain minimum atau pemain maksimal, saya berharap kami cukup efektif dalam mendapatkan jalan kami.

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;
    }
}
Linus
sumber
Jadi ternyata rollback tidak menghapus suntingan. Jika mungkin saya ingin ada suntingan dihapus untuk membuatnya sangat jelas ini adalah versi asli.
Linus
12

PrudentSniper

Sniper , tetapi dengan dua perilaku kasus khusus. Salah satunya adalah jika ada tiga bot yang tersisa, dan PrudentSniper adalah yang paling cerdas, ia akan memilih bot tengah daripada yang paling tidak pintar. Ini memungkinkan untuk memenangkan beberapa pertikaian lagi. Perilaku lainnya adalah bahwa jika bot yang paling pintar memacu untuk itu (memilihnya atau bot analog terakhir kali) dan yang paling tidak pintar tidak, itu akan memilih yang paling cerdas dalam pertahanan diri.

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;
    }
}
histokrat
sumber
Saya tidak yakin kedua kemajuan sama nilainya. Sudahkah Anda mencobanya secara terpisah?
Linus
Saya lakukan, dan sementara kasus tiga bot adalah perbaikan yang jelas (setidaknya terhadap bot saat ini di master pada repo), retribusi adalah tentang netral, di internet. Aku meninggalkannya sebagai semacam pencegah yang samar, pencegahan terhadap pembunuh.
histokrat
relevan;)
Conor O'Brien
Saya baru-baru ini memperbaiki bug di mana kecerdasannya 0-8 bukannya 1-9. Ini memecahkan kode Anda, jadi saya memperbaikinya (Anda dapat menemukan kode yang diperbarui di repositori): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
12

Kultus

Para pemain kultus memiliki skema pemungutan suara yang agak esoteris dimana mereka mencoba mengidentifikasi satu sama lain dan memilih sebagai sebuah kelompok, hanya menggunakan catatan pemungutan suara. Karena setiap anggota kultus tahu cara memilih, siapa pun yang memilih secara berbeda diungkapkan sebagai bukan anggota dan akhirnya ditargetkan untuk dieliminasi.

Sekilas tentang skema pemungutan suara:

  • pada giliran pertama memilih untuk kontestan terlemah, bekerja dalam konser dengan min & sniper membantu kultus mendapatkan kekuatan
  • pada giliran berikutnya berikan suara non-anggota yang diketahui sampai hanya kultus yang tersisa (kami memberikan suara non-anggota bernilai terendah untuk mengumpulkan poin selama kami pikir kami memegang kendali).
  • ketika hanya anggota yang tersisa, pilih anggota bernilai rendah untuk poin (memang mengorbankan diri Anda untuk kebaikan sekte).

Kode:

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

Pikiran akhir:

Sekte sekarang beralih ke pemungutan suara untuk pemain paling berbahaya ketika hanya ada dua atau lebih sedikit anggota kultus yang tersisa untuk berhadapan. Saya diuji beberapa kali dengan cult_cnt>1dan cult_cnt>2kondisi dan menang kemudian lebih sering.

Namun, ini adalah tindakan pencegahan dan kultus benar-benar tidak dirancang untuk bekerja sebagai pemain tunggal, sehingga jumlah pemain baru meningkat kultus masih harus kalah pada akhirnya.

Linus
sumber
Tidakkah ini lebih baik untuk memilih non-anggota yang terpandai terlebih dahulu?
agweber
Saya telah memperbarui kode pengontrol sehingga variabel acak bersifat statis (dan dapat diakses melalui Game.random). Saya juga mengambil kebebasan memperbarui kode pada github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
1
@NathanMerrill Terima kasih, tapi saya tampaknya mendapatkan hasil yang lebih baik jika saya membiarkan kultus menjadi lebih toleran (angka) untuk non-anggota yang tidak dikenal yang memilih minat itu.
Linus
@agweber, Terima kasih atas sarannya. Ini mungkin membuat ini menjadi satu-satunya pemain yang lebih baik, tetapi selama ia memiliki angka itu harus mencoba untuk menjalankan pot. Saya pikir versi baru saya adalah yang terbaik dari kedua dunia.
Linus
2
TheCult menawar saya untuk meminta agar unusedPlayers.addAll(allPlayers);dalam Game.java diduplikasi sekitar sembilan kali, sehingga semua pemain dapat muncul dalam multiplisitas yang bervariasi (seperti menyeret bersama beberapa deck kartu) ... tidak tidak tentu saja, itu benar-benar permintaan yang bias tetapi Sangat menarik untuk melihat seberapa kuat strategi berbasis tim masih bisa jika mereka memiliki peluang kecil untuk disatukan.
Linus
7

BridgeBurner

Bukan di suatu tempat di mana saya dapat menguji ini sekarang, dan ini keluar terasa seperti kode yang benar-benar jelek / bodoh, tetapi harus bekerja.

Bot ini hanya ingin dibenci. Ini suara untuk siapapun yang memilih menentang itu yang paling . Dalam hal seri, ia memilih siapa pun yang telah berjalan paling lama tanpa memilihnya. Jika terjadi dasi lain, ia memilih yang paling pintar dari mereka (mungkin karena mereka akan membuat musuh terburuk). Itu tidak akan memilih sendiri, karena tidak ada yang akan benar-benar membencinya ketika tidak ada.

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));
        }
    }
}
SnoringFrog
sumber
Saya tidak dapat mengaktifkan bot ini. Saya memperbaiki beberapa bug, dan sekarang memilih untuk pemain yang tidak ada. Satu perubahan yang saya tidak yakin apakah itu benar adalah bahwa "last_round_voted" tidak didefinisikan, jadi saya mengubahnya menjadi "last_voted_against". Anda dapat menemukan perubahan saya di sini: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
@NathanMerrill Kode ini ternyata bahkan lebih buruk dari yang saya kira. Sekarang saya bisa mengujinya, saya akan melihat kedua versi dan mencoba untuk membuatnya bekerja.
SnoringFrog
@NathanMerrill Menemukan beberapa masalah. Yaitu, saya tidak mengabaikan pemain yang tidak ditemukan yang tidak pernah memilih bot, itulah sebabnya selalu mencoba untuk memilih mereka. Juga menggunakan daftar yang salah untuk mendapatkan indeks pada satu titik, menghasilkan pemain -1yang dipilih. Tapi itu harus diperbaiki sekarang.
SnoringFrog
1
Yah, itu berhasil, tetapi tidak mengerikan. Selamat atas pemukulan pemain acak!
Nathan Merrill
1
@NathanMerrill pada mengalahkan pemain acak kadang-kadang
SnoringFrog
6

Kereta musik

Mengikuti orang banyak dalam pemungutan suara, kecuali dia yang menjadi sasaran.

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

Saya kira yang satu ini hanya akan membuat penembak jitu lebih kuat dengan mengikuti mereka, tetapi juga menghindari menjadi sasaran oleh kultus dan pembantu sniper dengan cara yang sedikit efektif. Ini mungkin juga menjadi daging bagi pembunuh sniper atau membantu mereka jika ada lebih banyak dari mereka. (Perlu menguji dengan pembaruan terbaru).

Menggunakan fitur java 8 karena permainan tetap membutuhkannya.

SolarAaron
sumber
1
Sangat menyenangkan melihat beberapa kode yang ditulis dengan baik :)
Nathan Merrill
6

RevengePlayer

Bot ini akan memilih siapa pun yang memilihnya paling banyak, tiebreak menjadi pemain paling cerdas. Teorinya adalah bahwa pemain yang memilih Anda di masa lalu kemungkinan akan memilih Anda lagi.

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;
    }
}
MegaTom
sumber
Saya baru-baru ini memperbaiki bug di mana kecerdasannya 0-8 bukannya 1-9. Ini memecahkan kode Anda, jadi saya memperbaikinya (Anda dapat menemukan kode yang diperbarui pada repositori): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
@NathanMerrill perbaikan Anda untuk kode saya punya bug kecil. Saya mengedit kode saya untuk membuatnya lebih baik.
MegaTom
5

MeanPlayer

Pilih pemain yang paling bodoh atau paling cerdas, dan dia membawa pistol (menyelinap melewati keamanan)

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];
    }
}
CSᵠ
sumber
Saya tidak mengerti mengapa pemain ini lebih kejam dari yang lainnya / sarc
Nathan Merrill
Awas @NathanMerrill, dia punya pistol! Saya akan memilih kata-kata saya dengan hati-hati jika saya adalah Anda ...
CSᵠ
10
@ CSᵠ Saya tidak khawatir. Ketika dia pemain biasa, dia menggunakan pistol pada dirinya sendiri.
kuintopia
14
Pemain ini kurang kejam dari yang dia bisa. Dia tampaknya lebih median dari rata-rata.
Yakk
7
Hah .... butuh waktu sebentar
Reinstate Monica
5

Anti Ekstremis

Sosialis ekstrem ini percaya bahwa semua orang harus memiliki kecerdasan yang sama. Dia mencoba membunuh mereka yang jauh lebih pintar atau bodoh daripada dia. Dia menganggap keduanya tetapi dia lebih suka bisu secara umum. Dia memihak orang bodoh pada awalnya dan pandai pada akhirnya, tapi itu tertimbang berdasarkan seberapa ekstrim orang-orang itu.

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;

    }

}

CATATAN: Menurut Linus ini akan memberikan suara yang sama dengan penembak jitu sebagian besar waktu (525602: 1228).

csga5000
sumber
Saya akan terus menjalankan 10K saat ini untuk saat ini (untuk pengujian lebih cepat). Ketika saya melakukan final run through, saya kemungkinan akan membuatnya lebih besar.
Nathan Merrill
Saya tidak mencoba menuduh Anda tentang apa pun, tetapi ini memberikan suara seperti yang dilakukan Sniper ~ 99,7% dari waktu, pada dasarnya ini akan menjadi koin balik siapa yang menang, karena mereka sangat dekat dengan strategi yang sama.
Linus
Dari mana Anda mendapatkan statistik itu? Saya akui itu memiliki strategi semi-mirip tetapi tujuan saya adalah mencoba memperbaiki sesuatu yang sederhana seperti milik Anda dengan memilih untuk memilih orang-orang yang sangat cerdas jika mereka secara signifikan lebih pintar daripada saya (alias saya tidak mungkin memenangkan pot jika mereka selamat)
csga5000
1
Saya memberi kelas Anda static Sniper S = new Sniper()dan static long agrees=0, disagrees=0;. Dalam metode pemungutan suara saya, saya menambahkan S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);yang menghitung bagaimana penembak jitu akan memilih di posisi Anda, kemudian memasukkan jawaban Anda ke dalam variabel untuk menghitung apakah itu setuju atau tidak setuju sebelum mengembalikan jawabannya. Setelah permainan selesai, Anda dapat mencetak setuju: tidak setuju yang 525602: 1228.
Linus
1
@Linus Itu masuk akal, kedengarannya sah. Saya akan menambahkan catatan tentang itu.
csga5000
5

Mengintai

Mata-mata dicadangkan. Dia tidak suka menembak orang yang paling pintar. Demikian juga, dia tidak seperti memilih pada quartata idiot berdaya. Jadi, dia suka menghilangkan orang-orang terdekatnya dalam kecerdasan.

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

Anda baru saja ditikam, mes amis . Dia tidak peduli jika dia menang. Dia seperti suara pisau di punggung Anda saat ia memilih Anda dengan sukses.

Anda baru saja ditikam.

Conor O'Brien
sumber
4
Namun gambar itu. +1
Addison Crump
Saya pikir ini memiliki bug. Math.abs(enemyIntel - selfIntel) < closestIntelseharusnya Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom
@MegaTom, saya pikir Anda benar. Saya akan memeriksa ini lebih lanjut ketika saya memiliki Java tersedia. Terima kasih atas kemungkinan tangkapannya!
Conor O'Brien
4

MedianPlayer

Pemain ini berusaha untuk menjadi yang paling kejam (baik, medianness) yang tersisa.

Itu memilih untuk menghilangkan lawan paling pintar dan paling bodoh (dengan sedikit bias terhadap memilih dari yang paling cerdas), tergantung pada apakah ada lebih atau kurang lebih pintar / bodoh daripada mereka sendiri.

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

Kerangka kerja terang-terangan dicuri dari @Linus di atas.

Yakk
sumber
Anda membuat IDE saya mengeluh tentang kode duplikat!
Nathan Merrill
@NathanMerrill Serangan salin-pasta! Catatan saya mengubah nama kelas sejak saya memposting. Seperti yang saya duga menduplikasi nama kelas orang lain untuk memastikan bahwa Anda tidak dapat melawan mereka akan bertentangan dengan semangat peraturan.
Yakk
2
Terima kasih karena secara terang-terangan mencuri pekerjaan saya, atau mengakui setidaknya.
Linus
2
@Linus Anda dipersilakan! Imitasi adalah sanjungan terbaik, saya harap.
Yakk
2
@ csga5000 secara terang-terangan mencuri adalah leluconnya, dan saya hanya bermain bersama. Setiap coder setengah kompeten (mis. Saya sendiri) akan menulis loop dengan cara yang sama, jadi semua yang dia lakukan hanyalah mencuri nama variabel saya. Jika saya berpikir untuk memberi hak cipta kepada mereka, mungkin saya bisa mengenakan biaya royalti; )
Linus
4

Pengecut

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;

  }
}

Hanya tidak ingin mendapatkan suaranya, jadi suara untuk lawan yang paling mirip dengan pemain yang mendapat putaran terakhir untuk memaksimalkan peluang berada di tim yang menang.

Tidak melakukannya dengan sangat baik sekarang, tetapi mungkin juga melemparkannya ke dalam campuran.

histokrat
sumber
Saya baru-baru ini memperbaiki bug di mana kecerdasannya 0-8 bukannya 1-9. Ini memecahkan kode Anda, jadi saya memperbaikinya (Anda dapat menemukan kode yang diperbarui di repositori): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
4

Pahlawan

Memberi suara mereka yang memilih yang lemah ... atau mengganggunya

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;
    }
}
TheNumberOne
sumber
Saya baru-baru ini memperbaiki bug di mana kecerdasannya 0-8 bukannya 1-9. Ini memecahkan kode Anda, jadi saya memperbaikinya (Anda dapat menemukan kode yang diperbarui di repositori): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
@NathanMerrill Terima kasih :)
TheNumberOne
4

Bob

Bob hanyalah pria biasa yang berpikir bahwa dia lebih pintar daripada dia sebenarnya. Tidak dapat memenangkan keluarga penembak jitu tetapi mendapatkan 5 besar dalam simulasi saya sebagian besar waktu.

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



}
Averroes
sumber
4

FixatedPlayer

Pilih sasaran acak, lalu pilih untuk mereka sampai hilang. Tidak akan memilih dirinya sendiri.

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();
        }
    }
}
SnoringFrog
sumber
Kode ini juga tidak berfungsi, tetapi merupakan perbaikan yang mudah. Do-while Anda sebenarnya tidak perlu, karena saya tidak memberi Anda kepintaran Anda ketika saya memberikan Anda lawan saat ini. Kode tetap dapat ditemukan di sini: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
@NathanMerrill Saya mengedit kode yang diperbaiki ke dalam jawaban saya sehingga siapa pun yang melihatnya di sini melihat apa yang sebenarnya sedang dijalankan
SnoringFrog
4

Statistik

Ini bukan entri untuk kontes. Ini hanyalah cara untuk mendapatkan statistik permainan yang bermanfaat. Statistik ini mencetak persentase kemungkinan bahwa pemain tertentu akan kalah dalam satu ronde.

Untuk melakukan ini, tambahkan baris berikut ke Round.javasehingga bagian atas file terlihat seperti ini:

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

...

Kemudian modifikasi metode pemilihan agar terlihat seperti ini:

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

Contoh 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
TheNumberOne
sumber
1
1, 2, 3? Saya sarankan mengubahnya untuk mencetak "Untuk putaran 1" dll.
Skyler
3

MaxPlayer

Tahu segalanya. Lebih suka menyingkirkan siapa pun dengan kecerdasan tinggi (yang karenanya dapat menantang kecerdasannya yang tak tertandingi)

public class MaxPlayer extends Player{

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

Menjaga

Pilih yang memilih kuat ... atau yang mengganggu dia.

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;
    }
}
TheNumberOne
sumber
Saya baru-baru ini memperbaiki bug di mana kecerdasannya 0-8 bukannya 1-9. Ini memecahkan kode Anda, jadi saya memperbaikinya (Anda dapat menemukan kode yang diperbarui di repositori): github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
3

Lintah

Bergantung pada bot lain untuk memilih orang-orang yang paling pintar dan bodoh dari .. semacam.

Dia puas dengan muncul di suatu tempat di tengah dan akhirnya membelah pot dengan pemenang (karena dia sebenarnya adalah bot pria yang benar-benar layak ).

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);
            }
        }
    }
}
sweerpotato
sumber
2
Saya suka. Saya khawatir ini tidak akan berhasil karena tidak banyak yang akan memilih sama seperti Anda. Salah satu kelemahan dari kompetisi ini adalah bagiku bahwa bot lain memaksa Anda untuk menyesuaikan diri dengan jenis strategi tertentu.
csga5000
3
Masih menyenangkan! Menang bukanlah segalanya: ~)!
sweerpotato
3

SniperKiller

Jawaban lain tanpa malu-malu dicuri dari kode Linus . Yang ini akan membunuh semua penembak jitu, bukan melindungi mereka. Jika tahu bahwa tidak ada penembak jitu yang tersisa, itu akan bertindak seperti penembak jitu itu sendiri.

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;
    }
}
MegaTom
sumber
1
Saya suka ide itu, tetapi sepertinya ada budaya memilih pemain minimum atau maksimal. memberikan suara untuk orang lain mungkin akan membuang suara Anda . Mungkin jika Anda memeriksa apakah maksnya adalah sniperish sebelum memilih orang lain, Anda akan sedikit ketagihan ... (saya tidak dapat memeriksa, di telepon)
Linus
2

RandomPlayer

public class RandomPlayer extends Player{

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

MinPlayer

Seorang Elitist. Lebih suka menghapus siapa pun dengan kecerdasan rendah.

public class MinPlayer extends Player {

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

VengefulSniper

Ini dimulai sebagai sesuatu yang saya pikir asli disebut StupidBuffering(nama yang saya benci untuk menyerah), kemudian berakhir hanya PrudentSniper yang tidak peduli jika dia menjadi sasaran. Ini juga tampaknya menjadi satu-satunya alasan dia tidak bisa mengalahkan PrudentSniper, jadi saya sedikit mengubah hal-hal untuk menjadikannya fokus.

Sekarang, ini pada dasarnya adalah penembak jitu, tetapi jika bot paling pintar atau paling bodoh membidiknya, ia akan menargetkan siapa pun yang mendapat suara terbanyak di putaran terakhir. Jika mereka berdua mendapat jumlah suara yang sama dan keduanya menargetkannya, ia kembali ke perilaku sniper-y normal. Dalam pengujian saya, ini sebenarnya mengalahkan PrudentSniper pada kesempatan.

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;
        }
    }
}
SnoringFrog
sumber
2

Perantara

MiddleMan mencoba yang terbaik untuk memaksimalkan keuntungan sambil tetap waspada bahwa dia tidak terputus dari permainan. Dia terus berkeliling kontestan yang lebih rendah untuk meningkatkan peluangnya untuk mencapai babak berikutnya (dan untuk meninggalkan penyelesaian mudah). Dia akan memilih seseorang yang lebih pintar darinya hanya jika ada lebih banyak kontestan lebih pintar daripada ada lebih sedikit kontestan. Mana pun dari dua kelompok, ia selalu memilih yang terendah dari kelompok untuk menjaga pot tetap naik.

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 berharap itu mengkompilasi, saya bukan orang Jawa.

Pikirkan skema ini sebelum membaca entri lainnya. Kemudian saya terkejut seberapa dekat (tapi sangat berbeda) Sniper jadi saya pergi ke depan dan menggunakannya sebagai titik awal karena saya tidak tahu sintaksis Java. Terima kasih @Linus

tbernard
sumber
1
Silakan uji kode Anda. jangan mencoba menulis jawaban dalam bahasa yang Anda tidak tahu
TanMath
@TanMath - Terima kasih atas masukan Anda. Saya memiliki banyak pengalaman dalam bahasa C / Java, namun tidak khusus untuk Java, jadi saya cukup yakin bahwa kode saya sebenarnya benar dan akan berfungsi. Yang sedang berkata, jika ada kesalahan di dalamnya dan itu tidak akan berjalan saya tidak akan tersinggung jika master game mendiskualifikasi entri.
tbernard
Kamu benar. Terima kasih @Linus. Diedit.
tbernard
1
@ Mattard Saya senang memperbaiki bug, tetapi kode Anda tidak punya :)
Nathan Merrill
Aduh. Tidak melakukan dengan baik seperti yang saya harapkan. Aku sepertinya membantu penembak jitu, jadi itu sesuatu yang kurasa haha.
tbernard
2

Perkiraan Posisi

Bot ini mencoba memotret kira-kira di sekitar nilai kecerdasan yang hilang, dengan anggapan bahwa grup akan melanjutkan dengan pola yang sama, artinya akan menargetkan jenis target yang sama. Itu selalu memilih yang paling cerdas dari dua pemain ketika ada pilihan.

Lama saya tidak menggunakan Java, dan saat ini sedang bekerja jadi ... Tidak bisa mengujinya, harap tidak terlalu buggy, mohon dengan lembut :).

Omong-omong, ini menggunakan awt.Point hanya karena aku terlalu malas untuk mengimplementasikan tuple n_n.

package WeakestLink.Players;
import WeakestLink.Game.Vote;

import java.util.*;
import java.awt.Point;

public class ApproximatePosition extends Player
{

    @Override
    public int vote(Set<Integer> currentOpponent)
    {
        List<Integer> present = new ArrayList<>(currentOpponent);
        List<Integer> emptyPosition = new ArrayList<Integer>();
        Collections.sort(present);

        //If it is the first round, vote for the smartest buddy
        if(present.size()==8)
            return present.get(present.size()-1);


        int lastCheck=present.get(0);
        if(lastCheck>0)
            for(int i=0;i<lastCheck;i++)
                if(i!=getSmartness()&&!emptyPosition.contains(i))
                    emptyPosition.add(i);
        for(int i=1;i<present.size();i++)
        {
            if(present.get(i)-lastCheck>1)
                for (int j=lastCheck+1;j<present.get(i);j++)
                    if(j!=getSmartness()&&!emptyPosition.contains(j))
                        emptyPosition.add(j);
            lastCheck=present.get(i);
        }
        //untill there's at least 3 excluded members, we continue with this behaviour
        if(emptyPosition.size()<=2)
        {
            if(emptyPosition.isEmpty()) return present.get(present.size()-1);
            return decide(emptyPosition.get(0),present.get(present.size()-1),present.get(0),present);
        }

        Point maxRangeOfBlank=new Point(present.get(present.size()-1),present.get(present.size()-1));
        for (int i=0;i<emptyPosition.size()-1;i++)
            if(emptyPosition.get(i+1)-emptyPosition.get(i)==1)
            {
                int size=0;
                while(i+size+1<emptyPosition.size() && emptyPosition.get(i+size+1)-emptyPosition.get(i+size)==1)
                    size++;
                if(size>=sizeOfRange(maxRangeOfBlank))
                    maxRangeOfBlank=new Point(emptyPosition.get(i),emptyPosition.get(size));
                i+=size;
            }

        return decide(maxRangeOfBlank,present.get(present.size()-1),present.get(0),present);
    }

    private int decide(int blankSeat, int smartest,int dumbest,List<Integer> present)
    {
        return decide(new Point(blankSeat,blankSeat),smartest,dumbest,present);
    }

    private int decide(Point rangeBlankSeat, int smartest,int dumbest,List<Integer> present)
    {
        int target= smartest;
        if (rangeBlankSeat.getY()==smartest||((int)rangeBlankSeat.getY()+1)==getSmartness()){
            if ((rangeBlankSeat.getX()==dumbest||(int)rangeBlankSeat.getX()-1==getSmartness())){
                target= smartest; //should not happen
            } else {
                target= (int) rangeBlankSeat.getX()-1; //Vote for dumber than the missing
            }
        } else {
            target= (int) rangeBlankSeat.getY() +1; //Vote for smarter than the missing, default comportment
        }
        if(present.contains(target))
            return target;
        return smartest;
    }
    //Return the number of consecutive values between X and Y (included)
    private int sizeOfRange(Point range)
    {
        return (int)(range.getY()-range.getX())+1;
    }

}
Katenkyo
sumber
Jadi ada beberapa bug. :) Pertama, sayangnya, pemeran Integer [] tidak berfungsi, itu harus menjadi pemeran Object [] (yang saya tidak suka). Jadi saya membungkus semuanya menjadi ArrayList, bukan array. Kedua, baris ini: emptyPosition[emptyPosition.length]=j;akan selalu memberi Anda array di luar batas. Akhirnya, tidak yakin mengapa, tetapi Anda akan memilih pemain yang tidak ada dalam putaran.
Nathan Merrill
Oh, juga, blok ternary Anda mengembalikan double bukan int, dan sangat berbelit-belit, saya mengubahnya menjadi standar jika / selain itu. Anda dapat menemukan semua perubahan saya di Github: github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill
@NathanMerrill Wow, terima kasih banyak. Untuk emptyPosition[emptyPosition.length]itu, itu adalah kesalahan bodoh karena panjang selalu satu di atas indeks terakhir ^^. Terima kasih atas perubahannya, saya akan menggunakan versi baru ini untuk memperbaikinya. Tentang blok ternary ... yeah, merasa ingin menggunakannya, dan mungkin terlalu terbiasa menulis untuk diriku sendiri, tidak berguna untuk membaca kurasa. Melakukan koreksi dan memperbaruinya.
Katenkyo
2

SniperAide

Sebelum penambahan PrudentSniper saya menulis bot untuk membantu Sniper mengalahkan AntiExtremist dan penipuan lainnya (saya menggunakan kata itu dengan cinta). Bot, SniperAide, mencari pemain yang memilih seperti penembak jitu dan memilih seperti yang mereka pikirkan ketika ada konsensus. Jika semua pemain terlihat seperti penembak jitu ia memilih untuk max, melindungi Penembak jitu yang lebih rendah (yang juga akan beralih ke max pada saat ini), bahkan jika itu adalah dirinya sendiri.

Kode :

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

Dia saat ini tidak banyak membantu melawan PrudentSniper.

Linus
sumber
Berdasarkan uraian dan teori Anda, saya tidak melihat bagaimana ini akan membantu bot seperti penembak jitu mengalahkan penembak jitu lainnya .. jika ada sesuatu yang tidak hanya melindungi semua penembak jitu? Maaf saya tidak punya lebih banyak waktu untuk menggali kode Anda dan benar-benar memahaminya sendiri.
csga5000
@ csga5000, Karena Anda mungkin jarang mengidentifikasi Sniper dengan memilih, sekarang hal itu sedikit melindungi mereka. Tetapi ketika perbedaan jelas itu selalu bertindak dalam kepentingan Penembak jitu, sehingga sebagian besar semacam tie-breaker. Fokus pada kemenangan adalah permainan makroskopis, bukan putaran individu, di sebagian besar putaran itu benar-benar tidak bisa melakukan apa-apa selain mempertahankan situasi flip koin.
Linus
1

HighOrLowNotSelf

Menghapus pemain intelijen terendah atau tertinggi secara acak (tetapi tidak mandiri).

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;
    }
}
username.ak
sumber
Jadi, ada beberapa bug dengan pengiriman ini. Pertama, Math.round () mengembalikan a long, bukan int. Kedua, opstidak mengandung diri sendiri. (Jika Anda ingin memilih sendiri, secara eksplisit Anda harus memasukkannya). Terakhir, if / else yang Anda masukkan bukan Java valid. Saya telah memperbaiki kode Anda, dan menambahkannya ke github
Nathan Merrill
1

Anarkis

Kaum anarkis tidak menyukai rezim.
Sang anarkis akan mencoba membunuh presiden saat ini.
Jika anarkis adalah presiden, ia memutuskan untuk menyalahgunakan kekuasaannya dan membunuh para perampas yang tidak berguna. Kecuali jika dia menjadi sasaran salah satu bawahannya, karena mereka seharusnya membakar.

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

}
Bassdrop Cumberwubwubwub
sumber
1

Pemilih Independen

Bot ini tahu bahwa populasi umum selalu salah! Jadi ia memilih siapa pun yang mendapat suara paling sedikit.

Kode ini hampir identik dengan "Bandwagon" SolarAaron, tetapi logika akhirnya dibalik.

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