究極のサムライ対決


37

通知:この挑戦は完了しました。これは、The ObserverのエントリでC5H8NNaO4に与えられた緑色のチェックマークが新しい回答に移動しないことを意味します。

まだ新しいエントリを送信できますが、新しいエントリを積極的にチェックしていないため、新しいトーナメントの実行が遅れる可能性があります。

前書き

このチャレンジでは、アルティメットサムライショーダウンアルティメットエディションスペシャルバージョン2.0 Xアルファオメガターボ(略してアルティメットサムライショーダウン)というタイトルアーケードゲームをプレイしています。相手は?Programming Puzzles&Code Golfの他のメンバー以外は誰もいません!

PPCGアーケードゲームに期待されるように、Ultimate Samurai Showdownを直接プレイするのではなく、ゲームをプレイするプログラムを作成します。このプログラムは、他のユーザーが1対1の決闘で提出したプログラムと戦います。最も熟練したプログラムは、PPCGのUltimate Samuraiを冠し、伝説の緑のカチカチを与えられます。

ゲームの説明

このセクションでは、ゲームの背後にあるメカニズムについて説明します。

勝利条件

試合は 2から成る武士互いに相殺直面しています。各muraは20 ヒットポイントと1 名誉で各試合を始めます。対戦相手が死亡し、まだ生きている場合、saが勝ちます。サムライが死ぬには2つの方法があります。

  1. サムライのヒットポイントが0になると、彼は死にます。
  2. sa が自分の名誉 0 未満にすると、決闘で不名誉な振る舞いをしたことで神に打たれます。

神に打たれることは、ヒットポイントを0に減らすことよりも優先されるため、1人の武士の体力が0で、もう1人の体力が-1の場合、体力が0の武士が勝ちます。両方のサムライが-1名誉である状況では、彼らは両方とも神に打たれ、ゲームは引き分けです。

マッチは最大500 ターンで構成されます。500ターンすべてがパスし、試合が決定されなかった場合(どちらのサムライも死亡しなかった場合)、神々は退屈して両方のサムライを打ち倒し、引き分けになります。

行動

各ターンで、サムライは次のアクションの1つを正確に実行する必要があります。

W

サムライは待機し、アクションを実行しません。これにより、彼はクールに見えますが、相手を倒すことはできません。これもデフォルトのアクションです。

B

サムライは、名誉ある方法で相手に頭を下げます。これは神を喜ばせ、したがってthusは1名誉を得るでしょう。名誉は基本的にこのゲームの「リソース」であるため、名誉はあなたのサムライの成功に不可欠です-名誉はすべて離れて移動しBW名誉を低下させる可能性があります。また、サムライが7名以上の名誉を得た場合、神の剣の使用が許可されます。これの意味を以下に説明します。
ただし、相手がお辞儀をすると、相手が剣であなたを攻撃することに決めた場合、あなたは開いたままになりますので、お辞儀をするときは注意してください。

G

サムライは防御的な位置に入り、剣の攻撃を防ぐものとする。この動きは、すべての剣のストライキ、神の剣で作られたものをもブロックします。
ただし、神は過度に防御的なサムライに眉をひそめるので、直前のターンのサムライのアクションも守っていた場合、この動きは1名誉を消費します。それ以外の場合は、Honorを消費しません。

I

サムライは、鞘から刀を素早く引き抜いて相手を攻撃しようとします。サムライに7名以上の名誉がある場合、彼は通常の剣の代わりに剣を使用します。この動きは1名誉を消費します。
クイックドローは速いストライクで、遅いオーバーヘッドの攻撃に打ち勝ちますが、受け流しに対しては負けます。ストライクが正常に接続されると、Sword of the Godsで 1ダメージ、または2ダメージを与えます。

P

サムライは、入ってくる攻撃を受け流そうとし、その後自分の攻撃を開始します。サムライに7名以上の名誉がある場合、彼は通常の剣の代わりに剣を使用します。この動きは1名誉を消費します。
この受け流しは速いストライキに対する優れた機動ですが、より遅いオーバーヘッド攻撃によって圧倒されます。ストライクが正常に接続されると、Sword of the Godsで 1ダメージ、または2ダメージを与えます。

O

サムライは、より遅いオーバーヘッド攻撃で相手を攻撃しようとします。サムライの名誉が7以上の場合、通常の剣の代わりに剣を使用します。この移動は1名誉を消費します。
頭上のストライキは受け流しを圧倒できますが、速いストライキに対しては負けます。ストライクが正常に接続されると、Sword of the Godsで 1ダメージ、または2ダメージを与えます。

神々の剣

7以上の名誉を持つwith は、神の剣を使用する能力を獲得します。彼の名誉が7を下回った場合、神を使用する能力は彼から取り消されます。神々剣は 1ではなく2のダメージを与えます。

神々剣は、ストライキが通常は負けない剣のストライキを打ち負かすことを許可しません。たとえば、Sword of the Godsの受け流しは通常のオーバーヘッドストライクで負け、Sword of the Godsのクイックドローは通常のクイックドローを圧倒しません。確かに、いわゆる神の剣強力ではありません-おそらくそれは神によって演じられる宇宙の冗談です...

相互作用表

以下のスタックスニペットには、2人のサムライが取ることができるアクションのさまざまな組み合わせのすべての可能な結果を​​明示的にリストするテーブルが含まれています。表示するには、[コードスニペットを表示]をクリックし、[コードスニペットを実行]をクリックします。

プログラムコミュニケーション

トーナメントの運営を容易にするために、「神」の役割を果たすコントローラプログラムが作成されました。これは名誉と健康の記録を保持し、それに応じてサムライを攻撃します。このセクションでは、プログラムがコントローラープログラムと通信する方法について説明します。

入力の説明

コントローラプログラムは、次のようにコマンドラインからプログラムを呼び出します。

<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>

ここで:

  • <command>プログラムの実行に必要なコマンドです。たとえば、プログラムがファイルにあるsuper_sentai.pl場合、コマンドはおそらくperl super_sentai.plです。

  • <history>あなたが行った動きの履歴です。たとえば、WWBP2回待機し、1回お辞儀をし、1回受け流したことを意味します。

  • <enemy_history>敵が行った動きの履歴です。たとえばBBBI、敵が3回頭を下げ、1回のクイックドローを実行したことを意味します。

  • <your_health> あなたの現在の健康状態です。

  • <enemy_health> 敵の現在の健康状態です。
  • <your_honour> あなたの現在の名誉です。
  • <enemy_honour> 敵の現在の名誉です。

最初のターンでは、historyand enemy_historyは空になるため、プログラムは次のように最後の4つの引数で呼び出されます。

<command> <your_health> <enemy_health> <your_honour> <enemy_honour>

これに備えてください!

気の利いた読者は、両方のofの名誉と健康を提供する4つの議論が、ある程度までは不必要であることに気付くかもしれません。これは完璧な情報ゲームであるため、武士の名誉と健康は、履歴のみを使用して決定できます。

これらの値は、履歴の引数を解析する必要がないように、便宜上提供されています。これは、Honorが0のときに攻撃しないなど、単純な戦略を実装するのに役立つはずです。

出力の説明

アクションを選択するには、あなたのプログラムのはず出力1 WBGIP、またはOあなたが作りたいものをアクションに応じて、標準出力に。プログラムが1000ミリ秒以内に何も出力しない場合、プログラムは終了し、プログラムは出力されたかのように扱われますWます。

プログラムが複数の文字を出力する場合、最初の文字のみが考慮されます。したがって、出力Parryは出力と同じになります。Pます。。

プログラムの最初の文字の出力が上記のオプションのいずれでもない場合、デフォルトで W

提出形式

この投稿への回答としてプログラムを送信してください。複数のプログラムを提出できます。複数の簡単なプログラムを提出する場合は、単一の回答として提出することをお勧めします。複数の複雑なプログラムを提出する場合は、個別の回答として提出することをお勧めします。プログラムをトーナメントに正常に追加したら、エントリ(下にリンク)を使用してgitリポジトリにコミットします。

プログラムがトーナメントに追加されない問題が発生した場合、問題を示すコメントをエントリに残します。

提出物に以下を含めてください:

  1. スコアボードで使用する、人間が読めるプログラムの名前。ここではスペースを使用できます。コンマとUnicode文字はそうではありません。
  2. あなたのプログラムが書かれている言語。TinyMUSHのような奇妙でアクセスが難しい言語で書かないでください。
  3. プログラムの短い概要。これは、プログラムの仕組みに関する説明、またはプログラムに関するフレーバーテキスト(すべて秘密にしたい場合)、またはその両方です。
  4. プログラムの実行に必要なコマンド。たとえば、で呼ばれるJavaで提出物を書いているexample.java場合は、コンパイル手順を提供してjavac example.javaから実行手順を提供しますjava example
  5. プログラムのソースコード。

提出を支援するために、ここにある提出テンプレートを提供します。このテンプレートにより、提出物がより見やすくなります。使用を強くお勧めします。

2つのサンプルエントリも提供します。サンプルエントリはラウンドロビンに参加しますが、その主な目的は、Ultimate Samuraiのタイトルの真剣な候補者ではなく、トーナメントの提出および入出力形式を明確にすることです。

トーナメント構造

このセクションでは、参加者間のトーナメントがどのように実行されるかについて説明します。

制御プログラム

制御プログラムはPython 2で記述されており、Ultimate Samurai Showdown Githubリポジトリにあります。自分で実行する場合は、リンクのREADME.mdファイルに実行方法の説明が含まれています。ただし、トーナメント結果に影響するハードウェアの違いを避けるために、コンピューターで実行されるトーナメントのみが公式になります。

制御プログラムは、Arch Linuxを実行しているラップトップコンピューターで実行されます。Intel Core i7プロセッサと8GBのRAMを搭載しています。すべてのエントリをコンピュータで実行できるように努力しますが、自由にアクセスできない言語を回避する場合は非常に高く評価します(無料)。

