당신은 가장 약한 링크입니다, 안녕


50

도전은 게임 쇼, 떨어져 기반으로 약한 고리 . 쇼에 익숙하지 않은 사람들을 위해, 이 도전의 핵심은 당신이 투표하는 사람을 다루는 것입니다 .

  • 다른 플레이어가 당신보다 똑똑하다면, 당신은 냄비를 얻을 가능성이 적습니다.
  • 다른 플레이어가 당신보다 더 어리 석다면, 당신은 얻을 수있는 냄비가 적습니다.

각 라운드 가 시작될 때 은 $ 0부터 시작합니다. 9 명의 플레이어 그룹이 구성되며, 각 플레이어는 1에서 9까지 의 고유 한 Smartness를 받습니다.

각 턴이 시작될 때마다 Pot += Smartness각 플레이어는 여전히 라운드에 있습니다. 그런 다음 플레이어는 제거하려는 플레이어에 투표합니다. 가장 많은 표를 얻은 플레이어가 제거됩니다. 동점 인 경우 더 똑똑한 선수가 유지됩니다.

라운드에 2 명의 플레이어 만 남았을 때, 그들은 재치의 전투에서 맞서게됩니다. 플레이어가 이길 확률은입니다 Smartness/(Smartness+OpponentSmartness). 승리 한 플레이어는 전체 냄비를받습니다.

게임이 끝날 때 가장 많은 돈을받은 플레이어가 승리합니다.

입출력

매 턴마다 현재 상대 목록을 받게됩니다. 당신은 당신의 현명 성과 플레이어 클래스의 라운드 비아 기능에 대한 모든 플레이어의 전체 투표 기록 에 액세스 할 수 있습니다 .

출력으로 투표하려는 플레이어를 나타내는 단일 정수를 반환해야합니다 (스마트 함을 나타냄). 자신을위한 투표 허용되지만 권장되지 않습니다.

9 라운드는 모든 플레이어가 최소 1000 10000 라운드를 플레이 할 때까지 반복 되며 모든 플레이어가 같은 라운드에서 플레이합니다.

https://github.com/nathanmerrill/WeakestLink 에서 컨트롤러를 찾을 수 있습니다.

플레이어를 만들려면 Player 클래스를 확장하고 PlayerFactory 클래스에 플레이어를 추가해야합니다. 수업은 다음 규칙을 따라야합니다.

  1. 다른 플레이어 (동일한 유형의 다른 플레이어 포함)와의 통신 또는 간섭은 엄격히 금지됩니다.

  2. 반사 및 정적 변수 (상수 제외)는 허용되지 않습니다.

  3. 임의성을 사용 getRandom()하려면 Player 클래스에서 함수를 제공했습니다 . 시뮬레이션을 결정적으로 사용할 수 있도록 사용하십시오.

데이터에 쉽게 액세스 할 수 있도록 Player 클래스에 많은 기능을 제공했습니다. Github에서 온라인 으로 찾을 수 있습니다 . 플레이어는 새로운 라운드마다 인스턴스화됩니다. "덤 / 자살"플레이어는 허용되지만 같은 전략을 가진 플레이어는 허용되지 않습니다.

점수

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
이것을 얻지 마라 : "각 라운드가 시작될 때 ... 9 명의 플레이어 그룹이 구성되고, 각 플레이어는 게임 시작의 시작이 아닌 고유 한 영리함을 받는다"?
CSᵠ

1
@ CSᵠ 맞습니다. 당신의 똑똑 함은 라운드에서 라운드로 바뀝니다 (그렇지 않으면 불공평 할 것입니다).
Nathan Merrill

2
스트레스와 기쁨이되어야합니다
CSᵠ

1
개미 빌드 구성 또는 이와 같은 것이 필요합니까? 나는 자바에 익숙하지 않으며 사람들이 일반적 으로이 같은 작은 프로젝트를 어떻게 설정하는지 잘 모르겠습니다.
데일 존슨

4
내에서 src\WeakestLink나는 javac Game\*.java Players\*.java Main.java컴파일하고 java -cp .. WeakestLink.Main실행했다.
Linus

답변:


22

저격병

