Bạn là liên kết yếu nhất, Tạm biệt


50

Đây thách thức là dựa tắt của các chương trình trò chơi, liên kết yếu nhất . Đối với những người không quen thuộc với chương trình, mấu chốt của thử thách này liên quan đến người bạn bỏ phiếu :

  • Nếu những người chơi khác thông minh hơn bạn, thì bạn sẽ ít có cơ hội nhận được tiền cược.
  • Nếu những người chơi khác ngu hơn bạn, thì bạn sẽ có ít tiền hơn.

Vào đầu mỗi vòng, Pot bắt đầu với $ 0. Một nhóm 9 người chơi được hình thành, và mỗi người chơi được đưa ra một độc đáo smartness 1-9.

Khi bắt đầu mỗi lượt, Pot += Smartnesscho mỗi người chơi vẫn vào vòng trong. Sau đó, người chơi bỏ phiếu cho người chơi mà họ muốn xóa. Người chơi có nhiều phiếu nhất sẽ bị xóa. Trong trường hợp hòa, người chơi thông minh hơn được giữ.

Khi chỉ còn 2 người chơi vào vòng trong, họ phải đối mặt trong một trận chiến trí tuệ. Cơ hội của người chơi chiến thắng là Smartness/(Smartness+OpponentSmartness). Người chơi chiến thắng sau đó nhận được toàn bộ tiền cược.

Người chơi nào nhận được nhiều tiền nhất vào cuối trò chơi sẽ thắng.

Đầu ra đầu vào

Mỗi lượt, bạn sẽ nhận được danh sách đối thủ hiện tại. Bạn sẽ có quyền truy cập vào sự thông minh của mình và toàn bộ lịch sử bầu chọn của người chơi cho vòng đấu thông qua các chức năng trong lớp Người chơi.

Là đầu ra, bạn phải trả về một số nguyên duy nhất, đại diện cho người chơi bạn muốn bỏ phiếu (đại diện cho sự thông minh của họ). Bỏ phiếu cho chính mình được cho phép (nhưng không được khuyến khích).

Vòng 9 sẽ lặp lại cho đến khi tất cả người chơi đã chơi ít nhất 1000 10000 vòng và tất cả người chơi đã chơi trong cùng một số vòng.

Bạn có thể tìm thấy bộ điều khiển ở đây: https://github.com/nathanmerrill/WeakestLink

Để tạo trình phát, bạn cần mở rộng lớp Trình phát và thêm trình phát của mình vào lớp PlayerFactory. Lớp học của bạn phải tuân theo các quy tắc sau:

  1. Liên lạc hoặc can thiệp với bất kỳ người chơi nào khác (bao gồm những người chơi khác cùng loại của bạn) đều bị nghiêm cấm.

  2. Các biến phản xạ và tĩnh (trừ các hằng số) không được phép.

  3. Nếu bạn muốn sử dụng tính ngẫu nhiên, tôi đã cung cấp một getRandom()hàm trong lớp Player. Sử dụng nó, vì vậy mô phỏng có thể được xác định.

Tôi đã cung cấp nhiều chức năng trong lớp Player để dễ dàng truy cập dữ liệu. Bạn có thể tìm thấy chúng trực tuyến trên Github . Người chơi của bạn sẽ được khởi tạo mỗi vòng mới. Người chơi "ngu ngốc / tự tử" được phép (nhưng không phải người chơi có cùng chiến lược).

Điểm số

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
đừng hiểu điều này: "Vào đầu mỗi vòng ... Một nhóm gồm 9 người chơi được thành lập và mỗi người chơi được cung cấp một Thông minh duy nhất" không phải khi bắt đầu trò chơi?
CSᵠ

1
@ CSᵠ đúng. Sự thông minh của bạn thay đổi từ vòng này sang vòng khác (nếu không sẽ không công bằng).
Nathan Merrill

2
phải là sự căng thẳng và niềm vui
CSᵠ

1
Tôi có nên mong đợi một cấu hình xây dựng kiến ​​hoặc một số như vậy? Tôi mới làm quen với java và tôi không chắc mọi người thường thiết lập các dự án nhỏ như dự án này như thế nào.
Dale Johnson

4
Từ bên trong src\WeakestLinktôi đã sử dụng javac Game\*.java Players\*.java Main.javađể biên dịch và java -cp .. WeakestLink.Mainchạy.
Linus

