你是最弱的一环,再见


50

这个的挑战是基于关闭的游戏节目,最薄弱的环节。对于那些不熟悉该节目的人,此挑战的症结在于您要投票否决谁

  • 如果其他玩家比您聪明,那么您获得底池的机会就更少。
  • 如果其他玩家比您还笨,那么您所拥有的底池就更少了。

在每个回合开始时,底从$ 0开始。组成一个由9个玩家组成的组,每个玩家都被赋予1到9之间的唯一智慧

在每个回合开始时,每个Pot += Smartness仍在回合中的玩家。然后,玩家对希望删除的玩家进行投票。得票最多的玩家将被删除。如果出现平局,则保留更聪明的玩家。

当本轮只剩下2位玩家时,他们将在智慧之战中对峙。玩家获胜的机会是Smartness/(Smartness+OpponentSmartness)。然后获胜的玩家将收到整个彩池。

在游戏结束时获得最多钱的玩家将获胜。

输入输出

每回合,您将收到当前的对手列表。您可以通过Player类中的功能访问自己的聪明才智和所有玩家的整个投票历史记录

作为输出,您必须返回一个整数,代表您希望投票的球员(代表他们的聪明才智)。投票为自己允许(但不推荐)。

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ᵠ是正确的。您的聪明才智不断变化(否则是不公平的)。
弥敦道·美林

2
一定是压力和喜悦
CS15 2015年

1
我应该期待一个ant build config或类似的东西吗?我是Java的新手,我不确定人们通常如何设置像这样的小项目。
戴尔·约翰逊

4
从内部src\WeakestLink我曾经javac Game\*.java Players\*.java Main.java编译并java -cp .. WeakestLink.Main运行过。
莱纳斯(Linus)2015年

Answers:


22

狙击手

一般的想法是让一名愚蠢的球员(即我们更可能在面对面击败的球员)中sn取得分。之后,我们尝试移除其他低价值玩家来提高底池。但是,当我们接触聪明的玩家时,我们会选择移除最危险的玩家,以防我们的愚蠢玩家被移除。这样,如果我们没有人要ipe,我们应该找一个至少有机会与之抗衡的人。另外,由于我们总是与最小或最大玩家一起投票,所以我希望我们在自己的方式上相当有效。

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)2015年

12

谨慎狙击手

狙击手,但有两种特殊情况的行为。一种是,如果剩下三个机器人,而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

我做到了,尽管这三个机器人程序的确是一个明确的改进(至少是针对目前在回购市场上处于主导地位的机器人),但净收益却是中立的。我把它留作一种含糊的威慑力,以防刺客。
histocrat


我最近修复了一个错误,该错误的智能度是0-8,而不是1-9。这破坏了您的代码,所以我进行了修复(您可以在存储库中找到更新的代码):github.com/nathanmerrill/WeakestLink/blob/master/src/…–
Nathan Merrill

12

邪教

邪教玩家有一个温和深奥的投票方案,通过该方案,他们尝试仅使用投票记录来相互识别并分组投票。由于邪教的每个成员都知道如何投票,因此投票方式不同的任何人都会被显示为非成员,并最终成为消除目标。

投票方案一目了然:

  • 在第一轮投票中选出最弱的参赛者,与min&sniper合作有助于邪教获得力量
  • 在随后的回合中,将已知的非成员投票出去直到只有邪教仍然存在为止(只要我们认为自己处于控制之中,我们就将最低价值的非成员投票以提高分数)。
  • 当仅剩下成员时,投票选出低价值成员以换取积分(实际上是为了崇拜自己而牺牲自己)。

编码:

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

最后的想法:

当只剩下两个或更少的邪教成员进行对峙时,邪教现在转而投票给最危险的玩家。我在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中要求重复大约9次,以便所有玩家可以以多种多样的方式出现(例如将多副纸牌混在一起)... 当然,这不是完全有偏见的请求,但有趣的是,即使他们只有很小的机会被放在一起,基于团队的策略仍然有多么强大。
莱纳斯(Linus)2015年

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 2015年