スコアリングシステム

スコアリングシステムはラウンドロビンです。各プログラムは、他のすべてのプログラムに対して8つの試合を行います。勝利はプログラムに1ポイント、損失はポイントなし、引き分けは0.5ポイントを与えます。最高得点のプログラムがゲームに勝ちます。引き分けがある場合、私は勝者を決定するためにお互いに対して上位2つのプログラムを決闘します。

参加者が非常に多い場合、各プログラムが他のプログラムを再生する回数は8回から減らすことができます。これが発生した場合は、ここにメモを追加します。

新しい提出物が投稿されると、ラウンドロビンを何度も実行しますが、カウントされるのは最新のラウンドロビンだけです。

失格

プログラムがトーナメントから失格になる可能性があります。次の場合、失格となる可能性があります。

  • プログラムはコンパイルも実行もされません。
  • プログラムは、別のプログラムの戦略的複製です(つまり、別のプログラムとまったく同じ戦略を実装します)。
  • プログラムは、コントローラーコード、他のプログラムのコードなどを変更することにより、他のプログラムを妨害しようとします。
  • プログラムは、コントローラーコードのバグを悪用しようとします。バグを悪用する代わりに、代わりにgitリポジトリで問題を開くか、ここでコメントするか、チャットでpingを実行する必要があります。

過去の結果

すべてのトーナメントの詳細な結果は、wikiページで入手できます

最新のトーナメントは2015-07-17 07:20に完了しました。結果の概要は次のとおりです。

The Observer: 209.0
Coward: 203.0
Monk: 173.0
Elephant Warrior: 157.0
Iniqy: 157.0
Agent 38: 144.0
Ninja: 138.0
Meiyo Senshi: 138.0
Kakashi: 136.0
Yoshimitsu: 131.0
Hermurai: 121.0
Warrior Princess: 120.0
Gargoyle: 119.5
The Honourable: 119.0
Hebi: 118.5
Predictor: 116.0
Whack-a-mole: 107.0
The Fool: 106.0
The Prophet: 105.0
Copy-san: 97.0
YAGMCSE: 80.0
The Waiter: 66.0
Swordsman: 43.0
Spork Holder: 32.5
Blessed Samurai: 27.5
Attacker: 27.0
The Terminator: 17.0
Master Yi: 16.0

1
ウェイターは驚くほどうまくやっています。Spork Holderが名誉を失ったとき、Spork Holderに勝つ必要があります。
StephenTG

これはきちんとした挑戦です。あなたは明らかに多くのことを考えてこれに取り組み、間違いなく報われたと思います。よくできました。:)
アレックスA.

1
@ C5H8NNaO4はい、次のトーナメントを実行する前にボットの更新を確認します。
アブサン

1
Notice:私のラップトップは最近故障しました。したがって、近い将来トーナメントを運営する現在の方法はありません。使用できるコンピューターを見つけようとすると、次のトーナメントの実行に遅れが生じます。
アブサン

1
@Leviはい!製造業者は、今日到着した交換品を出荷しました。トーナメントが開催されています。
アブサン

回答:


8

修道士(Java)

僧kは名誉を大切にし、神の祝福を称賛します。忍耐の訓練を受けた彼は、神に愛されていると感じるまで、穏やかに祈りを天国に送ります。

彼の人生を楽しんで、彼はそれを保護しようとします。彼が特定の割合で健康を失っているとき、彼はできる限り最善を尽くします。

彼の神々の支援を望んで、彼は射精をランダムに送る[1]を天国。そうでなければ、彼は可能な限り最善の戦いをします。

相手が戦闘で疲れ果てた場合、彼は残りの名誉を使って彼に素早く痛みのない死を与えます。

コンパイル/実行

javac Monk.java
java Monk

public class Monk {
    public static void main(String[] args){
        char  r = 'B';
        double  s = Math.random ();
        int n = Math.max (args [0].length ()- 8, 1);
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int l = Integer.parseInt (args [3]);
        int m = Integer.parseInt (args [2]);
        double d = 1 + (20 - m) / n;
        double e = 1 + (20 - l) / n;

        if (((p>8&&s<.7)||l<11||m<2)&&p>0) {
                r=(s<(.14)||d>=2||e/d<.618)?'G':"OPI".charAt((int)(Math.random()*3));
        }

        System.out.print (r);
    }
}

忍者(Java)

忍者は高速で、攻撃はさらに高速です。彼は友好的な正式な挨拶の後すぐに攻撃し、攻撃の前後に頭を下げて敵をさらに混乱させます。

祝福されると、忍者はこの振る舞いを保ち、相手が最初の動きをするのを待ちます。この機会を利用して、彼は一連の爆風を解き放ち、戦いからすり減るまで忍者の女神に祝福されます。残りの名誉を利用して、彼は下の葉の下に隠れ、次の攻撃から身を守ります。彼は飛び出し、背後から敵を攻撃し、再び速く隠されます。

致命的な傷を負った場合、彼は相手のライブを一緒に取りに行きます-もちろん、最小限の名誉を保ちます。

javac Ninja.java
java Ninja

public class Ninja {
    public static void main(String[] args){
        char  r = 'B';
        int n = args [0].length ();
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int m = Integer.parseInt (args [2]);
        int a = n % 3;
        if (p>7) {
           if (m>17) {
                r = "BBI".charAt (a);
           } else if (m>13) {
                r = "BII".charAt (a); 
           } else {
               r  = "GIG".charAt (a);
           }

        } else if (p>0) {
           if (m > 10) {
                    r = "BBI".charAt (a);
           } else {
                r="IGI".charAt (n%2);
           }
        }
        System.out.print (r);
    }
}

カカシ、模倣猫(Java)

カカシは、相手が行った最後の2つの動きからランダムに選択することにより、相手の動きをコピーします。対戦相手が待つ場合、彼はお辞儀をします-彼は同様に彼の名誉を守ります。

javac Kakashi.java
java Kakashi

public class Kakashi {
    public static void main(String[] args){
        char  r;
        String h = args [1];
        if (h=="W" || Integer.parseInt ( args.length > 4?args [4]:"0") < 1){
                 r = 'B';
        } else if (Math.random ()<.1) {
            r = 'I';
        } else {
            r  = h.charAt ((int) (h.length()==1?0: h.length()-Math.random ()*2));
        }

        System.out.print (r);
    }
}


カカシが万華鏡に恵まれることを望んでいます。cast.txtを読むことを考えました。そこにいるすべての対戦相手に対して、彼の歴史のあらゆるラウンドをシミュレートします。シミュレートされた敵の履歴を実際の敵の履歴と比較することで、どの対戦相手と対戦しているかを調べてみてください。次に、その情報を使用して、対戦相手が次に行う動きを予測し、事前定義されたリストから最適なカウンタームーブを選択します。しかし、現時点ではインターネットが非常に遅く、Javaスキルがないため、これには少し時間がかかると思います

オブザーバー(node.js)

オブザーバーは、過去の5つの動きから相手の次の動きを予測しようとする前に頭を下げ、予測された動きに最適な相手を選択します。

編集:node.jsボイラープレートを共有してくれた@apsillersに感謝します!

node observer.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var m = {
    m:{},
    l:function (a,b) {
        if (!this.m[a]) {
           this.m [a] = [];
        }
        this.m[a].push (b);
    },
    p:function (a) {
       for (var k=0;k<a.length;k++)
       for (var j=1;j<a.length;j++)
       for (var i=-1+k; i<a.length-j; i++)this.l (a.slice (i,i+j),a[i+j]);
    },
    a:function (a) {
      if (!this.m[a])return;
      return this.m[a][0|Math.random () * this.m[a].length-1]
    }
}
var g={
   B:"IPO",
   G:"B",
   I:"PG",
   O:"IG",
   P:"OG",
   W:"I"
}
var c,i=0;
m.p(enemy.history);
while (!c && i++<enemy.history.length) {
   c=m.a (enemy.history.slice (i));
}
decide.apply  (0,my.honor < 7?["B"]:g[c].split (''))

編集:オブザーバーに重大な欠陥がありました。昨日の夜、私が実際に何を考えていたかわかりません。彼は敵の過去の2つの動きだけを見たようです。彼はこのように驚くほどうまくやった。

彼の記憶は、彼がすでに見た敵の歴史の中で最も長い(最後の)部分について質問されます。これには、移動の履歴に従ったすべての移動を含む配列が含まれます。1つはランダムに選択されます。したがって、1つの動きがより頻繁に続いた場合、同様に選択される可能性が高くなります。マルコフチェーンのようなもの。

オブザーバーも同様にガードします。


[1]:TIL:射精には宗教的な意味があります


あなたは今#1と#3です!素敵なボット!:)
アプシラー

オブザーバーでの優勝おめでとうございます。緑色のチェックマークはあなたのものになりました:D-
アブサン

7

明洋戦士(Java)

拝島地区出身の明陽についてはあまり知られていません。彼らは通常スポーツの試合には参加しませんが、彼らのライバルを評価するためにこのゲームに戦士を送りました。

しかし、彼らは名誉ある束なので、彼は彼の存在を神々に短期間で知らせることを確信できます。報告する敵を十分に見たら、受け取った祝福を使用して相手を打ち倒します。

実行をコンパイルするには、標準のJavaの方法です。

> javac MeiyoSenshi.java
> java MeiyoSenshi
public class MeiyoSenshi {
    public static void main(String[] args){
        System.out.print(
                Integer.valueOf(args[args.length<5?0:2])>12 ||
                Integer.valueOf(args[args.length<5?2:4])<1  ?
                "B":
                "IPO".charAt((int)(Math.random()*3))
        );
    }
}

7

スポークホルダー(ルビー)

スポークホルダーは最初のターンでお辞儀をし、その後ランダムに行動します。これは、2つのサンプルエントリの1つです。

コマンド: ruby spork-holder.rb