일반적인 아이디어는 어리석은 선수 중 한 (즉, 우리가 페이스 오프에서 이길 가능성이 높은 선수 )을 유지 하여 포인트를 도용하는 것입니다. 그 후 우리는 다른 저 가치 플레이어를 제거하여 냄비를 올립니다. 그러나 우리가 똑똑한 플레이어를 만나면 우리의 어리석은 플레이어 가 제거 될 경우를 대비하여 가장 위험한 플레이어 를 제거하도록 선택합니다. 이런 식으로 우리가 도둑질 할 사람이 없다면 우리는 적어도 우리가 상대 할 기회를 얻어야합니다. 또한 우리는 항상 최소 또는 최대 선수와 투표하기 때문에, 나는 우리의 길을 얻는 데 상당히 효과적이라고 생각합니다.

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

12

신중한 저격수

스나이퍼 이지만 두 가지 특수한 동작이 있습니다. 하나는 3 개의 봇이 남아 있고 PrudentSniper가 가장 똑똑하면 가장 똑똑하지 않고 중간 봇에 투표합니다. 이것은 대결에서 몇 번 더 이길 수 있습니다. 다른 행동은 가장 똑똑한 봇이 마지막으로 투표 한 적이 있거나 가장 봇이 아닌 경우 가장 똑똑한 봇이 자기 방어에서 가장 똑똑한 투표를하는 것입니다.

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

두 가지 발전이 동등한 가치가 있는지 확실하지 않습니다. 각각 따로 사용해 보셨습니까?
Linus

나는 그랬고, 3 개의 봇 사례는 명백히 개선되었지만 (적어도 현재 리포 지엄에서 마스터에있는 봇에 대해서는), 징벌은 거의 중립적입니다. 나는 암살자에 대한 예방책으로 막연한 막힘을 막아 버렸다.
histocrat


나는 최근 smartness가 1-9 대신 0-8 인 버그를 수정했습니다. 이것은 코드를 손상 시켰으므로
Nathan Merrill

12

컬트

컬트 플레이어는 투표 기록 만 사용하여 서로를 식별하고 그룹으로 투표하려고하는 약간 난해한 투표 체계를 가지고 있습니다. 컬트의 각 구성원은 투표 방법을 알고 있기 때문에 다르게 투표하는 사람은 모두 비회원으로 표시되어 결국 제거 대상이됩니다.

한눈에 투표 구성표 :

  • 가장 약한 참가자에 대한 첫 번째 투표에서 최소 및 저격수와 협력하여 컬트 파워를 얻는 데 도움
  • 이후 차례에 컬트 만 남을 때까지 알려진 비회원 투표 (우리가 통제하고 있다고 생각하는 한 최저 가치 비회원 투표).
  • 회원 만 남았을 때, 가치가 낮은 회원에게 투표하십시오 (실제로 컬트의 이익을 위해 자신을 희생).

코드:

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

마지막 생각들:

컬트는 이제 페이스 오프에 남은 컬트 멤버가 2 명 이하일 때 가장 위험한 플레이어에게 투표로 전환합니다. 나는 그것을 여러 번 테스트 cult_cnt>1cult_cnt>2조건과 이후 승리를 더 자주.

그럼에도 불구하고 이것은 예방책이며 컬트는 실제로 고독한 플레이어로 작동하도록 설계되지 않았으므로 새로운 플레이어의 수가 증가함에 따라 컬트는 여전히 잃을 것입니다.


가장 똑똑한 비회원을 먼저 투표하는 것이 낫지 않습니까?
agweber

임의 변수가 정적 이도록 (그리고 Game.random을 통해 액세스 할 수 있도록) 컨트롤러 코드를 업데이트했습니다. 또한 github에서 코드를 업데이트 할 자유를 얻었습니다 : github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

1
@NathanMerrill 감사합니다.하지만 컬트가 관심있는 투표에 참여한 알 수없는 비회원들에게 컬트가 더 관 대해 지도록하면 더 나은 결과를 얻는 것 같습니다.
Linus

@agweber, 제안 해 주셔서 감사합니다. 이것은 아마도 컬트를 더 나은 단독 플레이어로 만들지 만 숫자가있는 한 냄비를 뛰어 올리려고 시도해야합니다. 내 새 버전이 세계 최고라고 생각합니다.
Linus

