あなたは最も弱いリンクです、さようなら


50

このオブザチャレンジは、ゲームショーWeakest Linkに基づいています。ショーに不慣れな人のために、このチャレンジの核心はあなたが投票する人を扱っています

  • 他のプレイヤーがあなたより賢い場合、ポットを獲得する可能性は低くなります。
  • 他のプレイヤーがあなたよりも愚かである場合、獲得するポットが少なくなります。

各ラウンドの開始時に、ポットは$ 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
ストレスと喜びでなければなりません
CS

1
ant build configまたはそのようなものを期待すべきですか?私はJavaに慣れていないので、人々がこのような小さなプロジェクトをどのように設定するのかよくわかりません。
デールジョンソン

4
内からsrc\WeakestLink私はjavac Game\*.java Players\*.java Main.javaコンパイルしjava -cp .. WeakestLink.Mainて実行するために使用しました。
ライナス

回答:


22

スナイパー

一般的な考えは、愚かなプレーヤー(つまり、フェースオフで勝つ可能性が高いプレーヤー)の 1人をキープして、ポイントを狙うことです。その後、他の価値の低いプレーヤーを削除してポットを上げようとします。しかし、インテリジェントプレーヤーに到達するとき、愚かなプレーヤーが削除された場合に備えて、最も危険なプレーヤーを削除することを選択します。そうすれば、狙撃する人がいない場合、少なくとも敵対する可能性のある人を獲得する必要があります。また、私たちは常に最小または最大プレーヤーで投票するので、私たちは自分のやり方を得るのにかなり効果的だと思っています。

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

したがって、明らかにロールバックは編集を削除しません。可能な限り編集を削除して、これが元のバージョンであることを明確にしたい場合。
ライナス

12

慎重なスナイパー

Sniperですが、2つの特別な場合の動作があります。1つは、3つのボットが残っており、PrudentSniperが最も賢い場合、最も賢くないのではなく、中央のボットに投票することです。これにより、さらにいくつかのショーダウンに勝つことができます。もう1つの動作は、最も賢いボットがそれを狙っていて(前回またはそれに類似したボットに投票した)、最も賢くないボットがそうでない場合、最も賢いボットが自己防衛で賢明なものに投票することです。

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

両方の進歩が同等の価値があるかどうかはわかりません。それぞれ別々に試しましたか?
ライナス

私はそうしましたが、3つのボットのケースは明白な改善ですが(少なくともレポで現在マスターになっているボットに対して)、報復はネット上でほぼ中立です。あいまいな抑止力、暗殺者に対する予防策の一種として残しました。
histocrat


私は最近、スマートさが1-9ではなく0-8であったバグを修正しました。私はそれを修正してこれは(あなたがリポジトリに更新されたコードを見つけることができます)、あなたのコードを破った:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

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/...
ネイサン・メリル

1
@NathanMerrillありがとう、しかし、カルトが関心を寄せる未知の非会員に対してより寛容になるようにすれば(図を見て)、より良い結果が得られるようです。
ライナス

@agweber、提案をありがとう。これはおそらくthecultをより優れた単独プレイヤーにしますが、数字があればポットを駆使しようとするはずです。私の新しいバージョンは両方の世界で最高だと思います。
ライナス

2
TheCultunusedPlayers.addAll(allPlayers);、Game.javaで約9回複製するように私に依頼しました。これにより、すべてのプレイヤーがさまざまな多重度で発生することができます(カードの複数のデッキをシャッフルするなど)... もちろん、それは完全に偏ったリクエストですが、チームベースの戦略がどれほど強力なものであり、それらがまとめられる可能性がわずかでもある場合、それがどれだけ強力であるかを見るのは興味深いことです。
ライナス

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

このボットを動作させることができませんでした。いくつかのバグを修正しましたが、現在は存在しないプレイヤーに投票しています。正しいかどうかわからない変更の1つは、「last_round_voted」が定義されていないことでした。そのため、「last_voted_against」に変更しました。あなたはここに私の変化を見つけることができます:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