if ARGV.length == 4
    print "B"
else
    print ["W", "B", "G", "I", "P", "O"].sample
end

ウェイター(bash)

ウェイターは毎ターンだけ待機します。これは、2つのサンプルエントリの1つです。

コマンド: echo W

ソースコードは必要ありません。


7

ward病者(Node.js)

私はco病者/それは私が息をする勇気のある奇跡です
圧倒的/最も穏やかな夏の微風によって

  • BXBXBX/のチェックBBBあなたがお辞儀しているときのパターンは、弓(またはあなたをヒット)します。
  • のチェック GXGXGXガードしているときにお辞儀パターンをます。
  • 彼のランダムな勇敢なロールがそのラウンドの恐怖の閾値を克服した場合、彼はヒットを試みます。
    • 神の剣を持つことは彼を勇気づけます。
    • 神の剣を持つ敵は彼をより恐ろしくします。
    • 少なくとも5ヘルス以上リードする対戦相手は、彼を少し怖がらせます。
  • それ以外の場合、彼は交代でガードとお辞儀をします。

Node.jsの投稿を作成する場合は、ボイラープレートコードを使用してください。decide関数を含むすべてのものは完全に一般的であり、自由に利用できます。


node coward.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var enemyGuards = !!enemy.history.match(/G.G.G.$/);
var enemyBows = !!enemy.history.match(/(B.B.B.$)|(BBB$)/);

// open with a bow
if(!my.history) { decide("B"); }

// enemy will likely bow? Hit them with your super sword! (or bow)
if((!enemy.honor || enemyBows)) {
    if(my.godSword) { decide("P","I","O"); }
    else { decide("B"); }
}

// no point in hitting them if they're going to guard
if(enemyGuards) { decide("B"); }

// calculate bravery level
var braveryLevel = 0.3;
braveryLevel += (my.godSword * 0.2) - (enemy.godSword * 0.2);
braveryLevel -= (enemy.health - my.health > 5) * 0.1;

// if we're feeling brave, hit them
if(Math.random() < braveryLevel && my.honor) { decide("P","I","O"); }

// if we didn't just guard, and we're not feeling brave, cower in fear
if(!my.history.match(/G$/)) {
    decide("G");
}

// if we did just guard, and we're feeling cowardly,
//   if we don't have sword of the gods, bow
//   otherwise, do anything except guard
if(!my.godSword) {
    decide("B");
} else {
    decide("B","P","I","O");
}

1
それは難しいボットです。素晴らしいボイラープレート。すぐに使用します。共有していただきありがとうございます:)
C5H8NNaO4

6

もぐらたたき(R)

敵がお辞儀をする可能性があるときに攻撃し、そうでなければガードします。

args <- commandArgs(TRUE)
L <- length(args)
my_health <- as.integer(args[L-3])
enemy_health <- as.integer(args[L-2])
my_honour <- as.integer(args[L-1])
enemy_honour <- as.integer(args[L])
if(L>4){enemy_history <- args[L-4]}else{enemy_history <- ""}
if(my_honour<1){
    out <- "B"
}else if (enemy_honour<=1 | grepl("BB$",enemy_history)){
    out <- sample(c("I","O"),1)
}else{
    out <- "G"
}
cat(out)

を使用して実行しRscript Whack-a-mole.Rます。


1
いい仕事だ、それに名前が大好き。
アレックスA.

3

象の戦士(Java)

象の戦士は、より古く、より自然な時代からのものです。彼は多くを見て、すべてを覚えています。彼は敵を調べている間、神に好意を与え、それから彼を心に取り込んで、それらをバラバラにします。

コンパイル:javac ElephantWarrior.java
コマンド:java ElephantWarrior

import java.util.LinkedList;

//Elephants never forget
class ElephantWarrior
{


  static LinkedList<Choice> analysis = new LinkedList<Choice>();

  public static void main(String[] args){
      if(args.length < 6){ respond("B");}   
      String myhis = args[0];
      String enHis = args[1];
      int health = Integer.parseInt(args[2]);
      int enHealth = Integer.parseInt(args[3]);
      int honour = Integer.parseInt(args[4]);
      int enHonour = Integer.parseInt(args[5]);

        //Bow a few times until I know how he operates
        if(enHis.length() <= 5){
            respond("B");
        }

        //Special cases
        //If I'm at 0 honor, better bow
        else if(honour <= 0){
            respond("B");

        }
        else{
          analyze(enHis);

          //Narrow it down to applicable choices
          char hisLast = enHis.toCharArray()[enHis.toCharArray().length - 1];
          LinkedList<Choice> hisOptions = new LinkedList<Choice>();
          for(Choice c: analysis){
              if(c.pattern.toCharArray()[0] == hisLast){
                  hisOptions.add(c);
              }
          }

           //Default to assuming they bow
          char hisNext = 'B';
          int mostLikely = 0;

          //What will they do next?
          for(Choice c : hisOptions){
              if(c != null && c.probability > mostLikely){
                  //System.out.println("Option = " + c.pattern);
                  //System.out.println("Prob = " + c.probability);
                  mostLikely = c.probability;
                  hisNext = c.pattern.toCharArray()[1]; }
          }

          //Now go through potential case
          switch(hisNext){
              case 'W':
                  respond("I");
                  break;
              case 'B': 
                  respond("O");
                  break;
              case 'G':
                  respond("B");
                  break;
              case 'I':
                  if(enHonour  > 0){
                      respond("P");
                  }
                  else{
                      respond("B");
                  }
                  break;
              case 'P':
                  respond("O");
                  break;
              case 'O':
                  respond("I");
                  break;
              default:
                  respond("G");
          }
        }
    }





      static void analyze(String his){

        //Keep track of his previous moves
        char[] shortString = his.substring(1,his.length() - 1).toCharArray();
        char[] longString = his.toCharArray();
        for( int i = 0; i < shortString.length; i++) {
          String pattern = "" + longString[i] + shortString[i];
          boolean exists = false;
          for(Choice c : analysis){
              if(c.pattern.equals(pattern)){
                  exists = true;
                  c.probability++;
              }
          }
          if(!exists){
              analysis.add(new Choice(pattern, 1));
          }
        }
      }

      private static void respond(String s){
            System.out.println(s);
            System.exit(0);
        }

    }

class Choice{
        String pattern;
        int probability;

       Choice(String p, int i){
            pattern = p;
            probability = i;
       }
}

2
私はこれをテストしていませんが、4つしかない最初のターンで範囲外になるようargsです。
ジオビット

そう、それらがまったく含まれないことに気づきませんでした。明らかに、空の文字列を渡すことはできないと思います、ありがとう!
カイン

@katyaトーナメントに含める必要がありますが、修正されました。
カイン

3

戦士の王女(ジュリア)

これは、私が参加した最初のキングオブザヒルチャレンジです。これがどうなるか見てみましょう。

ウォリアープリンセスは攻撃と名誉を優先し、必要に応じて自己保存に頼ります。彼女はかなり熱心で、待ちません。機敏さを保つために、彼女はオーバーヘッド攻撃も使用しません。


名前を付けて保存warrior-princess.jlし、次のようにコマンドラインから実行します。

julia warrior-princess.jl <arguments>

ジュリアをお持ちでない場合は、こちらからダウンロードできます。問題を回避するために、最新の安定バージョンが推奨されます(つまり、開発バージョンではありません)。


type Samurai
    history::String
    health::Int
    honor::Int
end

A = length(ARGS) < 5 ? ["", "", ARGS] : ARGS

me = Samurai(A[1], int(A[3]), int(A[5]))
opponent = Samurai(A[2], int(A[4]), int(A[6]))


if length(me.history) == 0

    # Always begin the match with an honorable bow
    action = "B"

elseif (!ismatch(r"[OIP]", opponent.history) && me.history[end] != 'G') ||
       (me.health < 2 && me.honor > 0)

    # Guard if the enemy has not yet attacked and I did not previously
    # guard, or if my health is low and my honor is sufficient
    action = "G"

elseif me.honor < 2

    # Bow if I'm low on honor
    action = "B"

elseif opponent.honor >= 7 && opponent.history[end]['B', 'W']

    # Assume the enemy will attack with the Sword of the Gods if they
    # most recently bowed or waited
    action = "I"

else
    action = "P"
end

println(action)

1
あなたの最初のKotHエントリと、私が間違えなければ最初のJulia KotHエントリ:おめでとう!
プランナパス

@plannapusありがとう!:Dたぶん私はそれを習慣にするでしょう。
アレックスA.

3

ガーゴイル(Java)

名誉を消費することなく、防御的な動きを使用しようとします。

Javaエントリなので:

> javac Gargoyle.java
> java Gargoyle
public class Gargoyle { 
    public static void main(String args[]) {
        if (args.length < 5 || Integer.valueOf(args[4]) > 0) {
            System.out.println("IPO".charAt((int)(Math.random()*3)));
        } else if (args[0].charAt(args[0].length()-1) != 'G') {
            System.out.println('G');
        } else {
            System.out.println('B');
        }
    }
}

3

剣士(C / Java)

剣士は最初のターンで、そして彼が名誉を失ったときはいつでもお辞儀をします。次に、相手が前のターンでお辞儀をしていないか、防御していないか、待機していないかをチェックします。相手がそうしていなかった場合、彼は現在のターンでこれらのいずれかを行う可能性が高く、したがって剣士はランダムに相手を攻撃します。これが当てはまらない場合、前のターンを防御していない場合、彼は防御します。彼がいた場合、彼は名誉を得るためにお辞儀をします。

Cバージョン:

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    char* attack_moves[]={"I", "P", "O"};
    int random_num = rand() % 3;

    if(argc == 5 || atoi(argv[5]) == 0)
        print_and_exit("B");
    else if(argv[2][strlen(argv[2])-1] != 'B' && argv[2][strlen(argv[2])-1] != 'G' && argv[2][strlen(argv[2])-1] != 'W')
        print_and_exit(attack_moves[random_num]);
    else if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit("G");

     print_and_exit("B");
}