2
TheCult가 요청 나를 입찰 unusedPlayers.addAll(allPlayers);... 모든 플레이어 (함께 카드의 여러 데크를 셔플 같은) 다양한 다양성에서 발생할 수 있도록 Game.java에 아홉 번 주위를 복제 할 수 없음은 물론, 그 완전히 바이어스 요청입니다하지 않습니다 하지만, 그들이 팀을 구성 할 가능성이 적더라도 팀 기반 전략이 얼마나 강력한 지 알면 흥미 롭습니다.
Linus

7

브리지 버너

내가 지금 이것을 테스트 할 수있는 곳이 아니며, 이것이 실제로 못생긴 코드처럼 느껴지지만 작동 해야 합니다.

이 봇은 미움을 원합니다. 가장 적은 표를 얻은 사람에게 투표합니다 . 동점 인 경우, 투표하지 않고 가장 오래 간 사람을 뽑습니다. 다른 동점 인 경우, 가장 똑똑한 사람을 선택합니다 (아마도 최악의 적을 만들 것이므로). 주위에 없을 때 아무도 그것을 싫어하지 않기 때문에 자체 투표하지 않습니다.

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

이 봇을 작동시킬 수 없었습니다. 몇 가지 버그를 수정했으며 현재 존재하지 않는 플레이어에게 투표하고 있습니다. "last_round_voted"가 정의되어 있지 않다는 것이 확실하지 않은 변경 사항은 "last_voted_against"로 변경했습니다. 여기에서 내 변경 사항을 찾을 수 있습니다 : github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill이 코드는 생각보다 훨씬 나빴습니다. 이제 테스트 할 수 있으므로 두 버전을 모두 살펴보고이 작업을 시도해 보겠습니다.
SnoringFrog

@NathanMerrill 몇 가지 문제를 발견했습니다. 즉, 봇에 투표 한 적이없는 선수에 대해서는 항상 투표를 시도한 이유를 무시하지 않았습니다. 또한 잘못된 목록을 사용하여 한 시점에서 색인을 가져 와서 플레이어 -1가 투표했습니다. 그러나 지금 수정해야합니다.
SnoringFrog

1
글쎄, 작동하지만 끔찍합니다. 무작위 플레이어를 때리는 것을 축하합니다!
Nathan Merrill

1
@NathanMerrill 무작위로 선수를 구타에 때때로
SnoringFrog

6

밴드와 곤

그가 목표로 정한 사람이 아닌 한, 투표에서 군중을 따릅니다.

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

나는 이것이 저격수를 따라 가면 강해지지만 컬트와 저격수의 목표를 약간 효과적으로 피할 수 있다고 생각합니다. 스나이퍼 킬러를위한 미트 실드 일 수도 있고, 더 많은 것이 있다면 그들을 도울 수도 있습니다. (최신 업데이트로 테스트해야합니다).

게임을 실행하려면 Java 8 기능을 사용해야합니다.


1
잘 작성된 코드를 보는 것이 좋습니다 :)
Nathan Merrill

6

복수 선수

이 봇은 그에게 가장 많이 투표 한 사람에게 순위를 매 깁니다. 이론은 과거에 당신을 위해 투표 한 선수가 당신을 위해 다시 투표 할 가능성이 있다는 것입니다.

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

나는 최근 smartness가 1-9 대신 0-8 인 버그를 수정했습니다. 이것은 코드를 손상 시켰으므로
Nathan Merrill

@NathanMerrill 내 코드에 대한 수정 사항에는 작은 버그가 있습니다. 더 나은 코드로 편집했습니다.
MegaTom

5

MeanPlayer

어리 석고 똑똑한 선수는 투표하지 말고 총을 들고있다

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

이 선수가 왜 나머지 / sarc보다 의미가 없는지 이해가되지 않습니다
Nathan Merrill

@NathanMerrill을 조심하십시오, 그는 총을 가지고 있습니다! 내가 너라면 내 말을 신중하게 고르겠다 ...
CSᵠ

10
@ CSᵠ 걱정하지 않습니다. 그는 평범한 선수 일 때 총을 사용합니다.
quintopia