@NathanMerrillこのコードは、思っていたよりも明らかに悪かった。これでテストできるようになったので、両方のバージョンを見て、これが機能するようにします。
SnoringFrog

@NathanMerrillいくつかの問題が見つかりました。つまり、ボットに投票したことがないファウンドにいないプレイヤーを無視しなかったため、常にボットに投票しようとしました。また、間違ったリストを使用して、ある時点でインデックスを取得したため、プレイヤー-1が投票されました。しかし、今すぐ修正する必要があります。
SnoringFrog

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
よく書かれたコードを見るのはうれしいです:)
ネイサンメリル

6

RevengePlayer

このボットは、最も頻繁に彼に投票した人に投票します。タイブレーカーは最も賢いプレイヤーです。理論的には、過去にあなたに投票したプレイヤーが再びあなたに投票する可能性が高いということです。

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

私は最近、スマートさが1-9ではなく0-8であったバグを修正しました。私はそれを修正してこれは(あなたがリポジトリに更新されたコードを見つけることができます)、あなたのコードを破った:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

@NathanMerrill私のコードの修正には小さなバグがありました。コードを編集して改善しました。
メガトム

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よりも意地悪なのか理解できません
ネイサンメリル

@NathanMerrillに注意してください、彼は銃を持っています!私があなただったら、私は...慎重に私の言葉を選ぶだろう
CSᵠ

10
@CSᵠ私は心配していません。彼が平均的なプレーヤーであるとき、彼は自分で銃を使用します。
キントピア

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に維持します(より迅速なテストのため)。最終段階を実行すると、おそらくそれが大きくなります。
ネイサンメリル

私はあなたを非難しようとはしていませんが、これはスナイパーが時間の99.7%になる方法を投票します。彼らは同じ戦略に非常に近いので、基本的に誰が勝つかについてコインフリップになります。
ライナス

その統計はどこから得たのですか?私はそれが準類似の戦略を持っていることを認めますが、私の目標は、あなたよりもかなり賢い人に投票することを選択することによってあなたのような単純なものを改善しようとすることでした(別名私は勝つ可能性が低いです彼らは生き残る場合ポット)
csga5000

1
私はあなたのクラスにstatic Sniper S = new Sniper()とを与えましたstatic long agrees=0, disagrees=0;。あなたの投票方法ではS.setSmartness(getSmartness()); int sniper_answer=S.vote(currentOpponents);、スナイパーがあなたの位置でどのように投票するかを計算し、答えを変数に入れて、答えを返す前に同意したか否かをカウントします。ゲームが終了すると、「525602:1228」である「agrees:disagress」を印刷できます。
ライナス

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
アディソンクランプ

これにはバグがあると思います。Math.abs(enemyIntel - selfIntel) < closestIntelする必要がありますMath.abs(enemyIntel - selfIntel) < Math.abs(closestIntel - selfIntel)
メガトム

@MegaTom私はあなたが正しいと思います。Javaが利用可能になったら、これについてさらに確認します。可能性のあるキャッチをありがとう!
コナーオブライエン

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

2
露骨に私の作品を盗んだ、または少なくともそう認めてくれてありがとう。
ライナス

2
@Linusどういたしまして!模倣は最高のお世辞です、私は願っています。
ヤック

2
@ csga5000 は彼の冗談を露骨に盗みました。半分能力のあるコーダー(例えば、私)はループを同じように書くので、彼が本当にやったのは私の変数名を盗むことだけでした。もし私がそれらを著作権で保護しようと思っていたら、多分私はロイヤリティを請求できるでしょう。)
ライナス

4

Co病者

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;

  }
}

ただ票を投じたくないので、勝ったチームにいる可能性を最大化するために、最後のラウンドで票を投じたプレイヤーに最も類似した相手に投票します。

今のところ特にうまくいくわけではありませんが、ミックスに入れることもできます。


私は最近、スマートさが1-9ではなく0-8であったバグを修正しました。私はそれを修正してこれは(あなたがリポジトリに更新されたコードを見つけることができます)、あなたのコードを破った:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

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