Câu trả lời:


22

Kẻ bắn tỉa

Ý tưởng chung là giữ xung quanh một trong những người chơi ngu ngốc (tức là những người mà chúng ta có nhiều khả năng đánh bại khi đối mặt) để bắn tỉa cho các điểm. Sau đó, chúng tôi cố gắng loại bỏ những người chơi có giá trị thấp khác để nâng cao số tiền. Nhưng khi chúng tôi đến với những người chơi thông minh, chúng tôi sẽ chọn loại bỏ những người nguy hiểm nhất trong trường hợp người chơi ngu ngốc của chúng tôi bị xóa. Theo cách đó, nếu chúng ta không có ai đó để bắn tỉa, chúng ta nên có một người mà chúng ta ít nhất có cơ hội chống lại. Ngoài ra, vì chúng tôi luôn bỏ phiếu với một người chơi tối thiểu hoặc tối đa, tôi hy vọng chúng tôi khá hiệu quả trong việc tìm đường.

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

Vì vậy, rõ ràng rollback không loại bỏ các chỉnh sửa. Nếu có thể, tôi muốn xóa mọi chỉnh sửa để làm cho nó rõ ràng rõ ràng đây là phiên bản gốc.
Linus

12

PrudentSniper

Sniper , nhưng với hai hành vi trường hợp đặc biệt. Một là nếu có ba bot còn lại và PrudentSniper là thông minh nhất, nó sẽ bỏ phiếu cho bot giữa thay vì kém thông minh nhất. Điều này cho phép nó giành chiến thắng thêm một vài trận đấu. Hành vi khác là nếu bot thông minh nhất đang bắn súng cho nó (đã bình chọn cho nó hoặc bot tương tự lần trước) và kém thông minh nhất thì không, nó sẽ bầu cho người thông minh nhất để tự vệ.

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

Tôi không chắc chắn rằng cả hai tiến bộ đều có giá trị như nhau. Bạn đã thử chúng riêng biệt?
Linus

Tôi đã làm, và trong khi ba trường hợp bot là một cải tiến rõ ràng (ít nhất là chống lại các bot hiện đang làm chủ trên repo), thì quả báo là về trung tính, trên mạng. Tôi để nó như một loại răn đe mơ hồ, một biện pháp phòng ngừa các sát thủ.
lịch sử


Gần đây tôi đã sửa một lỗi trong đó độ thông minh là 0-8 thay vì 1-9. Điều này đã phá vỡ mã của bạn, vì vậy tôi đã sửa nó (bạn có thể tìm thấy mã được cập nhật trên kho lưu trữ): github.com/nathanmerrill/WeakestLink/blob/master/src/ Khăn
Nathan Merrill

12

TheCult

Những người chơi sùng bái có một kế hoạch bỏ phiếu bí truyền nhẹ, qua đó họ cố gắng xác định lẫn nhau và bỏ phiếu như một nhóm, chỉ sử dụng hồ sơ bỏ phiếu. Vì mỗi thành viên của giáo phái đều biết cách bỏ phiếu, bất cứ ai bầu khác nhau đều được tiết lộ là người không phải là thành viên và cuối cùng bị nhắm mục tiêu để loại bỏ.

Sơ đồ bỏ phiếu trong nháy mắt:

  • trong lần bỏ phiếu đầu tiên cho thí sinh yếu nhất, làm việc trong buổi hòa nhạc với min & sniper giúp giáo phái có được sức mạnh
  • trong các lượt tiếp theo bỏ phiếu cho những người không phải là thành viên đã biết cho đến khi chỉ còn giáo phái (chúng tôi bỏ phiếu cho những người không phải là thành viên có giá trị thấp nhất để đạt được điểm miễn là chúng tôi nghĩ rằng mình đang kiểm soát).
  • khi chỉ còn các thành viên, bỏ phiếu cho các thành viên có giá trị thấp để lấy điểm (thực sự hy sinh bản thân vì lợi ích của giáo phái).

Mật mã:

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

Suy nghĩ cuối cùng:

Giáo phái bây giờ chuyển sang bỏ phiếu cho những người chơi nguy hiểm nhất khi chỉ còn hai hoặc ít hơn các thành viên giáo phái để đối mặt. Tôi đã thử nghiệm nó nhiều lần với cult_cnt>1cult_cnt>2điều kiện và sau đó chiến thắng thường xuyên hơn.