14
이 선수는 그녀가 할 수있는 것보다 덜 의미가 있습니다. 그녀는 평균보다 더 중간 인 것으로 보인다.
Yakk

7
하 .... 잠시만
기다려

5

극단 주의자

이 극단적 인 사회주의자는 모든 사람들이 평등해야한다고 믿는다. 그는 자신보다 훨씬 똑똑하거나 어리석은 사람들을 죽이려고합니다. 그는 둘 다 고려하지만 일반적으로 바보를 선호합니다. 그는 처음에는 바보 같은 사람들을 선호하고 결국은 똑똑하지만 사람들이 얼마나 극단인지에 따라 가중치를 부여합니다.

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;

    }

}

참고 : Linus에 따르면 이것은 대다수의 저격수와 같은 투표를 할 것입니다 (525602 : 1228).


지금은 빠른 실행을 위해 현재 실행을 10K로 유지하겠습니다. 마지막 통과시 더 크게 만들 것입니다.
Nathan Merrill

나는 당신에게 아무것도 비난하지 않으려 고 노력하지만, 이것은 저격자가 ~ 99.7 %의 시간과 같은 방식으로 투표합니다. 그들은 같은 전략에 너무 가까워서 누가 이겼는지에 대한 동전 던지기가 될 것입니다.
Linus

그 통계를 어디서 얻었습니까? 나는 반 유사 전략을 가지고 있음을 인정하지만 내 목표는 나보다 훨씬 똑똑한 사람들에게 투표하도록 선택함으로써 당신만큼 간단한 것을 개선하려고 노력하는 것이 었습니다 (일명 나는 승리하지 않을 것입니다) 냄비가 살아남을 경우)
csga5000

1
나는 당신의 클래스 A를했다 static Sniper S = new Sniper()하고 static long agrees=0, disagrees=0;. 귀하의 투표 방법 S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);에서 저격수가 귀하의 입장에서 투표하는 방법을 계산 한 다음 답변을 반환하기 전에 합의 여부에 따라 답변을 변수에 넣습니다. 게임이 끝나면 동의 : 인쇄 : 525602 : 1228 인 동의.
Linus

1
@Linus 합리적으로 들리 네요. 그것에 대한 메모를 추가하겠습니다.
csga5000

5

스파이

스파이는 예약되어 있습니다. 그는 똑똑한 사람들을 위해 총을 좋아하지 않습니다. 마찬가지로, 그는 쿼타 타 무방비 바보를 고르는 것을 좋아하지 않습니다 . 그래서 그는 가장 똑똑한 사람들을 제거하는 것을 좋아합니다.

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

당신은 방금 뒤죽박죽되었습니다, mes amis . 그는 이기면 상관하지 않습니다. 그는 당신을 성공적으로 투표로 당신의 등에서 칼 소리를 좋아합니다.

방금 쫓겨났습니다.


4
그래도 그 이미지. +1
Addison Crump

나는 이것이 버그가 있다고 생각합니다. Math.abs(enemyIntel - selfIntel) < closestIntel이어야합니다 Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel).
MegaTom

@MegaTom 당신이 옳다고 생각합니다. Java를 사용할 수있을 때이 내용을 추가로 확인하겠습니다. 캐치에 감사드립니다!
Conor O'Brien

4

MedianPlayer

이 플레이어는 가장 사소한 (잘, 중간) 사람이 되려고 노력합니다.

그것은 그들보다 더 똑똑하거나 멍청한 것이 있는지 여부에 따라 가장 똑똑하고 가장 멍청한 적을 제거하기 위해 투표합니다 (가장 똑똑한 투표에 약간의 편견이 있음).

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

위의 @Linus에서 훔친 프레임 워크.


IDE가 중복 코드에 대해 불평하게 만들었습니다!
Nathan Merrill

@NathanMerrill 복사 파스타 공격! 참고 게시 한 이후 수업 이름이 변경되었습니다. 내가 다른 사람의 학급 이름을 복제하여 규칙에 어긋나는 것을 방지한다고 가정 할 때 규칙의 정신에 위배됩니다.
Yakk

2
나의 작품을 훔치거나 최소한 인정하는 것에 감사드립니다.
Linus