@NathanMerrill发现了几个问题。也就是说,我没有忽略那些未被发现从未投票支持该机器人的玩家,这就是为什么它总是试图为其投票的原因。还使用错误的列表从某一点获取索引,从而导致玩家-1被投票。但现在应该修复。
SnoringFrog 2015年

1
好吧,它有效,但确实很糟糕。恭喜击败随机玩家!
弥敦道·美林

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

我最近修复了一个错误,该错误的智能度是0-8,而不是1-9。这破坏了您的代码,因此我进行了修复(您可以在存储库中找到更新的代码):github.com/nathanmerrill/WeakestLink/blob/master/src/…–
Nathan Merrill

@NathanMerrill您对我的代码的修复有一个小错误。我编辑了代码以使其更好。
MegaTom 2015年

5

MeanPlayer

不投票给最愚蠢或最聪明的球员,他却拿着枪​​(把枪past过安全区)

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

我不明白为什么这个球员是任何比其他人/红新月会更猛烈
弥敦道美林

当心@NathanMerrill,他有枪!我会认真选择我的话,如果我是你...
CSᵠ

10
@CSᵠ我不担心。当他是普通玩家时,他会用枪on自己。
quintopia

14
这个球员没有她的卑鄙。她似乎比平均水平更高。
Yakk 2015年

7
哈....花了我一分钟
恢复莫妮卡2015年

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(以便进行更快的测试)。当我完成最后的遍历时,我可能会加大它。
弥敦道·美林

我并不是要指责您任何事情,但这是以狙击手在大约99.7%的时间中的投票方式进行的,基本上,这将是谁获胜的一次掷硬币,因为他们是如此接近相同的策略。
莱纳斯(Linus)2015年

您从何处获得该统计信息?我承认它有一个半类似的策略,但我的目标是尝试通过选择比自己聪明得多的非常聪明的人投票来改善像您这样简单的事情(也就是我不太可能赢得锅,如果他们生存下去的话)
csga5000

1
我给你的班static Sniper S = new Sniper()和一个static long agrees=0, disagrees=0;。在您的投票方法中,我添加了S.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);一种计算方式,该功能可以计算狙击手将如何投票表决您的位置,然后将您的答案放入变量中,以计算其同意还是不同意,然后再返回答案。游戏结束后,您可以打印同意书:disagress,为525602:1228。
莱纳斯(Linus)2015年

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

艾米斯·阿米斯,你刚刚被刺了。他不在乎是否获胜。他就像您成功投赞成票一样,喜欢您背后的刀音。

您刚刚被刺伤了。


4
那个形象,不过。+1
艾迪生·克伦普

我认为这有一个错误。Math.abs(enemyIntel - selfIntel) < closestIntel应该是Math.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel)
MegaTom 2015年

@MegaTom我认为你是对的。当我有Java可用时,我将进一步检查。感谢您可能的收获!
Conor O'Brien 2015年

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抱怨重复的代码!
弥敦道·美林

@NathanMerrill复制粘贴攻击!注意自发布以来,我更改了班级的名称。我想复制别人的班级名称来确保您不会与他们相反,这违反了规则的精神。
Yakk 2015年

2
感谢您公然偷走我的作品,或者至少承认了。
莱纳斯(Linus)2015年

2
@Linus不客气!我希望模仿是最好的奉承。
Yakk 2015年

2
@ csga5000 公然偷了他的玩笑,而我只是在玩。任何半胜任的编码器(例如我自己)都将以相同的方式编写循环,因此他真正要做的就是窃取我的变量名。如果我考虑过版权,也许我可以收取版税; )
Linus 2015年

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;

  }
}

只是不想被选票,所以为对手争取的票数与上轮被选票的球员最相似,以便最大程度地赢得获胜球队的机会。

目前效果不佳,但最好将其混入。


我最近修复了一个错误,该错误的智能度是0-8,而不是1-9。这破坏了您的代码,所以我进行了修复(您可以在存储库中找到更新的代码):github.com/nathanmerrill/WeakestLink/blob/master/src/…–
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;
    }
}