GCC(コンパイラ)をインストールし、コードを「Swordsman.c」という名前のファイルに保存してコンパイルします。

gcc Swordsman.c -o Swordsman

Swordsman」という名前の実行可能ファイルが作成されます。を使用して実行

Swordsman

Javaバージョン:

public class Swordsman {

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        int random_num = (int)(Math.random()*3);

        if(argv.length == 4 || Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else if(argv[2].charAt(argv[2].length()-1) != 'B' && argv[2].charAt(argv[2].length()-1) != 'G' && argv[2].charAt(argv[2].length()-1) != 'W')
            print_and_exit(attack_moves[random_num]);
        else if(argv[1].charAt(argv[1].length()-1) != 'G')
            print_and_exit("G");

         print_and_exit("B");
    }

}

javac(コンパイラ)をインストールし、コードを「Swordsman.java」という名前のファイルに保存してコンパイルします。

javac Swordsman.java

Swordsman.class」という名前のクラスファイルが作成されます。を使用して実行

java Swordsman



アタッカー (Java)

攻撃者は、相手を死に望んでいること以外は何も気にしません。彼は攻撃の動きの1つをランダムにたたき、名誉が低い場合は弓を打ちます。

public class Attacker {

    static int position = -1;

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        position = (position + 1) % 3;

        if(argv.length != 5 && Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else 
            print_and_exit(attack_moves[position]);
    }

}

javac(コンパイラ)をインストールし、コードを「Attacker.java」という名前のファイルに保存します、コンパイルのために」コマンド。

javac Attacker.java

Attacker.class」という名前のクラスファイルが作成されます。を使用して実行

java Attacker


予測子 (C / Java)

予測器は敵の動きを予測します。最初のターンでは、ランダムな動きを使用します。彼の名誉が低い場合は弓、敵の名誉が低い場合、または前のターンでお辞儀をした場合は攻撃します。予測子が前のターンをガードしていない場合、現在のターンでガードします。それ以外の場合、前のターンで敵が行ったのと同じ動きをしますが、そうでない'W'場合は、プレディクターは弓を使います。

Cバージョン:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    int random = rand() % 5;
    char* moves[] = {"B", "G", "I", "P", "O"};

    if(argc == 5)
        print_and_exit(moves[random]);

    if(atoi(argv[5]) <= 0)
        print_and_exit(moves[0]);
    if(atoi(argv[6]) <= 0)
        print_and_exit(moves[4]);
    if(argv[2][strlen(argv[2])-1] == 'G')
        print_and_exit(moves[4]);
    if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit(moves[1]);

    if(argv[2][strlen(argv[2])-1] != 'W'){
        char buf[2]={0};
        *buf = argv[2][strlen(argv[2])-1];
        print_and_exit(buf);
    }

    print_and_exit(moves[0]);

}

GCC(コンパイラ)をインストールし、コンパイルするために「Predictor.c」コマンドという名前のファイルにコードを保存します。

gcc Predictor.c -o Predictor

Predictor」という名前の実行可能ファイルが作成されます。を使用して実行

Predictor

Javaバージョン:

public class Predicator{

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }

    public static void main(String[] argv){

        int random = (int)(Math.random() * 5);
        String moves[] = {"B", "G", "I", "P", "O"};

        if(argv.length == 4)
            print_and_exit(moves[random]);
        else if(Integer.valueOf(argv[5]) <= 0)
            print_and_exit(moves[0]);
        else if(Integer.valueOf(argv[6]) <= 0)
            print_and_exit(moves[4]);
        else if(argv[2].charAt((argv[2].length())-1) == 'G')
            print_and_exit(moves[4]);
        else if(argv[1].charAt((argv[1].length())-1) != 'G')
            print_and_exit(moves[1]);
        else if(argv[2].charAt((argv[1].length())-1) != 'W'){
                    print_and_exit(""+argv[2].charAt((argv[2].length())-1));
        }
        else
            print_and_exit(moves[0]);
    }
}

javac(コンパイラ)をインストールし、コードをコンパイル用の「Predicator.java」コマンドという名前のファイルに保存します。

javac Predicator.java

Predicator.class」という名前のクラスファイルが作成されます。を使用して実行

java Predicator


私はそれをテストするためのpython2インタープリターを持っていないので、これらのボットがどれほど効果的かはわかりません。


1
私はこれをテストしていません(Attacker)が、引数が4つしかない最初のターンで範囲外になるようです。
ジオビット

攻撃者ArrayIndexOutOfBoundsExceptionは最初のターンで攻撃を与えているようで、最初のターンで待機させます。それ以外は機能しています。
アブサン

@KatyaおよびGeobits、修正済み。見つけてくれてありがとう。
Spikatrix

予測を実行するとsegmentation fault (core dumped)、ラウンド後24
C5H8NNaO4

@ C5H8NNaO4問題を修正しました。3つのボットすべてのコードを更新しました。今は正常に動作するはずです。それを指摘してくれてありがとう!:-D
Spikatrix

2

マスターイー(Python)

マスターの暗殺者は初期のゲームで多くの支持を得て、無敵になるまでそれを構築します。彼らはそれを最も期待しないときに攻撃しようとします。

import sys, random

class MasterYi(object):
    def __init__(self):
        self.attack = lambda: random.choice(['I','P','O'])
        self.bow   = "B"
        self.guard = "G"
        self.wait  = "W"
        if len(sys.argv)>6:
            self.hist = sys.argv[1]; self.ohist = sys.argv[2]
            self.hp   = sys.argv[3]; self.ohp   = sys.argv[4]
            self.hon  = sys.argv[5]; self.ohon  = sys.argv[6]
        else:
            self.hist = [];          self.ohist = []
            self.hp   = sys.argv[1]; self.ohp   = sys.argv[2]
            self.hon  = sys.argv[3]; self.ohon  = sys.argv[4]
        self.last  = self.hist  and self.hist[-1]  or "W"
        self.olast = self.ohist and self.ohist[-1] or "W"
        self.oGuarder = len(self.ohist)>4 and self.ohist[-4]==self.ohist[-2]=="G"

    def move(self):
        if self.hon < 1: return self.bow
        if self.olast == "G": return self.attack
        if self.hon > 6:
            if self.oGuarder: return self.bow
            if self.ohon > 6: return self.guard
            if self.ohon < 7: return self.attack
            return self.attack
        if self.ohon > 6: return self.guard
        return self.bow

Yi = MasterYi()
print(Yi.move())

実行するには:名前を付けて保存 MasterYi.py

python MasterYi.py <args>

2

コピーさん(C)

相手のすべての動きをコピーします。彼が失うことを保証されていることをかなり確信しています。コンパイル:gcc copy-san.c

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc == 5) {
        putchar('B');
    } else {
        char *enemy_hist = argv[2];
        size_t len = strlen(enemy_hist);
        putchar(enemy_hist[len - 1]);
    }
    putchar('\n');
    return 0;
}

2

ヘビ(Java)

ヘビは「蛇の道」に従います。

ヘビは神の祝福を必要としません。

スネークはストライクをスリッシャーにします。ビーチの波のように、入ってくるものは戻ってきた。

ヘビは待ちません。

Snakeには適切な感覚がありません。そうでなければ、Pythonで書かれているでしょう。

実行手順:

> javac hebi.java
> java hebi

コード本体:

public class hebi{

    public static void main(String args[]){

        if( (args.length < 5) || (args[0].length() % 18 == 0) ) System.out.println( "IPO".charAt((int)(Math.random()*3)) );
        else{

            int hist_size = args[0].length();

            if      (hist_size % 3 == 1) System.out.println("G");
            else if (hist_size % 3 == 2) System.out.println("B");
            else{

                if     (hist_size % 18 ==  9) System.out.println(args[0].charAt(hist_size -  3));
                else if(hist_size % 18 == 12) System.out.println(args[0].charAt(hist_size -  9));
                else if(hist_size % 18 == 15) System.out.println(args[0].charAt(hist_size - 15));
                else{

                    char move_head = args[0].charAt( (hist_size / 18) * 18 );
                    char move_mid;
                    if( hist_size % 18 == 3 ){
                        if     ( move_head == 'I' ) move_mid = "PO".charAt((int)(Math.random()*2));
                        else if( move_head == 'O' ) move_mid = "IP".charAt((int)(Math.random()*2));
                        else                        move_mid = "OI".charAt((int)(Math.random()*2));
                        System.out.println(move_mid);
                    }
                    else{
                        move_mid = args[0].charAt( ((hist_size / 18) * 18) + 3 );
                        char move_tail;

                        if( move_head == 'I' ){
                            if( move_mid == 'P' ) move_tail = 'O';
                            else                  move_tail = 'P';
                        }else if( move_head == 'P' ){
                            if( move_mid == 'O' ) move_tail = 'I';
                            else                  move_tail = 'O';
                        }else{
                            if( move_mid == 'I' ) move_tail = 'P';
                            else                  move_tail = 'I';
                        }

                        System.out.println( move_tail );

                    }

                }

            }

        }

    }

}

2

名誉ある(Java)

名誉ある価値は何よりも光栄です。つまり、彼の名誉は他の誰よりも優れています。敵のサムライがより大きなまたは同等の名誉を持っている場合、彼はお辞儀をします。彼ほど名誉あるものはありません。そうでなければ、彼はランダムな動きをします。彼は2度連続でガードしません-それは不名誉です!

コンパイルします:

> javac TheHonourable.java
> java TheHonourable

ソース:

public class TheHonourable {
    public static void main(String[] args) {
        char move;

        if (args.length < 5) {
            move = 'B';
        } else if (Integer.valueOf(args[5]) >= Integer.valueOf(args[4])){
            move = 'B';
        } else {
            move =  (args[0].endsWith("G")) ?
                    "IPO".charAt((int)(Math.random()*3)) :
                    "GIPO".charAt((int)(Math.random()*4));
        }

        System.out.print(move);
    }
}