2
@Linus 천만에요! 모방이 가장 아첨입니다.
Yakk

2
@ csga5000은 뻔뻔스럽게 그의 농담을 훔쳤 으며, 나는 단지 함께 놀았습니다. 반 유능한 코더 (예 : 나 자신)는 루프를 같은 방식으로 작성하므로 실제로 내 변수 이름을 훔치기 만했습니다. 내가 저작권을 가지고 있다고 생각했다면 로열티를 청구 할 수도있다. )
Linus

4

겁쟁이

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;

  }
}

투표하기를 원하지 않기 때문에 마지막 라운드에서 투표 한 선수와 가장 유사한 상대에게 투표하면 승리 팀에 올 확률이 극대화됩니다.

지금은 특히 잘하지 않지만 믹스에 넣을 수도 있습니다.


나는 최근 smartness가 1-9 대신 0-8 인 버그를 수정했습니다. 이것은 코드를 손상 시켰으므로
Nathan Merrill

4

영웅

약한 사람을 선택하거나 귀찮게하는 사람들에게 투표하십시오.

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

나는 최근 smartness가 1-9 대신 0-8 인 버그를 수정했습니다. 이것은 코드를 손상 시켰으므로
Nathan Merrill

@NathanMerrill 감사합니다 :)
TheNumberOne

4

단발

밥은 자신이 똑똑하다고 생각하는 평범한 사람입니다. 저격수 가족을 이길 수는 없지만 대부분의 시뮬레이션에서 5 위를 차지했습니다.

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

무작위 대상을 선택한 다음 사라질 때까지 투표합니다. 그래도 자신에게 투표하지 않습니다.

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

이 코드는 작동하지 않았지만 쉽게 해결되었습니다. 당신의 현행 상대를 통과 할 때 당신의 현명함을주지 않기 때문에 당신의 do-while은 실제로 필요하지 않습니다. 고정 코드는 여기에서 찾을 수 있습니다 : github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill 수정 된 코드를 내 답변으로 편집하여 여기를 보는 사람이 실제로 실행중인 것을 볼 수 있습니다.
SnoringFrog

4

통계

컨테스트에 참가할 수 없습니다. 이것은 단지 게임의 유용한 통계를 얻는 방법입니다. 이 통계는 특정 선수가 한 라운드에서 투표 할 확률을 나타냅니다.

이렇게하려면 Round.java파일 맨 위에 다음과 같이 표시 되도록 다음 줄을 추가하십시오 .

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

...

그런 다음 투표 방법을 다음과 같이 수정하십시오.

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

출력 예 :

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 일? 나는 "라운드 1"등을 인쇄하도록 변경하는 것이 좋습니다.
Skyler

3

MaxPlayer

모든 것을 알고 있습니다. 지능이 높은 사람을 제거하는 것을 선호합니다 (따라서 자신의 탁월한 지성에 도전 할 수있는 사람)

public class MaxPlayer extends Player{

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

3

가드

강한 것을 선택하는 사람들이나 그를 귀찮게하는 사람들에게 투표하십시오.

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

나는 최근 smartness가 1-9 대신 0-8 인 버그를 수정했습니다. 이것은 코드를 손상 시켰으므로
Nathan Merrill

3

거머리

가장 똑똑하고 멍청한 사람들에게 투표하기 위해 다른 봇에 의존합니다.

그는 중간에 어딘가에 올라 서서 승자와 냄비를 나누는 것에 만족합니다 (실제로 정말 괜찮은 녀석 이기 때문에 ).

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
나는 좋아한다. 많은 사람들이 당신과 같은 투표를하지 않기 때문에 나는 그것이 좋지 않을 것이라고 걱정합니다. 이 경쟁의 한 가지 단점은 다른 봇이 특정 유형의 전략을 준수하도록 강요하는 것 같습니다.
csga5000

3
그래도 재미있다! 승리는 전부가 아닙니다 : ~)!
sweerpotato

3

스나이퍼 킬러