Tuy nhiên, đây là một biện pháp phòng ngừa và giáo phái thực sự không được thiết kế để hoạt động như một người chơi đơn độc, vì vậy khi số lượng người chơi mới tăng giáo phái vẫn sẽ mất dần.


Điều này sẽ không tốt hơn để bỏ phiếu cho những người không phải thành viên thông minh nhất trước?
agweber

Tôi đã cập nhật mã điều khiển để biến ngẫu nhiên là tĩnh (và có thể được truy cập qua Game.random). Tôi cũng có quyền tự do cập nhật mã trên github: github.com/nathanmerrill/WeakestLink/blob/master/src/ Lỗi
Nathan Merrill

1
@NathanMerrill Cảm ơn, nhưng tôi dường như có được kết quả tốt hơn nếu tôi cho phép giáo phái trở nên khoan dung hơn (đi theo con số) đối với những người không phải là thành viên bỏ phiếu quan tâm.
Linus

@agweber, Cảm ơn bạn đã gợi ý. Điều này có thể làm cho thecult trở thành một người chơi duy nhất tốt hơn, nhưng miễn là nó có số thì nên cố gắng chạy lên pot. Tôi nghĩ rằng phiên bản mới của tôi là tốt nhất của cả hai thế giới.
Linus

2
TheCult trả giá cho tôi để yêu cầu unusedPlayers.addAll(allPlayers);trong Game.java được nhân đôi khoảng chín lần, để tất cả người chơi có thể xảy ra với nhiều cấp độ khác nhau (như xáo trộn nhiều bộ bài) ... tất nhiên, đó không phải là một yêu cầu thiên vị nhưng thật thú vị khi thấy chiến lược dựa trên nhóm có thể mạnh đến mức nào nếu họ thậm chí có một cơ hội nhỏ để kết hợp với nhau.
Linus

7

Cầu quay

Không phải nơi nào tôi có thể kiểm tra điều này ngay bây giờ, và điều này xuất hiện cảm giác như mã thực sự xấu xí / ngu ngốc, nhưng nó sẽ hoạt động.

Bot này chỉ muốn bị ghét. Nó bỏ phiếu cho bất cứ ai đã bỏ phiếu chống lại nó ít nhất . Trong trường hợp hòa, nó chọn bất cứ ai đã đi lâu nhất mà không bỏ phiếu cho nó. Trong trường hợp có một chiếc cà vạt khác, nó chọn người thông minh nhất trong số đó (có lẽ vì họ sẽ tạo ra kẻ thù tồi tệ nhất). Nó sẽ không bỏ phiếu cho chính nó, bởi vì không ai sẽ thực sự ghét nó khi nó không ở gần.

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

Tôi đã không thể làm cho bot này hoạt động. Tôi đã sửa một số lỗi và hiện đang bỏ phiếu cho một người chơi không tồn tại. Một thay đổi tôi không chắc là nó có đúng hay không là "last_round_vote" không được xác định, vì vậy tôi đã thay đổi nó thành "last_vote_against". Bạn có thể tìm thấy những thay đổi của tôi ở đây: github.com/nathanmerrill/WeakestLink/blob/master/src/ Kẻ
Nathan Merrill

@NathanMerrill Mã này rõ ràng thậm chí còn tồi tệ hơn tôi nghĩ. Bây giờ tôi có thể kiểm tra nó, tôi sẽ xem xét cả hai phiên bản và cố gắng để nó hoạt động.
SnoringFrog

@NathanMerrill Tìm thấy một vài vấn đề. Cụ thể, tôi đã không bỏ qua những người chơi không tìm thấy bot mà không bao giờ bỏ phiếu cho bot, đó là lý do tại sao nó luôn cố gắng bỏ phiếu cho họ. Cũng sử dụng danh sách sai để lấy chỉ mục tại một thời điểm, dẫn đến việc người chơi -1được bình chọn. Nhưng nó nên được sửa chữa ngay bây giờ.
SnoringFrog

1
Vâng, nó hoạt động, nhưng làm khủng khiếp. Chúc mừng người chơi đánh bại ngẫu nhiên!
Nathan Merrill

1
@NathanMerrill đôi khi
SnoringFrog

6

Phong trào

Theo dõi đám đông bỏ phiếu, trừ khi anh ta là người được nhắm đến.

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