1

祝福されたSa (Python)

このSaは、神の恩恵を可能な限り長く維持しようとします。彼は急いで聖剣を手に入れ、ストライキの1つで警備と攻撃を交互に行い、必要に応じて名誉を補充します。彼または彼の対戦相手のいずれかがすぐに落ちる可能性があるように見える場合、彼は殺害のために急いで行きます。彼はパターンを追跡できる相手に簡単に倒れますが、常に2ダメージで攻撃するという彼の戦略は非常に効果的です。

import sys
import random
class BlessedSamurai(object):
    def __init__(self):
        if len(sys.argv) < 7:
            print("B")
        else:
            self.attack = ['O', 'I', 'P']
            self.hp = sys.argv[3]
            self.ohp = sys.argv[4]
            self.hon = sys.argv[5]
            self.last = sys.argv[1][-1]
            print(self.move())

    def move(self):
        #check if I have low health or should rush the kill
        if (self.hp < 5 or self.ohp < 5) and self.hon > 0:
            return(random.choice(self.attack))
        # charge honour to get SOTG
        elif self.hon < 7:
            return 'B'
        #Alternate guarding and attacking
        else:
            if self.last == 'G':
                return(random.choice(self.attack))
            return 'G'
Sam = BlessedSamurai()

実行するには:
BlessedSamurai.pyとして保存します

python BlessedSamurai.py <args>

4
あなたのプログラムはその動きを印刷する必要があります
mbomb007

3
これはテストしていませんが、引数が4つしかない最初のターンで範囲外になるようです。
ジオビット

私は彼がしたことと同様のフォーマットを使用しました。@Stranjyr、引数を取得するために私がしたことを見てみましょう。
mbomb007

y'allの両方に感謝します!現在、Pythonインタープリターにアクセスすることはできませんが、問題を修正したと思います。どういうわけか、最初の一連の指示には履歴がないことを完全に見落としていました。
Stranjyr

こんにちは、あなたのプログラムに「グローバル名 'last'が定義されていません」という小さなバグがありました。それは小さなバグなので、問題を修正するように変更lastしましたself.last
アブサン

1

Hermurai (C ++)

相手を賞賛し、少し妄想的です。彼は自分がsaであるとまだ信じられないので、彼が他のmuraができることをできるかどうか知りたい。彼の決して消えない夢は、彼がそれを知る前に現実になりました。それは彼の頭を犠牲にする可能性があります...

#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string enemy_history(argv[2]);

    int ho;
    string honour(argv[5]);
    stringstream(honour) >> ho;

    if(ho > 20){
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }

    char lastMove = enemy_history[enemy_history.length()-1];
    if(lastMove == 'W' || lastMove == 'G')
        lastMove = 'B';
    printf("%c", lastMove);
    return 0;
}

Iniqy (C ++)

可能な限り激しく打ちます。彼が危険にさらされると、止められない攻撃モードに入ります。

#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string history(argv[1]);
    string enemy_history(argv[2]);
    string health(argv[3]);
    string enemy_health(argv[4]);
    string honour(argv[5]);
    string enemy_honour(argv[6]);

    int he, enemy_he, ho, enemy_ho;
    stringstream(health) >> he;
    stringstream(enemy_health) >> enemy_he;
    stringstream(honour) >> ho;
    stringstream(enemy_honour) >> enemy_ho;

    if(ho > 6 || ((he < 6 || enemy_he < 6) && ho > 0))
    {
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }


    printf("B");
    return 0;
}

どちらもC ++で書かれています。コンパイルします:

g++ iniqy.cpp -o iniqy

Linuxで実行するには: ./iniqy

Windowsで実行するには: iniqy.exe


1

ターミネーター(ルビー)

ターミネーターは自分の健康に注意を払っていません。ターミネーターには名誉の概念はありません。ターミネーターは将来から送信され、相手を終了することを決定します。それは、相手の動きを監視することで行われ、それ以外は何も行いません。動きをサンプリングし、現在の技術ではターミネーターの行動を予測できないほど複雑な方法で適切な応答を計算します。実際、2015年に住んでいる人にとっては、ターミネーターはややランダムに見えるかもしれません...

responses = {
  ?W => %w(B I),
  ?B => %w(I O),
  ?G => %w(B B),
  ?I => %w(G P),
  ?P => %w(B O),
  ?O => %w(G I)
}

if ARGV.size > 4
  pool = ARGV[1].chars.map{ |c| responses[c] }.flatten
  puts pool.sample
else
  puts %w(O I P B).sample
end

1

エージェント38 [1](C)

大規模な遺伝子操作の産物として、エージェント38はスーパー[2]サムライの体格と精神力を持ち、無力な[引用が必要]欠陥のある[引用が必要]競合他社よりも確実に優れています。


//Agent 38
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