또 다른 답변은 Linus의 코드 에서 부끄럽게 도난당했습니다 . 이 중 하나는 모든 저격수를 죽일 것입니다. 스나이퍼가 없다는 것을 알고 있다면 스나이퍼 자체처럼 행동 할 것입니다.

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
나는 그 아이디어가 마음에 들지만 최소 또는 최대 선수 투표 문화가있는 것 같습니다. 다른 사람을 위해 투표하면 투표가 취소 될 수 있습니다 . 어쩌면 다른 사람을 위해 투표하기 전에 최대치가 도둑 맞았는지 확인하면 조금 따라 잡을 수 있습니다 ... (전화로 확인할 수 없음)
Linus

2

랜덤 플레이어

public class RandomPlayer extends Player{

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

2

MinPlayer

엘리트 지능이 낮은 사람을 제거하는 것이 좋습니다.

public class MinPlayer extends Player {

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

2

복수

이것은 내가 원래라고 생각했던 것 (내가 StupidBuffering포기하기 싫어하는 이름)으로 시작한 다음, 그가 목표로 삼고 있는지 걱정하지 않는 PrudentSniper였습니다. 이것이 그가 PrudentSniper를 이길 수없는 유일한 이유 인 것 같았으므로, 나는 그의 초점을 맞추기 위해 사물을 약간 조정했습니다.

이제 이것은 기본적으로 저격수이지만 가장 똑똑하거나 가장 멍청한 봇이 그를 목표로 삼 으면 마지막 라운드에서 가장 많은 표를 얻은 사람을 목표로 삼습니다. 둘 다 같은 수의 표를 얻었고 그를 표적으로 삼았다면 그는 정상적인 저격수 행동으로 돌아갑니다. 내 테스트 에서이 실제 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

중개자

MiddleMan은 수익을 극대화하기 위해 최선을 다하면서 게임에서 잘리지 않는다는주의를 기울입니다. 그는 다음 라운드로 진출 할 가능성을 높이기 위해 더 적은 참가자를 유지합니다. 그는 적은 참가자보다 똑똑한 참가자가있는 경우에만 자신보다 똑똑한 사람에게 투표합니다. 두 그룹 중 어느 쪽이든, 그는 항상 포트 클라이밍을 유지하기 위해 가장 낮은 그룹에 투표합니다.

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

추신 : 나는 자바 사람이 아니라고 컴파일하기를 바랍니다.

다른 항목을 읽기 전에이 계획을 염두에 두어야합니다. 그런 다음 스나이퍼 가 얼마나 가까운 지 놀랐습니다. 그래서 Java 구문을 알지 못했기 때문에 스나이퍼 가 그 점을 뛰어 넘었습니다. 감사합니다 @Linus


1
코드를 테스트하십시오. 모르는 언어로 답을 쓰려고하지 마십시오
TanMath

@TanMath-입력 해 주셔서 감사합니다. C / Java와 같은 언어에서 많은 경험을 가지고 있지만 Java는 구체적이지 않으므로 코드가 실제로 정확하고 작동 할 것이라고 확신합니다. 즉, 오류가 있고 실행되지 않으면 게임 마스터가 참가 자격을 박탈하더라도 기분이 상하지 않습니다.
tbernard

네가 옳아. 감사합니다 @Linus. 편집했습니다.
tbernard

1
@tbernard 버그를 고치게되어 기쁘지만, 코드에는 아무것도 없었습니다 :)
Nathan Merrill

아야. 내가 바랐던 것처럼 잘하지 않았다. 나는 저격수를 도와주는 것처럼 보였으므로 하하라고 생각합니다.
tbernard

2

대략적인 위치

이 봇은 그룹이 동일한 패턴을 계속 유지한다고 가정 할 때 누락 된 smartness 값을 중심으로 대략적으로 촬영하려고 시도합니다. 즉, 동일한 유형의 대상을 대상으로한다는 의미입니다. 선택이있을 때 항상 두 선수 중 가장 똑똑한 투표를합니다.

오랫동안 Java를 사용하지 않았고 현재 직장에서 그렇게하고 있습니다 ... 테스트 할 수 없으며, 버그가 많지 않기를 바랍니다. 부드럽게하십시오 :).

그건 그렇고, 튜플 n_n을 구현하기에는 너무 게으 르기 때문에 awt.Point 만 사용합니다.

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

}