Tôi đoán điều này sẽ giúp lính bắn tỉa mạnh hơn bằng cách theo dõi họ, nhưng cũng tránh bị nhắm vào giáo phái và xạ thủ bắn tỉa một cách hiệu quả. Nó cũng có thể là một meatshield cho những kẻ giết người bắn tỉa hoặc hỗ trợ họ nếu có thêm họ. (Cần kiểm tra với các bản cập nhật mới nhất).

Sử dụng các tính năng java 8 vì trò chơi cần điều đó để chạy.


1
Thật tuyệt khi thấy một số mã được viết tốt :)
Nathan Merrill

6

Trả thù

Bot này sẽ bình chọn cho bất cứ ai bầu chọn cho anh ta nhiều lần nhất, tiebreaker là người chơi thông minh nhất. Lý thuyết là một người chơi đã bình chọn cho bạn trong quá khứ có thể sẽ bỏ phiếu cho bạn một lần nữa.

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

Gần đây tôi đã sửa một lỗi trong đó độ thông minh là 0-8 thay vì 1-9. Điều này đã phá vỡ mã của bạn, vì vậy tôi đã sửa nó (bạn có thể tìm thấy mã được cập nhật trên kho lưu trữ): github.com/nathanmerrill/WeakestLink/blob/master/src/ Khăn
Nathan Merrill

@NathanMerrill bản sửa lỗi cho mã của tôi có một lỗi nhỏ. Tôi đã chỉnh sửa mã của mình để làm cho nó tốt hơn.
MegaTom

5

Nghĩa là

Bầu chọn những người ngu ngốc nhất cũng không phải là người chơi thông minh nhất và anh ta mang theo một khẩu súng (lén lút bảo mật)

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

Tôi không hiểu tại sao người chơi này lại có ý nghĩa hơn bất kỳ ai khác / mỉa mai
Nathan Merrill

Xem ra @NathanMerrill, anh ta có một khẩu súng! Tôi sẽ chọn lời nói của mình một cách cẩn thận nếu tôi là bạn ...
CSᵠ

10
@ CSᵠ Tôi không lo lắng. Khi anh ta là người chơi trung bình, anh ta tự dùng súng.
quintopia

14
Người chơi này ít có ý nghĩa hơn cô ấy có thể. Cô ấy có vẻ là trung bình hơn là có nghĩa.
Yakk

7
Hah .... đưa tôi một phút
Phục hồi Monica

5

Chống ngoại lệ

Chủ nghĩa xã hội cực đoan này tin rằng tất cả mọi người nên có sự thông minh như nhau. Anh ta cố gắng giết những người thông minh hơn hoặc ngu ngốc hơn anh ta. Anh ta xem xét cả hai nhưng anh ta nói chung là ngu ngốc. Anh ấy ủng hộ những người câm ngay từ đầu và cuối cùng thông minh, nhưng điều đó có trọng số dựa trên mức độ cực đoan của những người đó.

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;

    }

}

LƯU Ý: Theo Linus, điều này sẽ bỏ phiếu giống như bắn tỉa trong phần lớn thời gian (525602: 1228).


Bây giờ tôi sẽ giữ mức chạy hiện tại là 10 nghìn (để thử nghiệm nhanh hơn). Khi tôi thực hiện lần cuối cùng, tôi có thể sẽ làm cho nó lớn hơn.
Nathan Merrill

Tôi không cố gắng buộc tội bạn về bất cứ điều gì, nhưng điều này bầu chọn theo cách mà Sniper sẽ ~ 99,7% thời gian, về cơ bản nó sẽ là một xu lật như ai thắng, vì họ rất gần với cùng một chiến lược.
Linus

Bạn lấy số liệu thống kê đó từ đâu? Tôi thừa nhận nó có một chiến lược tương tự nhưng mục tiêu của tôi là cố gắng cải thiện một thứ đơn giản như của bạn bằng cách chọn bỏ phiếu cho những người rất thông minh nếu họ thông minh hơn tôi (hay tôi không có khả năng giành chiến thắng nồi nếu họ sống sót)
csga5000

1
Tôi đã cho lớp của bạn một static Sniper S = new Sniper()static long agrees=0, disagrees=0;. Trong phương thức bỏ phiếu của bạn, tôi thêm S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);tính toán cách một tay bắn tỉa sẽ bỏ phiếu ở vị trí của bạn, sau đó đưa câu trả lời của bạn vào một biến để tính xem nó có đồng ý hay không đồng ý trước khi trả lời câu trả lời. Khi trò chơi kết thúc, bạn có thể in đồng ý: disagress đó là 525602: 1228.
Linus