我最近修复了一个错误,该错误的智能度是0-8,而不是1-9。这破坏了您的代码,所以我进行了修复(您可以在存储库中找到更新的代码):github.com/nathanmerrill/WeakestLink/blob/master/src/…–
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

固定播放器

选择一个随机目标,然后投票给他们直到消失。不过不会投票给自己。

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

这段代码也不起作用,但是很容易解决。实际上,您不需要做任何事情,因为当您通过您当前的对手时,我不会给您您的聪明。固定的代码可以在这里找到:github.com/nathanmerrill/WeakestLink/blob/master/src/...
弥敦道美林

@NathanMerrill我将更正后的代码编辑到我的答案中,因此任何在此处查看内容的人都可以看到正在运行的内容
SnoringFrog 2015年

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轮”等
斯凯勒

3

最大播放器

万事通。倾向于删除具有高智能的任何人(因此可以挑战他无与伦比的智力)

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

我最近修复了一个错误,该错误的智能度是0-8,而不是1-9。这破坏了您的代码,所以我进行了修复(您可以在存储库中找到更新的代码):github.com/nathanmerrill/WeakestLink/blob/master/src/…–
Nathan Merrill

3

水蛭

依靠其他机器人投票选出最聪明和最笨的家伙。

他很满意在中间的某个位置转动起来并最终赢家分裂锅(因为他其实是一个很不错的家伙 BOT)。

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 2015年

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

PS希望它可以编译,但我不是Java专家。

在阅读其他条目之前,请牢记此方案。然后,我惊讶地发现Sniper如此接近(但与众不同),因为我不了解Java语法,所以我将它用作起点。谢谢@Linus


1
请测试您的代码。不要尝试用您不知道的语言写答案
TanMath 2015年

@TanMath-感谢您的输入。我在类似C / Java的语言方面有很多经验,但是没有专门针对Java的经验,因此我非常有信心自己的代码是正确的并且可以正常工作。话虽这么说,但是如果有错误并且无法运行,那么如果游戏大师取消了参赛资格,我将不会受到冒犯。
tbernard

你是对的。谢谢@Linus。编辑。
tbernard

1
@tbernard我很乐意修复错误,但您的代码没有任何:)
Nathan Merrill

哎哟。表现不理想。我似乎确实帮助了狙击手,所以我猜这就是哈哈。
tbernard

2

近似位置

假设该小组将以相同的模式继续进行,这意味着该机器人将以相同类型的目标为目标,并试图围绕丢失的智能度值进行射击。在有选择的情况下,它总是投票选出最聪明的两个玩家。

很长一段时间我没有使用Java,目前正在工作中……无法测试它,希望它不会过于马车,请保持谦虚:)。

顺便说一句,它使用awt.Point只是因为我懒于实现元组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;
    }

}

因此,存在一些错误。:)首先,不幸的是,Integer []强制转换不起作用,它必须是Object []强制转换(我不喜欢)。所以我将它们全部包装到ArrayList而不是数组中。其次,这行代码:emptyPosition[emptyPosition.length]=j;将始终为您提供数组的边界。最后,不确定为什么,但是您会投票淘汰不在该轮中的玩家。
内森·梅里尔

哦,同样,您的三元程序块返回的是double而不是int,并且超级复杂,我将其转换为标准的if / else。您可以在Github上找到我所有的更改:github.com/nathanmerrill/WeakestLink/blob/master/src/…–
Nathan Merrill

@NathanMerrill哇,非常感谢。对于emptyPosition[emptyPosition.length],这是一个愚蠢的错误,因为长度总是比最后一个索引^^大一。感谢所做的更改,我将使用此新版本进行更正。关于三元组……是的,感觉很喜欢使用它,也许太习惯于自己写东西了,我猜想起来并不方便。进行更正和更新。
Katenkyo,2015年

2

狙击手艾德

在添加PrudentSniper之前,我写了一个机器人来帮助Sniper击败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()返回一个long,而不是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;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.