私は最近、スマートさが1-9ではなく0-8であったバグを修正しました。私はそれを修正してこれは(あなたがリポジトリに更新されたコードを見つけることができます)、あなたのコードを破った:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

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

このコードも機能しませんでしたが、簡単に修正できました。あなたのcurrentOpponentsを渡すとき、私はあなたにあなたの賢さを与えないので、あなたのdo-whileは実際に必要ではありません。固定コードはここで見つけることができます:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

@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は、」印刷し、それを変更することをお勧めしたい
スカイラー

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

私は最近、スマートさが1-9ではなく0-8であったバグを修正しました。私はそれを修正してこれは(あなたがリポジトリに更新されたコードを見つけることができます)、あなたのコードを破った:github.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

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
好き。あなたと同じように投票する人は多くないので、うまくいかないのではないかと心配しています。この競争の欠点の1つは、他のボットが特定のタイプの戦略に従うように強制するように思われることです。
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
私はこのアイデアが好きですが、最小または最大プレーヤーに投票する文化があるようです。他の誰かに投票することはあなたの票を捨てるかもしれません。たぶん、他の誰かに投票する前に最大値が狙撃的であるかどうかを確認すると、少し追いつくでしょう...(電話では確認できません)
ライナス

2

RandomPlayer

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

VengefulSniper

これは私がオリジナルだと思ったもの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の男ではありません。

他のエントリを読む前に、このスキームを念頭に置いていました。それから、スナイパーがどれほど近いか(しかし非常に異なる)ので驚いたので、Java構文がわからないので、それをジャンプオフポイントとして使用しました。ありがとう@Linus


1
コードをテストしてください。あなたが知らない言語での書き込みの回答しようとしないでください
TanMath

@TanMath-ご意見ありがとうございます。私はC / Javaライクな言語で多くの経験を持っていますが、特にJavaではありません。そのため、コードが実際に正しく機能することを確信しています。とはいえ、エラーがあり、実行されない場合、ゲームマスターがエントリを失格させても気分を害することはありません。
tbernard

あなたが正しい。@Linusに感謝します。編集済み。
tbernard

1
@tbernardバグを修正できてうれしいですが、あなたのコードには何もありませんでした:)
Nathan Merrill

痛い。期待したほどうまくいかなかった。私は狙撃兵を助けたように見えたので、それは私が推測するものです。
tbernard

2

近似位置

このボットは、グループが同じパターンで続行することを想定して、同じ種類のターゲットをターゲットとすることを想定して、欠落しているスマートネス値のほぼ周りを撮影しようとしています。選択肢があれば、常に最も賢い2人のプレイヤーに投票します。

長い間私は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;は常に配列の範囲外になります。最後に、理由はわかりませんが、ラウンドに参加していないプレイヤーは投票します。
ネイサンメリル

ああ、また、あなたの三元ブロックはintではなくdoubleを返していて、とても複雑でした。私はそれを標準のif / elseに変えました。:あなたはGithubの上の私のすべての変更見つけることができますgithub.com/nathanmerrill/WeakestLink/blob/master/src/...
ネイサンメリル

@NathanMerrillうわー、ありがとう。の場合、emptyPosition[emptyPosition.length]長さは常に最後のインデックスに対する1であるため、これは愚かな間違いです^^ 変更のおかげで、この新しいバージョンを使用して修正します。三元ブロックについて...ええ、それを使用するように感じました、そしておそらく自分のために書くのにあまりにも慣れていたので、読むのが便利ではなかったと思います。修正を行い、更新します。
かてんきょう

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、記録を投票することでスナイパーを特定することはめったにないので、今では少しでもそれらを保護します。しかし、違いが明確な場合、それは常に狙撃兵の利益に作用するため、ほとんどがタイブレーカーのようなものです。勝つことに焦点を当てているのは、個々のラウンドではなく、巨視的なゲームです。ほとんどのラウンドでは、コインフリップ状況を維持する以上のことはできません。
ライナス

1

HighOrLowNotSelf

ランダムに最低または最高のインテリジェンスプレーヤーを削除します(自己ではありません)。

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はなくaを返します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.