1
@Linus Điều đó có ý nghĩa, âm thanh hợp pháp. Tôi sẽ thêm một lưu ý về điều đó.
csga5000

5

Gián điệp

Gián điệp được bảo lưu. Anh ta không thích dùng súng cho những người thông minh nhất. Tương tự như vậy, anh không làm như chọn trên quartata idiots khả năng tự vệ. Vì vậy, anh ấy thích loại bỏ những người gần gũi nhất với anh ấy bằng sự thông minh.

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

Bạn vừa bị đánh đập, mes amis . Anh ta không quan tâm nếu anh ta thắng. Anh ta chỉ thích tiếng dao đâm vào lưng bạn khi anh ta bỏ phiếu cho bạn thành công.

Bạn vừa bị đánh đập.


4
Hình ảnh đó, mặc dù. +1
Addison Crump

Tôi nghĩ rằng điều này có một lỗi. Math.abs(enemyIntel - selfIntel) < closestIntelnên Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@MegaTom Tôi nghĩ bạn đúng. Tôi sẽ kiểm tra thêm về điều này khi tôi có sẵn Java. Cảm ơn vì đã bắt được!
Conor O'Brien

4

MedianPlayer

Người chơi này cố gắng trở thành người trung bình nhất (tốt, trung bình) một bên trái.

Nó bỏ phiếu để loại bỏ những đối thủ thông minh nhất và ngu ngốc nhất (với một chút thiên vị đối với việc bỏ phiếu thông minh nhất), tùy thuộc vào việc có nhiều hay ít thông minh hơn / ngu ngốc hơn chính họ.

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

khung bị đánh cắp trắng trợn từ @Linus ở trên.


Bạn đã làm cho IDE của tôi phàn nàn về mã trùng lặp!
Nathan Merrill

@NathanMerrill Sao chép tấn công mì ống! Lưu ý tôi đã thay đổi tên của lớp kể từ khi tôi đăng. Vì tôi cho rằng việc sao chép tên lớp của người khác để đảm bảo rằng bạn không thể chống lại họ sẽ trái với tinh thần của các quy tắc.
Yakk

2
Cảm ơn đã ngang nhiên ăn cắp công việc của tôi, hoặc ít nhất là thừa nhận.
Linus

2
@Linus Bạn được chào đón! Bắt chước là lời nịnh hót tốt nhất, tôi hy vọng.
Yakk

2
@ csga5000 ăn cắp trắng trợn là trò đùa của anh ấy, và tôi chỉ chơi cùng. Bất kỳ lập trình viên nửa có thẩm quyền nào (ví dụ như bản thân tôi) sẽ viết vòng lặp theo cùng một cách, vì vậy tất cả những gì anh ta thực sự làm là đánh cắp tên biến của tôi. Nếu tôi đã nghĩ đến bản quyền của họ, có lẽ tôi có thể tính tiền bản quyền; )
Linus

4

nhát gan

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;

  }
}

Chỉ không muốn bỏ phiếu, vì vậy, phiếu bầu cho đối thủ giống với người chơi đã bỏ phiếu vòng trước để tối đa hóa cơ hội được vào đội chiến thắng.

Không làm đặc biệt tốt ngay bây giờ, nhưng cũng có thể ném nó vào hỗn hợp.


Gần đây tôi đã sửa một lỗi trong đó độ thông minh là 0-8 thay vì 1-9. Điều này đã phá vỡ mã của bạn, vì vậy tôi đã sửa nó (bạn có thể tìm thấy mã được cập nhật trên kho lưu trữ): github.com/nathanmerrill/WeakestLink/blob/master/src/ Khăn
Nathan Merrill

4

Anh hùng

Bỏ phiếu những người yếu đuối ... hoặc làm phiền anh ta.

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

Gần đây tôi đã sửa một lỗi trong đó độ thông minh là 0-8 thay vì 1-9. Điều này đã phá vỡ mã của bạn, vì vậy tôi đã sửa nó (bạn có thể tìm thấy mã được cập nhật trên kho lưu trữ): github.com/nathanmerrill/WeakestLink/blob/master/src/ Khăn
Nathan Merrill