그래서 몇 가지 버그가있었습니다. :) 불행히도 Integer [] 캐스트는 작동하지 않습니다. Object [] 캐스트 여야합니다. 그래서 배열 대신 ArrayList에 모두 래핑했습니다. 둘째,이 줄 : emptyPosition[emptyPosition.length]=j;항상 범위를 벗어난 배열을 제공합니다. 마지막으로, 왜 그런지 확실하지 않지만, 당신은 라운드에없는 선수들에게 투표를합니다.
Nathan Merrill

또한, 삼항 블록이 int 대신 double을 반환하고 초 복잡 해져서 if / else 표준으로 바꿨습니다. Github에서 모든 변경 사항을 찾을 수 있습니다 : github.com/nathanmerrill/WeakestLink/blob/master/src/…
Nathan Merrill

@NathanMerrill 와우, 고마워. 의 경우 emptyPosition[emptyPosition.length]길이가 항상 마지막 인덱스보다 하나이므로 엉뚱한 실수입니다 ^^. 변경 사항에 감사드립니다.이 새 버전을 사용하여 수정하겠습니다. 삼항 블록에 관해서는 ... 예, 그것을 사용하는 것처럼 느껴졌고 어쩌면 나 자신을 위해 쓰는 데 너무 익숙했을 것 같았습니다. 읽기가 쉽지 않았습니다. 수정 및 업데이트
Katenkyo

2

스나이퍼

PrudentSniper를 추가하기 전에 저는 스나이퍼AntiExtremist 및 기타 사기를 물리 치는 데 도움이되는 봇을 작성했습니다 (나는 사랑으로 단어를 사용합니다). 봇 스나이퍼 에이드 (SniperAide)는 스나이퍼처럼 투표하고 합의가있을 때 생각하는대로 투표하는 플레이어를 찾습니다. 모든 플레이어가 저격수처럼 보인다면, 자신이 있더라도 낮은 스나이퍼 (이 시점에서 최대로 전환 할 것임)를 보호하여 최대 값에 투표합니다.

코드 :

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

그는 현재 PrudentSniper에 대해 많은 도움을주지 않습니다.


귀하의 설명과 이론에 따르면, 저격병과 같은 봇이 다른 저격수를 이길 수있는 방법을 모르겠습니다. 죄송합니다. 코드를 파헤쳐 서 직접 이해해야 할 시간이 없습니다.
csga5000

@ csga5000, 투표 기록으로 스나이퍼를 거의 식별하지 못할 수 있으므로 지금은 조금씩 보호합니다. 그러나 차이가 분명 할 때는 스나이퍼의 관심사에 항상 영향을 미치므로 대부분 일종의 타이 브레이커입니다. 승리에 초점을 맞추는 것은 개별 라운드가 아닌 거시적 게임입니다. 대부분의 라운드에서 코인 플립 상황을 유지하는 것 이상으로 아무것도 할 수 없습니다.
Linus

1

높음 낮음

무작위로 가장 낮거나 가장 높은 지능 플레이어를 제거합니다 (자체는 아님).

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

따라서이 제출에는 몇 가지 버그가 있습니다. 먼저 Math.round ()는 longnot이 아닌을 반환합니다 int. 둘째, ops자신을 포함하지 않습니다. (자신을 위해 투표하려면 명시 적으로 포함시켜야합니다). 마지막으로 포함시킨 if / else가 유효한 Java가 아닙니다. 코드를 수정하고 github에
Nathan Merrill

1

무정부주의자

무정부주의자는 정권을 좋아하지 않습니다.
아나키스트는 현 대통령을 죽이려 할 것이다.
무정부주의자가 대통령이라면, 그는 자신의 힘을 남용하고 쓸모없는 농약을 죽이기로 결정합니다. 그가 열등한 사람 중 한 사람을 목표로하지 않는 한, 그들은 대신 태워야하기 때문입니다.

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

독립적 인 투표자

이 봇은 일반 인구가 항상 틀렸다는 것을 알고 있습니다! 따라서 가장 적은 표를 얻은 사람에게 투표합니다.

코드는 SolarAaron의 "Bandwagon"과 거의 동일하지만 최종 논리는 바뀌 었습니다.

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;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.