float program[5][4][4][4][4]={
    {{{{-1.192779,0.693321,-1.472931,-0.054087},{0.958562,0.557915,0.883166,-0.631304},{-0.333221,1.410731,0.496346,0.087134},{0.459846,0.629780,-0.479042,-0.025909}},{{0.547976,1.059051,-0.748062,-0.675350},{-0.607591,-0.152156,-0.400350,-0.685337},{1.686450,0.628706,0.312865,0.324119},{1.652558,0.403733,-0.456481,-0.081492}},{{0.371629,-0.036948,-0.982682,0.065115},{1.360809,0.681294,0.505074,0.782737},{-0.545192,0.954937,-0.727853,0.273542},{-0.575777,1.615253,-0.064885,-0.516893}},{{0.577015,-0.112664,0.456595,-0.007560},{-0.660930,-0.738453,0.668093,1.716388},{1.972322,0.108558,0.535114,-0.337916},{0.640208,-0.019680,-0.769389,0.873087}}},{{{-0.021140,-0.095956,-0.098309,-0.280295},{-0.926284,1.724028,0.278855,0.678060},{0.153006,-1.860947,-0.577699,-1.931683},{-0.187152,0.529719,-1.164157,0.125499}},{{0.582208,-0.835029,-0.329857,0.088176},{-0.030797,0.389396,0.584636,-0.025866},{-0.736538,1.624658,0.690493,0.387515},{0.973253,-0.530825,1.934379,-0.872921}},{{0.812884,0.138399,-1.452478,-1.504340},{-0.119595,0.986078,-0.993806,1.102894},{0.848321,-0.268764,0.876110,0.782469},{0.948619,-0.557342,0.749764,-0.712915}},{{-1.195538,0.783784,-1.973428,-0.873207},{0.085426,-0.241360,-0.534561,-0.372105},{0.029696,-0.906821,0.932227,-0.834607},{0.764903,-0.276117,-1.346102,-0.093012}}},{{{0.168113,0.855724,1.817381,-0.547482},{0.468312,0.923739,-0.723461,0.798782},{-0.875978,-0.942505,-0.684104,-0.046389},{0.893797,-0.071382,0.283264,0.811233}},{{0.391760,0.309392,-0.045396,-0.977564},{0.085694,0.257926,-0.775461,0.060361},{0.486737,-0.175236,0.806258,-0.196521},{0.691731,-0.070052,0.636548,0.464838}},{{0.532747,-1.436236,-0.900262,-0.697533},{0.566295,0.650852,0.871414,-0.566183},{-0.075736,-0.886402,0.245348,-0.438080},{-0.811976,0.022233,-0.685647,0.323351}},{{-1.864578,1.141054,1.636157,-0.455965},{0.592333,0.890900,-0.259255,0.702826},{0.404528,0.905776,0.917764,0.051214},{0.761990,0.766907,-0.595618,-0.558207}}},{{{0.209262,-1.126957,-0.517694,-0.875215},{0.264791,0.338225,0.551586,0.505277},{0.183185,0.782227,0.888956,0.687343},{0.271838,0.125254,1.071891,-0.849511}},{{0.261293,-0.445399,0.170976,-0.401571},{0.801811,0.045041,-0.990778,-0.013705},{-0.343000,-0.913162,0.840992,0.551525},{-0.526818,-0.231089,0.085968,0.861459}},{{0.540677,-0.844281,-0.888770,0.438555},{0.802355,-0.825937,0.472974,-0.719263},{-0.648519,1.281454,0.470129,-0.538160},{-0.851015,0.985721,-0.993719,0.558735}},{{1.164560,-0.302101,0.953803,0.277318},{0.886169,0.623929,1.274299,-0.559466},{-0.948670,0.807814,-1.586962,-0.502652},{-0.069760,1.387864,-0.423140,0.285045}}}},
    {{{{0.747424,-0.044005,0.402212,-0.027484},{0.785297,0.169685,0.734339,-0.984272},{-0.656865,-1.397558,0.935961,-0.490159},{-0.099856,-0.293917,0.129296,-0.920536}},{{0.546529,-0.488280,-0.516120,-1.112775},{0.155881,-0.103160,0.187689,0.485805},{0.918357,0.829929,0.619437,0.877277},{0.389621,0.360045,0.434281,0.456462}},{{-0.803458,-0.525248,-0.467349,0.714159},{-0.648302,-0.005998,-0.812863,0.205664},{0.591453,0.653762,-0.227193,-0.946375},{0.080461,0.311794,0.802115,-1.115836}},{{-0.495051,-0.869153,-0.179932,0.925227},{-1.950445,1.908723,-0.378323,-0.472620},{-0.688403,-1.470251,1.991375,-1.698926},{-0.955808,-0.260230,0.319449,-1.368107}}},{{{-0.029073,-0.622921,-1.095426,-0.764465},{-0.362713,-0.123863,0.234856,-0.772613},{0.697097,0.103340,0.831709,0.529785},{0.103735,-0.526333,-0.084778,0.696831}},{{-0.670775,0.289993,-0.082204,-1.489529},{0.336070,0.322759,0.613241,0.743160},{0.298744,-1.193191,0.848769,-0.736213},{0.472611,-0.830342,0.437290,-0.467557}},{{-0.529196,-0.245683,0.809606,-0.956047},{-1.725613,0.187572,0.528054,-0.996271},{-0.330207,0.206237,0.218373,0.187079},{0.243388,0.625787,-0.388859,0.439888}},{{-0.802928,-0.811282,0.788538,0.948829},{0.966371,1.316717,0.004928,0.832735},{-0.226313,0.364653,0.724902,-0.579910},{-0.544782,-0.143865,0.069256,-0.020610}}},{{{-0.393249,0.671239,-0.481891,0.861149},{-0.662027,-0.693554,-0.564079,-0.477654},{0.070920,-0.052125,-0.059709,0.473953},{-0.280146,-0.418355,0.703337,0.981932}},{{-0.676855,0.102765,-0.832902,-0.590961},{1.717802,0.516057,-0.625379,-0.743204},{-0.170791,-0.813844,-0.269250,0.707447},{0.057623,0.472053,-0.211435,0.147894}},{{-0.298217,0.577550,1.845773,0.876933},{0.617987,0.502801,0.951405,0.122180},{0.924724,-0.166798,0.632685,-0.466165},{-0.834315,-0.864180,-0.274019,0.568493}},{{0.669850,-0.961671,0.790462,0.738113},{-0.534215,-0.556158,0.653896,0.031419},{0.065819,0.220394,0.153365,-0.373006},{0.886610,-0.742343,1.282099,0.198137}}},{{{0.092579,-0.026559,-1.121547,0.143613},{-0.289030,0.265226,-0.350741,-0.897469},{-0.918046,0.038521,-1.515900,0.488701},{-0.759326,-1.782885,-1.787784,0.249131}},{{-0.849816,-0.857074,-0.843467,-0.153686},{0.998653,0.356216,0.926775,0.300663},{-0.749890,-0.003425,-0.607109,0.317334},{-0.561644,0.446478,-0.898901,0.711265}},{{0.232020,-0.445016,0.618918,0.162098},{0.381030,-0.036170,0.084177,0.766972},{0.493139,0.189652,-0.511946,-0.273525},{0.863772,-0.586968,0.829531,-0.075552}},{{0.191787,-0.627198,0.975013,-0.448483},{-0.197885,0.151927,-0.558646,-1.308541},{-0.582967,1.207841,0.746132,0.245631},{0.314827,-0.702463,-0.301494,0.787569}}}},
    {{{{0.670028,-1.825749,-0.739187,0.482428},{0.175521,-0.020120,-0.154805,0.187004},{0.971728,-0.160181,-0.164031,-0.868147},{-0.954732,-0.175713,0.791116,0.294173}},{{-0.958337,-0.843157,-0.472882,0.273517},{-0.999058,0.824762,-0.223130,-0.150628},{0.393747,-0.301297,0.095572,-0.798950},{-0.119787,0.746673,0.955094,0.259353}},{{0.951590,0.225539,0.503282,0.668746},{-0.384898,-0.979592,-0.005485,-0.191883},{-0.692369,-0.642401,-0.825598,0.171933},{-0.321919,-0.498635,0.449704,0.780842}},{{-0.387902,0.522435,0.565608,0.166193},{-0.799671,-0.295871,-0.702573,-0.151006},{0.040550,-0.468503,0.651076,0.636352},{-0.839299,-0.090651,0.428761,0.187043}}},{{{-0.369823,0.377011,0.422936,0.284752},{-0.181514,-0.701449,0.748768,0.540533},{0.734381,0.149410,-0.867043,-0.397142},{-0.770904,-0.581897,-1.578306,-0.402638}},{{0.859015,-0.540358,0.202715,-0.975354},{-0.773629,-0.382342,-0.022498,-0.129286},{-0.901210,-0.641866,1.219216,0.731525},{0.740457,0.858546,-0.408661,-0.364897}},{{-0.830865,-1.370657,-1.226303,-0.392147},{-0.810554,-0.975232,-0.717845,-0.825379},{-0.150096,-0.664533,0.347084,0.243443},{-0.447383,0.842164,1.491342,0.380295}},{{-0.383958,0.811219,0.160459,0.841601},{1.631515,0.371637,0.110000,0.467783},{-0.689356,-0.004289,-0.081057,-0.317243},{0.092451,-0.181268,-0.575747,-0.580061}}},{{{0.908549,-0.013975,-0.880165,-0.938937},{-0.225713,0.449478,0.372569,-0.229889},{0.255711,-0.264752,0.307982,0.260505},{0.314966,-0.540905,0.743032,-0.078475}},{{-0.307472,-1.268296,0.020383,1.798401},{-0.150954,0.909716,-0.407903,0.379046},{0.621853,-0.003629,-0.582697,0.614618},{-0.122843,-0.627133,-0.217968,0.608322}},{{0.071923,0.807315,0.538905,-0.630660},{0.495641,0.240202,-0.920822,-0.258533},{-1.760363,-0.448525,-0.351553,-0.551666},{0.152720,0.900531,0.061966,-0.544377}},{{0.648923,0.450945,-1.530020,1.570190},{0.536210,0.078454,0.577168,0.464872},{-0.888258,-0.950748,0.781474,0.958593},{0.463631,0.319614,-0.248374,-0.413144}}},{{{0.293463,0.236284,1.721511,0.107408},{-0.790508,-0.072027,-0.559467,-0.955839},{-0.777662,-0.169876,0.896220,0.776105},{0.003944,-0.745496,-0.236446,-0.824604}},{{-1.770746,-0.051266,-0.174258,0.003074},{-0.339553,-0.868807,-0.032754,-0.494847},{-0.896712,0.957339,-0.003444,-1.582125},{-0.699883,0.626691,0.799635,-0.542343}},{{-0.635123,-0.755960,0.576373,-0.899530},{-0.393745,0.718900,0.312400,0.511415},{-0.647565,0.368431,0.214726,0.892693},{-0.511960,-0.513262,0.885908,-0.536478}},{{-0.590074,0.623328,0.268674,-0.401391},{0.308868,-0.869862,0.233132,0.243337},{-0.242908,-0.557192,-0.728454,0.867029},{0.156435,-0.805308,-0.815392,-1.437798}}}},
    {{{{0.613484,1.454566,-0.363858,0.634053},{0.535096,-0.641079,-0.607553,0.852559},{0.959100,-0.398621,0.375819,0.385756},{-0.601982,0.494128,0.809699,0.608804}},{{-1.390871,-0.943062,1.556671,0.966501},{-0.013242,0.152716,-0.089592,0.230793},{0.933785,0.119358,0.057387,0.502033},{-0.332925,0.537509,-0.081436,-0.701995}},{{-0.435117,0.996885,0.646630,-0.092342},{0.004343,-0.737514,-0.716187,-0.946819},{0.814258,-0.766971,-0.488162,-0.531619},{-0.923069,0.683915,-0.023809,-1.242992}},{{-0.909155,-0.166488,-0.159273,-0.908121},{-0.783871,-0.522598,0.691845,-0.164065},{1.255966,0.051373,-0.566025,0.820081},{0.186583,0.266032,-0.793747,-0.510092}}},{{{0.890639,0.970042,-0.507885,-0.029557},{-0.771142,-0.875802,0.400070,-1.264247},{-0.881146,0.570950,-0.051624,0.347612},{0.312110,-0.374885,0.600112,0.388460}},{{-0.417107,-0.309284,-0.128477,0.689671},{-0.695866,1.254585,-0.381883,-0.313415},{0.433565,0.919626,0.159180,-0.657310},{-1.396139,0.346053,0.108768,0.061238}},{{-0.776695,0.084491,0.045357,0.312823},{-0.379268,1.217006,-0.014838,-1.032272},{-1.251344,-0.366283,-0.124786,0.729754},{0.979936,0.669519,-0.900018,-0.596954}},{{-0.998834,0.593942,0.375639,-0.627459},{0.297281,0.400240,0.839707,0.960262},{-0.872143,0.574040,-0.559580,-1.965570},{-0.559218,-0.778780,-0.955526,-0.253380}}},{{{-1.919625,-1.911049,0.025035,0.754917},{-0.110993,0.535933,-0.572788,-0.856476},{-0.810836,-0.496261,1.128368,1.758826},{-0.564368,-1.849772,-0.251560,0.635528}},{{0.768196,-0.934122,0.207228,0.884610},{-0.356145,0.265792,-0.835582,0.377675},{-0.410745,0.613212,0.245560,-0.873826},{1.725191,-0.263344,-0.077167,-0.976379}},{{-0.736299,-0.109476,0.044512,-0.004005},{0.692230,0.316670,0.267247,-1.076821},{-0.903184,0.189762,-0.674111,0.219113},{0.639162,1.347521,0.428823,-0.765664}},{{-0.509165,0.458806,-0.851011,0.455027},{-0.218564,-0.063492,0.889320,-0.762062},{0.145950,0.985037,-0.489372,-0.879851},{0.352346,-0.127275,0.896496,-0.596037}}},{{{0.402678,1.479855,0.089187,0.967153},{-0.431225,0.402980,0.883584,-0.900324},{0.262233,-0.647278,0.637005,0.142678},{-0.003253,-0.671924,0.969458,-0.316752}},{{0.345185,-0.477503,-0.326822,-0.106251},{0.239521,1.617125,0.632651,0.969976},{-1.015183,-0.676629,0.955842,0.134925},{-0.319063,-0.493157,-0.488088,0.713008}},{{-0.468621,1.301292,-1.826501,1.138666},{0.170247,-0.661171,0.895204,-0.400700},{-0.077645,-0.978179,-0.245724,0.245282},{-0.258300,0.287261,-0.006274,0.549716}},{{-0.932247,-0.274950,0.920451,0.016237},{0.888865,-0.845248,1.661716,-0.108960},{0.712357,0.586609,-0.867356,0.355058},{-0.540912,0.892622,0.302627,0.247194}}}},
    {{{{0.817578,0.719047,0.438903,0.637398},{0.750466,-0.911799,-0.609606,0.358541},{-1.782979,-0.851717,-0.802122,0.735913},{0.490604,-0.417822,-0.332074,0.836756}},{{-0.650232,-0.442026,0.874916,0.705671},{0.217602,-0.755841,0.573944,0.279365},{-0.713729,0.358880,-0.308992,0.778297},{0.832099,-0.916695,-0.887834,1.041483}},{{1.019467,1.099488,-0.130674,-0.241995},{0.792572,0.756977,0.518186,0.070411},{-0.815779,-0.790757,-1.027439,-0.163698},{0.721461,-0.403364,0.656609,-0.367364}},{{-0.279333,-0.742041,0.515832,-0.408114},{0.834577,0.736056,0.900594,0.276357},{0.726000,0.464991,-0.569281,0.098139},{-0.582324,0.875666,-0.681556,-0.903009}}},{{{1.300969,-0.798351,0.107230,1.611284},{0.239211,0.418231,-0.795764,-0.398818},{-0.939666,1.768175,-0.297023,-0.064087},{-0.239119,-0.365132,0.864138,0.595560}},{{1.898313,-0.343816,1.066256,0.876655},{-0.053636,0.544756,-0.937927,0.189233},{0.445371,-0.656790,-0.675091,0.753163},{-0.293330,-0.002717,0.341173,0.095493}},{{0.951658,0.513912,-0.678347,-0.981140},{-0.020791,0.571138,-0.890648,0.881789},{-1.783345,0.909598,-0.393155,0.240630},{-0.057908,-0.237435,-0.124993,-0.754091}},{{-0.014153,0.127172,0.097134,0.538952},{0.167943,0.786395,0.946153,-0.762513},{-0.562758,0.675657,-0.226395,0.979761},{0.850214,0.818309,0.397074,-0.372059}}},{{{0.803316,-0.659538,-1.987864,-0.186366},{-0.259213,0.315848,-0.427898,0.326521},{-0.168181,-0.620898,0.562309,0.722064},{-1.949690,0.307720,-0.147760,0.603492}},{{0.898339,0.986228,0.724530,0.105193},{0.066046,0.037689,-0.553543,0.597864},{0.296553,0.165199,0.500125,-0.395978},{0.790120,-1.873361,0.354841,-0.187812}},{{-0.559746,0.357012,0.373903,-0.113564},{-0.671918,-0.919720,0.258328,-0.283453},{0.008365,0.597272,0.355827,0.391287},{0.355297,-0.631888,0.221383,1.448221}},{{0.259199,-0.491776,0.721151,0.391427},{0.494000,0.652814,-0.153306,-0.615687},{0.142167,-0.601161,0.281702,0.563390},{0.904019,1.284241,0.901663,0.244620}}},{{{-0.664638,-0.564596,0.839897,0.153358},{-0.506883,0.822337,-0.974957,-0.098112},{-0.962870,-0.274566,0.418039,-0.020525},{-0.965969,0.954587,-0.250493,-0.031592}},{{-0.966475,0.455338,0.868491,0.723032},{-0.002141,0.021922,-0.131429,-0.601106},{-1.240003,1.483318,1.612920,-0.653210},{-0.505979,0.005588,-0.087506,-0.705789}},{{-0.203137,0.765652,-0.132974,-0.900534},{0.731132,0.133467,-1.086363,0.600763},{1.795911,-0.411613,-1.990494,0.405937},{0.729332,-0.119175,-0.979213,0.362346}},{{-0.049014,0.228577,-1.728796,-0.898348},{-0.540969,1.245881,-0.820859,0.285859},{0.430751,-0.373652,0.034535,0.434466},{0.365354,0.243261,0.910114,1.497873}}}}
};
float eval_polynomial(float variables[4],int program_index,int variable_index,int indices[4]){
    if(variable_index==4)return program[program_index][indices[0]][indices[1]][indices[2]][indices[3]];
    float result=0,base=1;
    for(int power=0;power<4;++power){
        indices[variable_index]=power;
        result+=base*eval_polynomial(variables,program_index,variable_index+1,indices);
        base*=variables[variable_index];
    }
    return result;
}
int main(int argc,char *argv[]){
    srand(tick_count());
    rand();
    float variables[4],probability[5],total=0;
    int i,indices[4],temp;
    for(i=0;i<4;++i){
        sscanf(argv[i-4+argc],"%d",&temp);
        variables[i]=temp;
    }
    temp=variables[1];
    variables[1]=variables[2];
    variables[2]=temp;
    if(variables[1]==0){ //bow if our honour is 0
        putchar('B');
        return 0;
    }

    variables[0]/=20;variables[2]/=20;
    variables[1]=1/(variables[1]+1);variables[3]=1/(variables[3]+1);
    for(i=0;i<5;++i){
        probability[i]=eval_polynomial(variables,i,0,indices);
        if(probability[i]<0)probability[i]=0;
        total+=probability[i];
        probability[i]=total;
    }
    total*=(float)rand()/RAND_MAX;
    for(i=0;i<5;++i)if(total<probability[i]){
        putchar("BGIPO"[i]);
        return 0;
    }
    putchar('B');
    return 0;
}