@NathanMerrill Cảm ơn bạn :)
TheNumberOne 6/12/2015

4

Bob

Bob chỉ là người bình thường nghĩ rằng anh ta thông minh hơn anh ta thực sự. Không thể chiến thắng gia đình bắn tỉa nhưng có được top 5 trong các mô phỏng của tôi hầu hết thời gian.

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

Chọn một mục tiêu ngẫu nhiên, sau đó bỏ phiếu cho chúng cho đến khi chúng biến mất. Không bỏ phiếu cho chính mình mặc dù.

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

Mã này cũng không hoạt động, nhưng là một sửa chữa dễ dàng. Việc làm của bạn thực sự không cần thiết, bởi vì tôi không cung cấp cho bạn sự thông minh của bạn khi tôi chuyển cho bạn các thành phần hiện tại của bạn. Mã cố định có thể được tìm thấy ở đây: github.com/nathanmerrill/WeakestLink/blob/master/src/ Kẻ
Nathan Merrill

@NathanMerrill Tôi đã chỉnh sửa mã đã sửa thành câu trả lời của mình để bất kỳ ai nhìn vào đây cũng thấy những gì thực sự đang được chạy
SnoringFrog

4

Số liệu thống kê

Đây không phải là một mục để tham gia cuộc thi. Đây chỉ là một cách để có được số liệu thống kê hữu ích của một trò chơi. Các thống kê này in ra khả năng phần trăm mà một người chơi cụ thể sẽ được bỏ phiếu trong một vòng.

Để thực hiện việc này, hãy thêm các dòng sau vào Round.javađể phần trên cùng của tệp trông như thế này:

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

...

Sau đó sửa đổi phương thức bỏ phiếu để trông như thế này:

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

Kết quả ví dụ:

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? Tôi khuyên bạn nên thay đổi nó để in "Đối với vòng 1", v.v.
Skyler

3

MaxPlayer

Một bí quyết Thích loại bỏ bất cứ ai có trí thông minh cao (do đó có thể thách thức trí tuệ chưa từng có của anh ta)

public class MaxPlayer extends Player{

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

3

Bảo vệ

Bỏ phiếu những người chọn kẻ mạnh ... hoặc những người làm phiền anh ta.

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

Gần đây tôi đã sửa một lỗi trong đó độ thông minh là 0-8 thay vì 1-9. Điều này đã phá vỡ mã của bạn, vì vậy tôi đã sửa nó (bạn có thể tìm thấy mã được cập nhật trên kho lưu trữ): github.com/nathanmerrill/WeakestLink/blob/master/src/ Khăn
Nathan Merrill

3

Đỉa

Dựa vào các bot khác để bầu chọn những kẻ thông minh và ngu ngốc nhất .. loại.

Anh ta hài lòng với việc bật lên ở đâu đó ở giữa và cuối cùng chia nồi với người chiến thắng (vì anh ta thực sự là một anh chàng bot thực sự đàng hoàng ).

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
Tôi thích. Tôi lo ngại nó sẽ không làm tốt mặc dù vì không nhiều người sẽ bỏ phiếu giống như bạn. Đó là một lỗ hổng với cuộc thi này đối với tôi, dường như các bot khác buộc bạn phải tuân theo một loại chiến lược nhất định.
csga5000

3
Dù vậy vẫn vui! Chiến thắng không phải là tất cả: ~)!
sweerpotato

3

Súng bắn tỉa

Một câu trả lời khác bị đánh cắp một cách đáng xấu hổ từ mã của Linus . Cái này trong sẽ giết tất cả lính bắn tỉa, không bảo vệ họ. Nếu nó biết rằng không còn lính bắn tỉa nào nữa, nó sẽ hoạt động giống như một tay bắn tỉa.

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
Tôi thích ý tưởng này, nhưng dường như có một văn hóa bầu chọn cho người chơi tối thiểu hoặc tối đa. bỏ phiếu cho người khác có thể sẽ bỏ phiếu của bạn đi . Có thể nếu bạn kiểm tra xem max có bị bắn tỉa hay không trước khi bỏ phiếu cho người khác, bạn sẽ bắt kịp một chút ... (tôi không thể kiểm tra, trên điện thoại)
Linus

2

Ngẫu nhiên