[1]完全に無関係な数[2] 1%の確率で真であることが保証されている


YAGMCSE

モンテカルロ法はまともな遊びを示すようですので、ここにもう1つの一般的なモンテカルロシミュレーションエントリがあります!

このコンテストの他のほとんどのエントリとは異なり、このエントリはランダムゲームの多数のシミュレーションを使用するため、最適なパフォーマンスを得るには-O3フラグを使用する必要があります。

コマンドを使用してプログラムをコンパイルし ます。gccmonte.c -o monte -O3 -std = c99

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

const int turn_limit=500;
enum Move{
    WAIT,BOW,GUARD,QUICK,PARRY,OVERHEAD
};
struct Player{
    int health,honour;
    enum Move lastMove;
};
typedef struct Player Player;
//<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>
//<command> <your_health> <enemy_health> <your_honour> <enemy_honour>
int damage_table[6][6][2]={
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is waiting
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is bowing
    {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, //P1 is guarding
    {{0,1},{0,1},{0,0},{0,0},{1,0},{0,1}}, //P1 is using quick draw
    {{0,1},{0,1},{0,0},{0,1},{0,0},{1,0}}, //P1 is parrying
    {{0,1},{0,1},{0,0},{1,0},{0,1},{0,0}} //P1 is using overhead attack
};
enum Move decode_move(char x){
    switch(x){
        case 'W': return WAIT; break;
        case 'B': return BOW; break;
        case 'G': return GUARD; break;
        case 'I': return QUICK; break;
        case 'P': return PARRY; break;
        case 'O': return OVERHEAD; break;
    }
    return WAIT;
}
struct SimulationStat{
    enum Move first_me_move;
    int win,draw,lose,compound;
};
int stat_compare(const void*a,const void*b){
    return ((struct SimulationStat*)b)->compound-((struct SimulationStat*)a)->compound;
}
struct SimulationStat monte_carlo(int num_iters,enum Move first_me_move,Player original_me,Player original_opponent){
    struct SimulationStat simulation_result={first_me_move,0,0,0};

    for(int iter=0;iter<num_iters;++iter){
    Player me=original_me,opponent=original_opponent;
        int turn,game_result;
        for(turn=0;turn<turn_limit;++turn){
            enum Move me_move,opponent_move=rand()%(OVERHEAD-BOW+1)+BOW;
            if(turn==0)me_move=first_me_move;
            else me_move=rand()%(OVERHEAD-BOW+1)+BOW;

            //update honour for guarding
            if(me.lastMove==GUARD&&me_move==GUARD)--me.honour;
            if(opponent.lastMove==GUARD&&opponent_move==GUARD)--opponent.honour;

            int me_attacking=me_move==QUICK||me_move==PARRY||me_move==OVERHEAD,opponent_attacking=opponent_move==QUICK||opponent_move==PARRY||opponent_move==OVERHEAD;

            //update health of players
            me.health-=damage_table[me_move][opponent_move][0]*(1+(opponent.honour>=7));
            opponent.health-=damage_table[me_move][opponent_move][1]*(1+(me.honour>=7));

            //update honour for attacking (Sword of the Gods is revoked after the player attacks with an original honour value of 7)
            if(me_attacking)--me.honour;
            if(opponent_attacking)--opponent.honour;

            //printf("%d %d\n",me.health,me.honour);
            //printf("%d %d\n",opponent.health,opponent.honour);

            //check if any of the terminating conditions are met
            //c. both players fall off the graces of the gods (me.honour<0&&opponent.honour<0)
            if(me.honour<0&&opponent.honour<0){
                game_result=0; //draw
                break;
            }
            //a. player 1 falls off the graces of the gods (me.honour<0)
            else if(me.honour<0){
                game_result=-1; //loss
                break;
            }
            //b. player 2 falls off the graces of the gods (opponent.honour<0)
            else if(opponent.honour<0){
                game_result=1; //win
                break;
            }
            //d. both players are dead (me.health<0&&opponent.health<0)
            else if(me.health<0&&opponent.health<0){
                game_result=0; //draw
                break;
            }
            //e. player 1 is dead (me.health<0)
            else if(me.health<0){
                game_result=-1; //loss
                break;
            }
            //f. player 2 is dead (opponent.health<0)
            else if(opponent.health<0){
                game_result=1; //win
                break;
            }
        }
        //both players get struck down by the guards for being boring
        if(turn==turn_limit)game_result=0; //draw

        if(game_result==1)++simulation_result.win;
        else if(game_result==0)++simulation_result.draw;
        else ++simulation_result.lose;
    }
    return simulation_result;
}
int main(int argc,char*argv[]){
    //const int num_iters=200000,num_shortlist_iters=1000000;
    const int num_iters=20000,num_shortlist_iters=55000;

    srand(tick_count());
    Player me,opponent;
    if(argc==5){
        sscanf(argv[1],"%d",&me.health);
        sscanf(argv[2],"%d",&opponent.health);
        sscanf(argv[3],"%d",&me.honour);
        sscanf(argv[4],"%d",&opponent.honour);
        me.lastMove=WAIT;
        opponent.lastMove=WAIT;
    }else{
        sscanf(argv[3],"%d",&me.health);
        sscanf(argv[4],"%d",&opponent.health);
        sscanf(argv[5],"%d",&me.honour);
        sscanf(argv[6],"%d",&opponent.honour);
        me.lastMove=decode_move(argv[1][strlen(argv[1])-1]);
        opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]);
    }

    struct SimulationStat results[6];
    results[0].first_me_move=WAIT;
    results[0].win=0;
    results[0].draw=0;
    results[0].lose=num_iters;
    results[0].compound=-num_iters*2-1000; //waiting is worse than any other action

    for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){
        results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent);
        struct SimulationStat *cur=&results[first_me_move];
        cur->compound=cur->win*4+cur->draw*1-cur->lose*2;
    }
    qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare);

    for(int i=0;i<OVERHEAD-BOW+1;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound);
    }

    for(int i=0;i<2;++i){
        results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent);
        struct SimulationStat *cur=&results[i];
        cur->compound=cur->win*2+cur->draw*1;
    }
    qsort(results,2,sizeof(*results),stat_compare); 

    for(int i=0;i<2;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound);
    }
    putchar("WBGIPO"[results[0].first_me_move]);
    return 0;
}

1
彼はなんらかの理由でお辞儀をするようです。あなたはそれを見てあげたいかもしれません
C5H8NNaO4

@ C5H8NNaO4この深刻なバグについてお知らせいただきありがとうございます。私の編集はバグを修正するはずです。
ジャガイモ

YAGMCSEは、GBWWWWW...またはBWWWW
C5H8NNaO4

@ C5H8NNaO4それは奇妙です。あなたが言及した結果を再現することはできません。YAGMCSEの反対者はずっとお辞儀をしていましたか?
ジャガイモ

はい、彼は最初の7ラウンドでお辞儀をしていました。ここにペーストビンがあります
-C5H8NNaO4

1

ターゲットダミーに入ろうとして失敗した後、次のボットを紹介します...

ScroogeBot-Python 2

彼が1つの名誉を持っている場合、このボットはお辞儀をします。そうでなければ、彼はコインを投げます。

それが頭に着地した場合、彼はランダム攻撃を実行します。尾に着くと、彼はお辞儀をするかガードします。

コマンド: python scroogebot.py

import random, sys
# If he has more than one honor...
if int(sys.argv[5]) > 1:
    #Flip a coin.
    coin = random.choice(['heads','tails'])
    #If the coin lands on heads...
    if coin == 'heads':
        #Attack!
        print random.choice(['I','O','P'])
    #If the coin lands on tails...
    else:
        #Don't attack!
        print random.choice(['G','B'])
#If he has 1 honor...
else:
    #Bow!
    print "B"

イェーイ、新しいエントリー!ちょっと早急に-昨日オペレーティングシステムのイメージを再作成してから、新しいトーナメントをセットアップできるようになるまでしばらく時間がかかるかもしれません。今週の終わりまでに、結果で新しいトーナメントを開催する必要があります。
アブサン

0

ヨシミツ(JS)

最後の2つの動きをチェックすることで守られないようにしようとすると、より高い名誉で勇敢になります。作られたテンプレートapsillersに基づいて

var attacks = ['I','P','O'];
var pasive = ['B','W'];
var argv = process.argv;
var playerHistory = argv.length>6?argv[2].split(''):[];
var enemyHistory = argv.length>6?argv[3].split(''):[];
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:playerHistory };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;

enemy.lastMove = enemyHistory.pop();
enemy.secondToLast = enemyHistory.pop();

enemy.didAttack = !!attacks.indexOf(enemy.lastMove);

my.lastMove = playerHistory.pop();

function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

chooseAnAttack = function(){ decide.apply(this,attacks); };

if( ( pasive.indexOf( enemy.lastMove ) && my.honor < 15 ) || (my.honor < 7 && enemy.health > 10) || my.honor === 1 ){
    if( Math.random * 15 < my.honor ){
        chooseAnAttack();
    } else {
        decide('B');
    }
} else if( enemy.honor < 2 ){
    chooseAnAttack();
} else if( enemy.didAttack ){

    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }

} else if( enemy.lastMove = 'G' ) {
    chooseAnAttack();
} else if( enemy.lastMove === 'W' ){
    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }
}

0

ザ・フール(C)

愚か者は名誉の欠如を余儀なくされない限り、二度と同じ動きを繰り返すことのない、かなり不安定な戦略を懇願します。彼の動きは主にランダム性に基づいており、彼の行動を予測することは困難です。彼の考えは流血と究極の勝利にのみ設定されているため、彼の幸福は彼の心の最後のものです

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

const char commands[] =
{
    'W', 'B', 'G', 'I', 'P', 'O'
};

char select_candidate(const char c[])
{
    unsigned i = 0;
    int n_candidates = 0;
    char candidates[sizeof(commands)];

    for (; i < sizeof(commands); i++)
        if (c[i])
            candidates[n_candidates++] = c[i];

    /* There are no candidates for actions, so the fool blindly attacks his opponent, hoping for the best */
    return n_candidates == 0 ? 'I' : candidates[rand() % n_candidates];
}

int main(int argc, char *argv[])
{
    unsigned i = 0;
    int honour;
    char candidates[sizeof(commands)];
    char last_action;

    srand(time(NULL));

    memcpy(candidates, commands, sizeof(commands));

    /* It's the first round, the fool selects a random action except for waiting */
    if (argc != 7)
    {
        candidates[0] = 0;
        putchar(select_candidate(candidates));
        return 0;
    }

    last_action = argv[1][strlen(argv[1]) - 1];
    honour = atoi(argv[5]);

    if (honour == 0)
    {
        /* The fool realises he will meet his doom if he performs any of the following moves */
        /* and removes them from his list of possible actions */
        candidates[3] = 0;
        candidates[4] = 0;
        candidates[5] = 0;

        /* Only omit the blocking action if the last action was blocking */
        if (last_action == 'G')
            candidates[2] = 0;
    } else if (honour >= 7) {

        /* If the fool has the opportunity to abuse power, he will */
        candidates[0] = 0;
        candidates[1] = 0;
    }

    /* However unintellegent, the fool decides never to repeat the same move twice */
    for (; i < sizeof(commands); i++)
    {
        if (candidates[i] == last_action)
        candidates[i] = 0;
    }

    /* The fool randomly selects a possible action and hopes for the best */
    putchar(select_candidate(candidates));

    return 0;
}


預言者 (C)

預言者は、相手の前の2つの動きの知識を使用して、次の動きを予測し、迅速かつ致命的な反撃を提供します。また、彼は占星術などを行っています。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(int argc, char* argv[])
{
    char* hist;
    char* enemy_hist;
    int hist_len;
    int enemy_hist_len;
    int health;
    int enemy_health;
    int honour;
    int enemy_honour;

    if (argc != 7)
    {
        /* Always start with guarding */
        putchar('G');
        return 0;
    }

    srand(time(NULL));

    /* Grab the command-line values */
    hist         = argv[1];
    enemy_hist   = argv[2];
    health       = atoi(argv[3]);
    enemy_health = atoi(argv[4]);
    honour       = atoi(argv[5]);
    enemy_honour = atoi(argv[6]);

    hist_len = strlen(hist);
    enemy_hist_len = strlen(enemy_hist);

    /* Looks like the enemy is starving for honour. */
    /* This means that they have to bow, so attack them,  */
    /* But only if we have the honour to do so. */
    if (enemy_honour == 0 && honour > 0)
    {
        putchar('O');
        return 0;
    } else if (honour == 0) {
        /* We have to bow */
        putchar('B');
        return 0;
    } else if (honour <= 3) {
        /* We have low honour, attack if the enemy has no honour, otherwise bow to restore some of our honour */
        putchar(enemy_honour == 0 ? ((rand() % 2) ? 'I' : 'O') : 'B');
        return 0;
    }

    switch (enemy_hist[enemy_hist_len - 1])
    {
        /* The enemy has previously performed a passive action, so they will likely attack this round */
        case 'W':
        case 'B':
        case 'G':
            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G'); /* Protect ourselves, using `guard` if we did not use it last turn */
            return 0;

        default:
            if (enemy_hist_len >= 2)
            {
                switch (enemy_hist[enemy_hist_len - 2])
                {
                    case 'I':
                    case 'P':
                    case 'O':
                        /* The enemy has attacked for the last 2 turns, they will likely rest now */
                        putchar((rand() % 2) ? 'I' : 'O');
                        return 0;

                    default:
                        /* Low health, block an incoming attack */
                        if (health <= 5)
                        {
                            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G');
                            return 0;
                        } else {
                            /* Choose randomly to bow or attack */
                            int decision = rand() % 3;
                            putchar(decision == 2 ? 'B' : decision == 1 ? 'I' : 'O');
                            return 0;
                        }
                }
            } else {
                /* Attack! */
                putchar((rand() % 2) ? 'I' : 'O');
                return 0;
            }
    }

    /* If somehow we get to this point, parry */
    putchar('P');
    return 0;
}


編集

両方のプログラムはCで記述されており、次のコマンドでコンパイルできますgcc

gcc fool.c -o fool
gcc prophet.c -o prophet


ランニング

* nix

./fool <args>
./prophet <args>

fool.exe <args>
prophet.exe <args>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.