public class RandomPlayer extends Player{

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

2

MinPlayer

Một Elitist. Thích loại bỏ bất cứ ai có trí thông minh thấp.

public class MinPlayer extends Player {

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

2

Báo thù

Điều này bắt đầu như một thứ mà tôi nghĩ là ban đầu được gọi StupidBuffering(một cái tên mà tôi ghét phải từ bỏ), sau đó cuối cùng chỉ là một PrudentSniper, người không quan tâm nếu anh ta bị nhắm đến. Đây dường như cũng là lý do duy nhất anh ta không thể đánh bại PrudentSniper, vì vậy tôi đã điều chỉnh mọi thứ xung quanh một chút để làm cho anh ta tập trung.

Bây giờ, đây về cơ bản là một tay bắn tỉa, nhưng nếu bot thông minh nhất hoặc ngu ngốc nhất nhắm vào anh ta, anh ta sẽ nhắm mục tiêu bất cứ ai có nhiều phiếu bầu nhất vòng trước. Nếu cả hai đều có cùng số phiếu và cả hai đều nhắm vào anh ta, anh ta sẽ quay lại hành vi bắn tỉa bình thường. Trong các thử nghiệm của tôi, đôi khi thực tế đánh bại PrudentSniper.

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

Trung sĩ

MiddleMan cố gắng hết sức để tối đa hóa lợi nhuận trong khi vẫn cảnh giác rằng anh ta không bị cắt khỏi trò chơi. Anh ấy giữ các thí sinh ít hơn để cải thiện cơ hội lọt vào vòng tiếp theo (và để lại một kết thúc dễ dàng). Anh ta sẽ bỏ phiếu cho ai đó thông minh hơn anh ta nếu có nhiều thí sinh thông minh hơn so với những thí sinh kém hơn. Bất cứ ai trong hai nhóm, anh ta luôn bỏ phiếu cho nhóm thấp nhất trong nhóm để giữ cho nồi trèo.

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 hy vọng nó biên dịch, tôi không phải là một người Java.

Có kế hoạch này trong tâm trí trước khi đọc các mục khác. Sau đó, tôi đã rất ngạc nhiên khi Sniper gần (nhưng cực kỳ khác biệt) nên tôi đã tiếp tục và sử dụng nó như một điểm xuất phát kể từ khi tôi không biết cú pháp Java. Cảm ơn @Linus


1
Vui lòng kiểm tra mã của bạn. đừng cố viết câu trả lời bằng các ngôn ngữ bạn không biết
TanMath

@TanMath - Cảm ơn bạn đã đóng góp. Tôi có nhiều kinh nghiệm về các ngôn ngữ giống như C / Java, tuy nhiên không phải là Java cụ thể, vì vậy tôi khá tự tin rằng mã của tôi trên thực tế là chính xác và sẽ hoạt động. Điều đó đang được nói, nếu có lỗi trong đó và nó sẽ không chạy, tôi sẽ không bị xúc phạm nếu chủ trò chơi không đủ điều kiện nhập cảnh.
tbernard

Bạn đúng. Cảm ơn @Linus. Đã chỉnh sửa.
tbernard

1
@tbernard Tôi rất vui khi sửa lỗi, nhưng mã của bạn không có lỗi nào :)
Nathan Merrill

Ôi. Tôi đã không làm tốt như tôi hy vọng. Tôi dường như đã giúp bắn tỉa, vì vậy đó là điều tôi đoán haha.
tbernard

2

Xấp xỉ

Bot này đang cố gắng bắn khoảng các giá trị thông minh bị thiếu, giả sử rằng nhóm sẽ tiếp tục với cùng một mẫu, nghĩa là nó sẽ nhắm mục tiêu cùng loại mục tiêu. Nó luôn bầu chọn cho người chơi thông minh nhất trong hai người chơi khi có sự lựa chọn.

Lâu rồi tôi không sử dụng Java và hiện đang làm việc nên ... Không thể kiểm tra được, hy vọng nó không quá lỗi, vui lòng nhẹ nhàng :).

Nhân tiện, nó chỉ sử dụng awt.point vì tôi quá lười để thực hiện một 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;
    }

}

Vì vậy, đã có một số lỗi. :) Đầu tiên, thật không may, dàn diễn viên Integer [] không hoạt động, nó phải là một đối tượng [] cast (mà tôi không thích). Vì vậy, tôi đã gói tất cả vào một ArrayList thay vì một mảng. Thứ hai, dòng này: emptyPosition[emptyPosition.length]=j;sẽ luôn cung cấp cho bạn mảng ngoài giới hạn. Cuối cùng, không chắc tại sao, nhưng bạn sẽ bỏ phiếu cho những người chơi không vào vòng trong.
Nathan Merrill

Ồ, ngoài ra, khối ternary của bạn đã trả lại gấp đôi thay vì int và cực kỳ phức tạp, tôi đã biến nó thành một tiêu chuẩn nếu / khác. Bạn có thể tìm thấy tất cả các thay đổi của tôi trên Github: github.com/nathanmerrill/WeakestLink/blob/master/src/ mẹo
Nathan Merrill

@NathanMerrill Wow, cảm ơn rất nhiều. Đối với emptyPosition[emptyPosition.length], đó là một sai lầm ngớ ngẩn vì chiều dài luôn luôn là một so với chỉ số cuối cùng ^^. Cảm ơn những thay đổi, tôi sẽ sử dụng phiên bản mới này để sửa nó. Về khối ternary ... yeah, cảm thấy thích sử dụng nó, và có lẽ tôi đã quá quen với việc viết cho bản thân mình, không tiện đọc tôi đoán. Làm các sửa chữa và cập nhật nó.
Katenkyo

2

Bắn tỉa

Trước khi thêm PrudentSniper, tôi đã viết một bot để giúp Sniper đánh bại AntiExtremist và các gian lận khác (tôi sử dụng từ này với tình yêu). Bot, SniperAide, tìm kiếm những người chơi bỏ phiếu như lính bắn tỉa và bỏ phiếu vì họ nghĩ họ sẽ làm thế khi có sự đồng ý. Nếu tất cả người chơi trông giống như những tay súng bắn tỉa mà anh ta bầu cho tối đa, bảo vệ những xạ thủ thấp hơn (người cũng sẽ chuyển sang tối đa tại thời điểm này), ngay cả khi đó là chính anh ta.

:

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

Anh ta hiện không giúp được gì nhiều cho PrudentSniper.


Dựa trên mô tả và lý thuyết của bạn, tôi không thấy điều này sẽ giúp bất kỳ bot giống như bắn tỉa nào đánh bại bất kỳ tay súng bắn tỉa nào khác .. nếu có bất cứ điều gì nó sẽ không bảo vệ tất cả các tay súng bắn tỉa? Xin lỗi tôi không có nhiều thời gian hơn để đào sâu vào mã của bạn và thực sự hiểu nó cho chính tôi.
csga5000

@ csga5000, Vì bạn hiếm khi xác định Sniper bằng cách bỏ phiếu hồ sơ, nên nó bảo vệ tất cả chúng một chút. Nhưng khi có sự khác biệt rõ ràng, nó luôn hoạt động theo sở thích của Snipers, vì vậy nó chủ yếu là một loại máy bẻ khóa. Trọng tâm của chiến thắng là các trò chơi vĩ mô, không phải các vòng riêng lẻ, trong hầu hết các vòng, nó thực sự không thể làm gì hơn là duy trì tình huống lật đồng xu.
Linus

1

HighOrLowNotSelf

Loại bỏ ngẫu nhiên người chơi thông minh thấp nhất hoặc cao nhất (nhưng không tự).

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

Vì vậy, có một vài lỗi với trình này. Đầu tiên, Math.round () trả về a long, không phải int. Thứ hai, opskhông chứa đựng chính mình. (Nếu bạn muốn bỏ phiếu cho chính mình, bạn rõ ràng phải bao gồm nó). Cuối cùng, nếu / khác bạn bao gồm không phải là Java hợp lệ. Tôi đã sửa mã của bạn và thêm nó vào github
Nathan Merrill

1

Người vô chính phủ

Người vô chính phủ không thích chế độ.
Người vô chính phủ sẽ cố gắng giết tổng thống hiện tại.
Nếu người vô chính phủ là tổng thống, anh ta quyết định lạm dụng quyền lực của mình và giết những viên thuốc vô dụng. Trừ khi anh ta bị nhắm đến bởi một trong những người thấp kém của mình, vì họ nên đốt cháy thay thế.

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

Độc lậpVoter

Bot này biết rằng dân số nói chung luôn luôn sai! Vì vậy, nó bỏ phiếu cho bất cứ ai nhận được ít phiếu nhất.

Mã gần giống với "Bandwagon" của SolarAaron, nhưng logic cuối được lật.

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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.