4人のスタンドオフ


54

4人のスタンドオフ

説明

どういうわけか、4方向のスタンドオフに陥りました。装填された銃が手にあり、手some弾がベルトに引っかかっています。

目的は、スタンドオフの終わりに最も健康になることです。せいぜい1人の人がプラスの健康状態にあるとき、スタンドオフは終了します。

各プレイヤーは5体力を持ち、体力が/を下回ると死亡します0。プレイヤーが死亡するターンは、そのプレイヤーがダメージを受けることができる最後のターンです。

スタンドオフの最後にライブプレイヤーがいる場合、そのプレイヤーが勝ちます。そうでない場合、負のヘルスが最も少ないプレイヤーが勝ちます。

行動

  • 撃つ:誰かを撃つ

    • 2 生きている敵を撃った場合のダメージ
    • 0 死んだ敵を撃った場合のダメージ
    • health_at_start_of_turn+2自分を撃った場合のダメージ。(これにより、MOSTの-2健康状態が維持されることに注意してください。)
    • 自分が撃った同じターンに敵が1人撃った場合、-4の体力でスタンドオフを終了します(自殺したターンに他のプレイヤーからダメージを受けます)。
    • 次のターンのあなたの行動は無視されます(そしてそうであると仮定されますNothing)。
  • ダッジ:ダッジシングル相手のショットを試してみてください。

  • 準備:手g弾を外し、投げる準備をします。

    • あなたはそれをスローするために3ターンしか持っていません、あなたが爆破される前に(6あなた自身への3ダメージ、すべての生きている敵へのダメージ)
    • 投げられていない手ren弾で死ぬことは、手turns弾を3ターン投げないことと同じです。
  • 投げる:誰かに手g弾を投げつけて、最高のものを願ってください。

    • 8生きている場合、ターゲットはダメージを受けます
    • 3生きている場合、他のすべての人(自分を含む)がダメージを受ける
  • 何もない:ターンの間、じっと立って、全員が死ぬのを見てください。

入力

プログラムには次の情報が渡されます。

  • 各プレイヤーの健康
  • スタンドオフの開始以降にそのプレーヤーが行ったアクションのリストは、プレーヤーごとに渡される情報の形式です。

    [Health],[Action 1],[Action 2],[Action 3],...
    

アクションは、出力セクションで指定された形式で提供されます。

スペースで区切られた単一の引数として渡された4つの文字列を受け取ります。これらの文字列の順序は次のとおりです。

[Player Info] [Opponent 1 Info] [Opponent 2 Info] [Opponent 3 Info]

文字列は2番目の引数として渡されます。最初の引数には、成立するスタンドオフを一意に識別する整数が含まれます。同じプレーヤーのセット間のスタンドオフは、同時でないことが保証されています。ただし、複数のスタンドオフ同時に発生します。

例えば:

$./Player.bash 5 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

現在、プレーヤーと2番目の対戦相手のヘルスは3、1番目の対戦相手のヘルスは5、3番目の対戦相手のヘルスは-2で死んでいます。

最初のターン:

  • プレイヤー1が敵2を撃った
  • 敵1が手ren弾を用意した
  • 敵2ショットプレーヤー
  • 敵3が自分を撃った

2番目のターン:

  • すべてのプレイヤーは何もしませんでした。(プレイヤーと敵2は、前のターンで撃ったので何もできません。敵3は死んでいます。彼はNothing残りのスタンドオフを行います。)

スタンドオフの開始時の2番目の引数は次のとおり5 5 5 5です。

出力

コマンドは、以下のリスト形式で出力する必要があります。無効な出力は「Nothing」として解釈されます。ターゲットを必要とするコマンドの後には整数(0-30プレーヤーを表し、1-3敵1〜3 を表す)が続く必要があります。

  • S[target]:[ターゲット]を撃ちます。
  • D[target]:[ターゲット]をかわそうとします。
  • P:手ren弾を準備します。
  • T[target]:[ターゲット]に手ren弾を投げます。
  • N: 何もしない。

ターゲットを必要とするが、ターゲット間0ではなくターゲットに供給されるコマンド、3またはターゲットに完全に供給されないコマンドは、ターゲット0(プレイヤー)と見なされます。

得点

各スタンドオフの終わりに、プレイヤーは次の式で計算されたスコアを受け取ります。

35 + health at end of standoff 

プレイヤーが負の体力でスタンドオフを終了した場合、35以下のスコア受け取ります。次のポイントもボーナスとして報われます:

  • ほとんどの健康:+4ポイント
  • 2番目に健康:+2ポイント
  • 3番目に健康:+1ポイント。

同点の場合、より低いボーナスが付与されます(2人が最も健康な状態で同点の場合、両方に+2が付与されます。

最終スコアは、すべての個々のスコアの平均を計算して決定されます。

ルール/詳細

  • ターン内のイベントの順序は次のとおりです。
    • すべてのプレイヤーがアクションを実行します。
    • 体力が0以下のプレイヤーは死亡します。
    • 爆発する必要のある投げられていない手rena弾は爆発します(これは彼らが死んだ順番なので、死んだばかりのプレイヤーはまだ傷ついています)。
  • エントリー間のコラボレーションはありません。
  • 4人のプレーヤーの各セットの間で3つのスタンドオフが発生します。(プレーヤーの順序は、スタンドオフごとに異なる場合があります)。
  • ディスク容量のメモリを過剰に消費するエントリは失格となります。
  • エントリ以外のファイルを読んだり変更したりすると、エントリは失格となります。
  • 50thターンの終わりにスタンドオフがまだ終わっていない場合、酔っぱらいで運転されるトラックは、ターン後にすべての生きているプレイヤーの上を走り50thます。
    • このトラックは、すべてのライブプレイヤーに20のダメージを与えます。
  • スタンドオフはすぐに起こります。プログラムは1秒後に切断されます。
  • あなたのプログラムは、あなたが死んだ後でも毎ターン呼ばれます。
  • ディレクトリのファイルのみを読み書きできます(エントリの名前がJohnDoeの場合、players / JohnDoe /ディレクトリにファイルを保存できます)。ただし、これはスクリプトの実行中は現在のディレクトリではありません。
  • スタンドオフはArch Linuxを実行しているマシンで行われます(リリース2014.08.01)。

コントローラーはGitHubで入手できます

投稿に以下を含めてください:

  • ボットの名前
  • ボットを実行するシェルコマンド(例java Doe.java)入力は、単一の引数(java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")としてコマンドラインを介して渡されます。
  • ボットのコード
  • ボットのコンパイル方法(該当する場合)
  • 言語(および該当する場合はバージョン、特にpythonの場合)

*コントローラーは6時間がかかりすぎています。

スコアボード

                      Observer 43.280570409982
                   MuhammadAli 43.134861217214
                         Osama 43.031983702572
                    LateBoomer 42.560275019099
                 SimpleShooter 42.412885154062
             LessSimpleShooter 42.3772
                           Neo 42.3738
                        Scared 42.3678
                     Richochet 42.3263
                   Equivocator 42.2833
  TwentyFourthsAndAHalfCentury 42.2640
                        Darwin 42.1584
                       HanSolo 42.1025
                        Coward 42.0458
           ManipulativeBastard 41.8948
                        Sadist 41.7232
                     Aggressor 41.7058
                 CourageTheDog 41.5629
                     Grenadier 40.9889
                     Bomberman 40.8840
                         Spock 40.8713
                        Sniper 40.6346
                 DONTNUKEMEBRO 39.8151
               PriorityTargets 39.6126
                     Hippolyta 39.2480
                     EmoCowboy 39.2069
                      Zaenille 39.1971
                 AntiGrenadier 39.1919
      PoliticallyCorrectGunman 39.1689
                 InputAnalyzer 39.1517
                      Rule0Bot 39.1000
                     BiasedOne 39.0664
                      Pacifist 39.0481
               StraightShooter 39.0292
                         Ninja 38.7801
                           MAD 38.2543
                        Monkey 37.7089
                   Label1Goto1 36.2131
Generated: 2014/08/22 03:56:13.470264860 UTC

ログ:GitHubで


1
手exactly弾は1つだけですか、それともたくさんありますか?一度に複数の手rena弾を準備できますか?
isaacg 14

2
@Bob EmoWolf が、もはやおかしくない標準的な抜け穴に追加されたことは間違いありません。自殺のエントリは実際にそれほどひどくしないかもしれませんが。
es1024 14

3
みんなへのレッスン:飲んだり運転したりしないでください。
マークガブリエル14

8
@ es1024自殺が実際に実行可能な戦略である場合、EmoWolfタイプの提出は本当に許可されるべきです。特に、使用可能なアクションに明示的に自殺が含まれる場合!今ではそれほど「抜け穴」ではないでしょうか?そして、これらの抜け穴のほとんどが本当にある不公平な利点ではありません。しかし、それは私の意見です。
ボブ14

3
コントローラーを数回実行すると、かなりうるさいようです。このコンテストが終了した場合は、おそらく実行回数を増やして少しスムーズにする必要があります。
デイビス吉田14

回答:


7

観察者

この男は彼の敵を分析します。目標は、「攻撃的な」相手が1人だけ残るまで生き残り、その後、壮大なスタンドオフでその相手を殺すことです。

コンパイル:javac Observer.java実行:java Observer arg0 arg1

import java.util.List;
import java.util.ArrayList;
import java.util.Random;

class Observer {
    private static List<Integer> aggressiveEnemies = new ArrayList<>();
    private static List<Integer> enemyGrenadiers = new ArrayList<>();
    private static List<Integer> aliveEnemies = new ArrayList<>();

    public static void main(String[] args) {
        if (args[1].length() <= 7) { //first round
            Random rand = new Random();
            printResult("D" + (rand.nextInt(3) + 1));
        }
        String players[] = args[1].split(" ");

        if (truckIsOnWay(players[0])) {
            printResult("P");
        }       

        calcEnemyInfo(players);

        // end this standoff now
        if (truckWillHit(players[0])) {
            if (isGrenadier(players[0]))
                printResult("T" + aliveEnemies.get(0));
            else
                printResult("S0");
        }

        // shoot enemy who is not aggressive
        if (aggressiveEnemies.size() == 0) {
            printResult("S" + aliveEnemies.get(0));
        }

        // only one enemy to handle
        if (aggressiveEnemies.size() == 1) {
            String player = players[aggressiveEnemies.get(0)];
            if (isGrenadier(player)) {
                printResult("S" + aggressiveEnemies.get(0));
            } else if (shotLastTurn(player, aggressiveEnemies.get(0))) {
                //safe to shoot him without receiving damage
                printResult("S" + aggressiveEnemies.get(0));
            } else {
                printResult("D" + aggressiveEnemies.get(0));
            }
        }

        // multiple aggressive enemies
        if (enemyGrenadiers.size() > 0) {
            printResult("S" + enemyGrenadiers.get(0));
        } else {
            int id = aggressiveEnemies.get(0);
            for (int playerId : aggressiveEnemies) {
                if (!shotLastTurn(players[playerId], playerId)) {
                    id = playerId;
                }
            }
            printResult("D" + id);
        }
    }

    private static void printResult(String result) {
        System.out.print(result);
        System.exit(0);
    }

    private static boolean isAlive(String player) {
        return !(player.charAt(0) == '-' || player.charAt(0) == '0');
    }

    private static void calcEnemyInfo(String[] players) {
        for (int i = 1; i < players.length; i++) {
            if (isAlive(players[i])) {
                aliveEnemies.add(i);
                if (isAggressive(players[i], i)) {
                    aggressiveEnemies.add(i);
                }
                if (isGrenadier(players[i])) {
                    enemyGrenadiers.add(i);
                }
            }
        }
    }

    private static boolean truckIsOnWay(String player) {
        return player.length() - player.replace(",", "").length() == 48;
    }

    private static boolean truckWillHit(String player) {
        return player.length() - player.replace(",", "").length() == 49;
    }

    private static boolean isAggressive(String player, int id) {
        return (player.contains("S") || player.contains("P")) && !player.contains("S" + id);
    }

    private static boolean isGrenadier(String player) {
        return player.contains("P");
    }

    private static boolean shotLastTurn(String player, int id) {
        return player.charAt(player.length() - 2) == 'S' && !player.contains("S" + id);
    }
}

!player.contains("S" + id)これは「isAggressive」機能の必要条件ですか?とにかく自殺者は死んでしまいます
ランチャー

22

G弾兵

銃は過大評価されています。真のスコットランドのスタンドオフは、このように書きます:

  • 準備する
  • 最も体力のある敵に投げる
  • 繰り返します(何らかの奇跡によってあなたがまだ生きているなら)

これは些細なことのように思えますが、恐ろしい戦略ではないでしょう。銃と手rena弾はどちらも2ターンサイクルであるため、これはダメージを与えるためのはるかに効率的な1つの方法です。

もちろん、最初のラウンドで3人の対戦相手全員が私を撃った場合、それは良くありません。しかし、他にはあまりありません。

public class Grenadier {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;

        if(list[0].charAt(list[0].length()-1) != 'P'){
            System.out.print("P");
            return;
        }

        int target = 1;
        for(int i=2;i<4;i++)
            if(list[i].charAt(0)>list[target].charAt(0))
                target = i;

        System.out.print("T"+target);
    }
}

標準のJavaの方法でコンパイル/実行します。

> javac Grenadier.java
> java Grenadier arg0 arg1

1無意味な脚注


41
ハハハ

手g弾を投げてから撃つほうが効率的だと思います。この戦略で4ターンを生き延びる可能性は非常に低いです。しかし、多分3(はい、両方とも2を取りますが、射撃の2番目のターンはアクションの後であり、前ではありません)
ランチャー

@Cruncherあなたはおそらく正しいです。エリックはチャットで同じことを言った。私は、彼が銃を信じておらず、その論理を使用するには頑固すぎると彼に言ったので、彼はその戦略を投稿しました。ただし、与えられたダメージについて厳密に話している場合は、これがより効率的であると考えています。それはゲームに勝つことでより効果的であることを意味しません。3ターン目に死んでも、2番目の手ren弾は消えます。したがって、それまで生きていれば、すべての人に6以上のダメージ、ゲームオーバーが保証されます。
ジオビット

@Geobitsについて考えると、これはもっと良いかもしれません。最も重要なのは、あなたと相手の間のデルタです。手g弾が爆発すると、投げた相手とのデルタが+3、残りが+0になります。+3のネット。撮影。あなたが撃った人との+2デルタを得ます。残りは+0。問題は、すでに死んでいる人々と-3することだと思います。誰かが死んでいる場合は撮影する必要があります:)
ランチャー

2
@codebreakerプレイしたことはありません。これは実際の参照です。
ジオビット14

16

Asimovのルール番号0ボット-Python

ロボットは人類に危害を加えたり、不作為によって人類に危害を加えたりすることはできません。

かなり率直に、彼は人間の大部分を保護するために手g弾を持っていると見た最初のプレイヤーを攻撃します。誰もが大多数の人間にとって脅威でない場合、彼は何もしません。

import sys

def total_humans_alive(humans):
  return sum([is_alive(human) for human in humans])

def is_alive(x):
  return int(x.split(",")[0]) > 0  

def is_threat_to_humanity(lastAction):
  return lastAction == "P"

action = "N"
threat_id = 1
humans = sys.argv[2].split()[1:];

if total_humans_alive(humans) == 3:
  for human in humans:
    if is_threat_to_humanity(human[-1]):
      action = "S" + str(threat_id)
      break
    threat_id= threat_id+ 1

print action

次のように実行します:

python rule0bot.py

2
ロボットは非論理的です。手g弾を持っているプレイヤーが投げた場合、人類は8 + 3 + 3 + 3 = 17のダメージを受けます。ショットで彼を殺すと、人類は2 + 6 + 3 + 3 + 3 = 17のダメージを受けます。どちらのシナリオでも、手g弾が爆発した人は8人、他の人はすべて3人になります(以前に死んでいない場合)。人類全体は影響を受けません。それでも私はそれが好きです。+1:D
ジオビット14

4
実際、人類にとって最良のシナリオは、
手ren

1
@Geobits脅威のある人を阻止しようとしないことは、ロボットの性質に反します。大多数(他の2人)が傷つくのを防ぐために、手ren弾を持っている人を止めようとします。私、ロボットを読んだことがありますか?この論理は、Little Lost RobotとThe Evitable Conflictによって支えられています。
ウィリアムバルボサ14

私はそれを読みましたが、私が言っているのは、彼らを撃つことここでそれを止めないということです。手he弾を持ったまま死んでも、爆発します。それだけでなく、人類に与えられた損害の総量は同じままです。あなたは人類に利益をもたらすことなく、人間に直接害を与えています。
ジオビット14

2
+1カイルカノスの投票に同意せず、無効にします。また、Geobitsは、これが人類を助けるものではないと仮定するのは間違っています。確かに、最悪のシナリオでは人類は良くならないかもしれませんが、他の2人のプレイヤーがグレネードを使って潅水を振るうと、彼らはすべてより良くなります。
FreeAsInBeer 14

14

ハン・ソロ-パイソン

ハンが最初に撃った。この場合、彼は生きている最も近いターゲットを選ぶことによって最初に撃ちます。

import sys

def is_alive(player):
  return int(player.split(",")[0]) > 0

closest_living_target = 1;

for player in sys.argv[2].split()[1:]:
  if is_alive(player):
    action = "S" + str(closest_living_target)
    break

  closest_living_target = closest_living_target + 1

print action

次のように実行します:

python hansolo.py

:これは、私がPythonで書いた最初のものです。そのため、Python固有の悪い習慣があれば、教えてください。


1
pep8スタイルは、メソッドがis_alive
Daenyth 14

4
@WilliamBarbosaはpep8を見て、誰もが使用するpythonスタイルガイドです。legacy.python.org/dev/peps/pep-0008
Daenyth

2
8/11ラウンドで平均ヘルスが0を超える唯一のボットであることを祝福します。
isaacg 14

6
IMO、「スタイルガイド」は、プログラマーではなくヘアドレッサー向けです。
カイルKanos

2
@KyleKanosただし、ある程度の一貫性があると便利です。私は、プロジェクトの使用のキャメルケースと、このような他のハーフタイプの半分の開発者が、結果は「blergh」になる場合、意味
ウィリアム・バルボサ

12

エモカウボーイ

なぜ死ぬのを待つのですか?今すぐ自殺してください。願わくば、残りの愚か者たちが互いに-2をはるかに下回るまで爆破することを願っています。

通常、スコアは-2になります。人々が私を撃ち殺すことにした場合、時々-4。それ以上のことはありません。これは、これが現在の提出物のいくつかを打ち負かすことを意味します。

Python

print('S0')

python EmoCowboy.py

編集:これは冗談ではありません。これが一般にこれらのエモの提出が嫌われる理由です。これは正当な戦略です。生きていることは致命的です!


11

平和主義者

彼は本当のうねりで、間違った群衆に追いついただけです。

main = putStr "N"

として実行runghc pacifist.hsしますが、効率が問題になる場合は、-O3でコンパイルすることをお勧めします。


1
名前をルイージに変更して、彼が何かを獲得するかどうか見てみましょう!
ウィリアムバルボサ14

1
@WilliamBarbosaルイージ?ルイージと言った?
殺人14

7
まるで-O3おかしな違いを生むかのように笑。
tomsmeding

@tomsmeding runghc側では遅いです。実際、Linuxボックスでは10倍遅くなります。
レイ14

5
それは暴力の存在を意味し、私たちの平和主義者が対処する準備ができていないことを意味します
殺人14

9

-Python(初めてのエントリー!)

猿は見る、猿はする。ランダムプレーヤーがとった最後のアクションを正確に繰り返します。

import sys, random
targetData = sys.argv[2].split()[random.randint(0,3)]
print(targetData.split(',')[len(targetData.split(','))-1])

次のように実行できます。「python monkey.py args」追加の手順は必要ありません。


2
彼らがあなたを撃っていないことを願っています!Pythonは負の配列インデックスをサポートしているため、長さを計算して減算する必要はありません。-1直接使用するだけです。
14

@comperendinous私は彼らのリストにいるS3だと言ってください。S3を実行すると、ばかげたことはありません。また、-1インデックスは最後の要素を返しますか?もしそうなら、クール!必ず追加します。
エリアスベネベデス14

そして、最初の(整数)引数を忘れないでください。argv[2]プレイヤーの履歴を取得する必要があります。
14

エモカウボーイとマッチしないことを願っています。
codebreaker

6

Simple Shooter-Perl (バグを修正)

このボットは、体力が最も高い相手を撃ちます。これは非常に単純な戦略ですが、実際にうまくいく可能性は十分にあると思います。

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$target = 1;
for(2..3){
 if($history[$_][0] >= $history[$target][0]){$target = $_}
}
print "S$target"

これは、いくつかの入力例を使用して実行する方法です。

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

ワオ。シンプルでスマート。
ソハムチョードリー14

6

Spock、Python 3.x

このコードはかなり実験的です(そのため、Spockにちなんで名付けられました...彼はバルカンであり、これらの種類のものはかなり得意です)にもかかわらず、それを構築するのは楽しかったです。このすべてのコードの背後にある主な理由は、ゲームのルールが与えられた場合、Spockのように、良い論理的な存在が行うであろう仮定です:


このゲームの目的は、スコアを最大化することです。これは、じっと立っている全員によって行われますが、トラックのために不可能です。

  • スポックが従わなければならない指令の1つは、トラックが現れるのを防ぎ、トラックが現れる前に1人を除く全員が死んでいることを確認することです。

ゲームの残りの部分でのスポックのプレイ方法は、彼の有名な引用で要約することができます:「多くの人のニーズが少数の人のニーズを上回る」。言い換えれば、スポックは、それを行うものを殺すことによって、最小限のダメージを受けることを確認する必要があります。彼のやり方:

  • 手player弾を準備したプレイヤーがいない場合は、まだプレイしている最も健康度の低いプレイヤーをターゲットにします。
  • 手rena弾を準備したプレイヤーがいる場合、それらのターゲットから最も健康的でない。

その理由は、最も弱いプレイヤーをターゲットにすることで、ダメージの原因を終わらせることです。手rena弾の背後にある理由は、手regardless弾は関係なくオフになり、投げられなければダメージが少なくなるということです。


したがって、このボットは機能します。入力エラーについては広範囲にテストしていませんが(何か問題が発生した場合は警告してください)、ほとんどの問題を解決したと確信しています。HanSoloボットのコードの一部を基にしましたが、ほとんどの部分は複雑なコードの混乱です。楽しい。

def IsAlive(player):
  return int(player[1].split(",")[0]) > 0
def IsTarget(player, target_health):
  return int(player[1].split(",")[0]) < target_health
def HasGrenade(player):
  max_range = max(-4,-current_turn)
  for foo in range(-1,max_range,-1):
    if "P" in player[1].split(",")[foo]:
      for bar in range(-1,foo-1,-1):
        if player[1].split(",")[bar] not in ["T0", "T1", "T2", "T3"]:
          return True
  return False

import sys
info_list = sys.argv[2].split()
current_turn = len(info_list[0].split(","))
action = "N"

def Startgame():
  global action

  target = 1
  target_health = 5
  grenade_list=[]

  for player in zip(range(1,4),info_list[1:]):
    if HasGrenade(player):
      grenade_list.append(player)

  if not grenade_list:
    foo_list = []
    for player in zip(range(1,4),info_list[1:]):
      foo_list.append(player)
    target_list = foo_list
  else:
    target_list = grenade_list

  # Choose the least healthy player
  for player in target_list:
    if IsAlive(player) and IsTarget(player, target_health):
      target = player[0]
      target_health = int(player[1][0])

  action = "S" + str(target)

def Endgame(turn):
  global action

  if turn in [47, 49]:
    # Check if in 2 moves he can do enough damage
    rem_health = 0
    for player in zip(range(1,4),info_list[1:]):
      if IsAlive(player): rem_health += player[0]

    if rem_health < 5:
      Startgame() # It's lazy, but it should work
      return
    else:
      action = "P"
      return

  if turn in [48, 50]:
    # If Spock shot someone before, it needs to shoot again
    if info_list[0].split(",")[-1] in ["S0", "S1", "S2", "S3"]:
      Startgame()
      return
    else:
    # There's no rule against throwing grenades to dead bodies, so if
    # possible it will be thrown there.    
      target = 1
      target_health = 5

      foo_list = []
      for player in zip(range(1,4),info_list[1:]):
        foo_list.append(player)
      target_list = foo_list

      for player in target_list:
        if IsTarget(player, target_health):
          target = player[0]
          target_health = int(player[1][1])

      action = "T" + str(target)
      return

if current_turn > 46:
  Endgame(current_turn)
else:
  Startgame()

print(action)

次のように実行します:

python spock.py

2014-08-12-
手g 弾の検出に関するマイナーなバグ修正2014-08-14-前のゲームを指摘してくれたisaacgのおかげで、エンドゲームに関するマイナーなバグ修正


2ラウンドに1回以上は撮影できません。撮影に関する仕様をお読みください。
isaacg 14

@isaacgリマインダー(動作を説明しています)に感謝しますが、いくつかの潜在的なバグがあるようです。たとえば、このスポックは、ライブグレネードを持っているため(Soloの体力が2以上ある場合でも)InputAnalyserを撃ったはずです。
ドクトロライチャード14

Traceback (most recent call last): File "./players/Spock/Spock.py", line 87, in <module>: Endgame(current_turn) File "./players/Spock/Spock.py", line 79, in Endgame: if IsTarget(player, target_health): File "./players/Spock/Spock.py", line 4, in IsTarget: return int(player[1].split(",")[0]) < target_health TypeError: unorderable types: int() < str()
es1024 14

player[1][1]する必要がありますint(player[1][1])
isaacg 14

再び@isaacg、助けてくれてありがとう。私はもっ​​と早くこれをやっただろうが、私はものでいっぱいでした。スポックは最終的に、これがどのように展開されるかについての見当違いの概念に基づいて構築されたため、彼は比較的低いスコアを獲得しました。新しいボットにはいくつかのアイデアがありますが、非常に多くのボットがあるため、メインのアイデアがオリジナルであることを確認する必要があります。
ドクトロライチャード

5

政治的に正しいガンマン

それは何に対しても差別しないので、非常に政治的に正しい。したがって、あまりスマートではありません。

import random

array = ["P", "N", "S0", "S1", "S2", "S3", "D1", "D2", "D3", "T1", "T2", "T3"]

print(array[random.randrange(0,11)])

それは...どの引数がどのように渡されるかは本当に関係ありません。 python politicallycorrectgunman.py


角括弧が出力の一部になるとは思わない。おそらく@ es1024がそれを確認できます。random.choiceについて知っていますか?この種の選択には最適です。
驚異的な14

何が後に無視されているが、出力でのアクションとターゲットの前に何があっすることはできません
es1024

@ es1024の方が見やすいですか?
元に戻す

はい@Undo、今完璧に動作します
es1024

7
使っていただけませんrandom.choice(array)か?
user2357112 14

5

ストレートシューター

彼は騎兵隊の訓練を受けた部分であり、多くの言語で話していますが、まばたきされているため、ストレートシューターは彼の前にいる敵を1人しか見ることができません。馬であることから、彼はあなたがショットとショットの間を待たなければならないことを理解していません。

print('S2')

Perl、Python 2/3、Ruby:この馬は本当にポリゴットエントリです。

とにかく勝ちです。負けない あなたは私を撃つことができますが、私を殺すことはできません。ミスター・エドは私にうんざりしていません!

もう少し考え(および機能的なパラダイム)を入れた回答については、「20世紀と半世紀」を参照してください。


5

反g弾兵

手G弾は悪いです。ひどい。だから誰かが準備をしているなら、やるべきことはそれらを撃つことです。それ以外の場合は、たむろします。

-- Antigrenadier
local args = {...}  -- command line arguments

match = args[2]     -- store the set of matches

-- why this isn't standard in Lua....
function string:split( inSplitPattern, outResults )
  if not outResults then
    outResults = { }
  end
  local theStart = 1
  local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  while theSplitStart do
    table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
    theStart = theSplitEnd + 1
    theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  end
  table.insert( outResults, string.sub( self, theStart ) )
  return outResults
end

-- set up the players
players = match:split(" ")

-- search other players for someone who pulled a grenade
for i=2,#players do
   moves = players[i]
   -- test if person is alive
   if moves:sub(1,1) ~= "-" then
      -- cycle through all elements of the string
      for j=#moves,2,-1 do
         -- if found, shoot!
         if moves:sub(j,j) == "P" then
            print("S"..i-1)
            os.exit()
         end
      end
   end
end

-- otherwise we just relax
print("N")

4

跳ね返る-Perl

この課題では単純な戦略がきちんと機能しているように見えるので、もう1つあります。ランダムに生きているプレイヤーを撃ちます。トラックを回避するために最後に自殺するという追加機能があります。

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$health = $history[0][0];
@options = ();
for(1..3){
 if($history[$_][0] > 0){
  push(@options,$_);
 }
}
$target = @options[int(rand(~~@options))];
if(~~@{$history[0]} == 50){
 $target = 0;
}
print"S$target";

次のように実行します:

perl ricochet.plx 5 "-2,S0 -2,S1 -2,S2 5,N" 

4

攻撃者

ラウンド1でプルし、ラウンド2で最高のヘルスの相手に投げ、その後、最高のヘルスの相手でシュートします。

#include <cstdio>
#include <cstring>

int main(int argc, char** argv){
   char* t;
   t = strtok(argv[2]," ");
   int len = strlen(t);
   int max = -50, maxP;
   for(int i=1;i<4;i++){
      int cur;
      t = strtok(NULL," ");
      if(t[0]=='-'){cur = -1*(t[1]-'0');}
      else{cur = t[0]-'0';}
      if(cur>max){
         max = cur;
         maxP = i;
      }
   }
   if(len == 1){printf("P\n"); return 0;}
   if(len == 3){printf("T%d\n",maxP); return 0;}
   printf("S%d\n",maxP);
   return 0;
}

./agg ID "5 5 5 5"のように実行します。


4

忍者

ただ、ヒットしないようにランダムに回避します。

math.randomseed(os.time())
print("D"..tostring(math.random(4)-1))

として実行

lua ninja.lua

引数は不要ですが、問題なしで追加できます。


2
@KyleKanosは忍者が自分のショットをかわすでしょうか?
スケグゼ14

2
@distilledchaos:...はい、そうです。
カイルカノス

4

名前:PriorityTargets

シェルコマンド:ruby PriorityTargets.rb 5 [game_state]

言語:Ruby V2.1.2

説明:PriorityTargetsは、一般的なプレイスタイルを見つけようとします。次に、それらのプレイスタイルに基づいて、攻撃したい人と使用する武器を決定します。

:最初のコードゴルフの提出!私が少し夢中になったので、他の提出よりもはるかに大きい。

#!/usr/bin/env ruby

class PriorityTargets
  class PlayerAction
    SHOOT = 'S'
    DODGE = 'D'
    PREPARE_GRENADE = 'P'
    THROW_GRENADE = 'T'
    NOTHING = 'N'
    attr_accessor :action, :target

    def initialize(action_string)
        @action = action_string[0, 1]
        @target = self.has_target? ? action_string[1, 1].to_i : false
    end

    def to_s
      string = @action
      string << @target.to_s if self.has_target?
      string
    end

    def has_cooldown?
      [SHOOT].include? @action
    end

    def is_aggressive?
      [SHOOT, PREPARE_GRENADE, THROW_GRENADE].include? @action
    end

    def has_target?
      [SHOOT, DODGE, THROW_GRENADE].include? @action
    end
  end


  class Player
    attr_reader :identifier, :health, :history
    attr_accessor :playstyles

    def initialize(player_identifier, player_string)
      @identifier = player_identifier
      @playstyles = []

      player_info = player_string.split(',')
      @health = player_info.shift.to_i
      @history = parse_history(player_info)
    end


    def has_attacked?(player, round = nil)
      round ||= self.history.length - 1
      player.history[0, round].each do |turn|
        did_attack = true and break if turn.is_aggressive? && turn.has_target? && turn.target == player.identifier
      end
      did_attack ||= false
    end

    def is_holding_grenade?(round = nil)
      round ||= self.history.length
      turn_history = self.history[0, round]
      is_holding = false

      turn_history.each_with_index do |turn, curr_round|
        if turn.action == PlayerAction::PREPARE_GRENADE && curr_round >= round - 3
          is_holding = true if turn_history.drop(curr_round).select{|turn| turn.action == PlayerAction::THROW_GRENADE }.length == 0
        end
      end

      is_holding
    end

    def is_dead?; self.health <= 0; end
    def is_on_cooldown?
      return false if self.history.length == 0
      self.history.last.has_cooldown?
    end

    def turn_at_round(round); self.history[round-1]; end

    private

      def parse_history(history_array)
        parsed = []
        history_array.each {|action_string| parsed << PlayerAction.new(action_string) }
        parsed
      end
  end

  class PlayerList
    include Enumerable

    def initialize(player_list = [], filter_list = false)
      @list = player_list
      @filter = filter_list if filter_list
    end

    #Enumerable Methods
    def each
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.each {|player| yield(player) }
    end

    def <<(player); @list << player; end
    def [](key)
      player = @list.select{|player| @filter.include?(player.identifier) }[key] if @filter
      player = @list[key] unless @filter
      player
    end

    def length
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.length
    end

    def empty?; self.length == 0; end
    def not_empty?; self.length > 0; end

    def create_filtered_list(player_ids)
      new_player_list = PlayerList.new(@list, player_ids)
      new_player_list
    end

    #PlayerList Methods
    def includes_playstyle?(playstyle)
      (self.with_playstyle(playstyle).length > 0)
    end

    def have_executed_action?(action)
      action_found = false
      self.each {|player| action_found = true and break if player.history.select {|turn| turn.action == action}.length > 0 }
      action_found
    end

    def direct_damages(round = nil)
      round ||= self.first.history.length

      damage_list = {}
      @list.each {|player| damage_list[player.identifier] = 0 }

      if round >= 1
        @list.each do |player|
          player.history[0, round].each_with_index do |turn, curr_round|

            if turn.has_target?
              target_player = @list.select{|curr_player| curr_player.identifier == turn.target }.first
              target_turn = target_player.turn_at_round(curr_round)

              damage_list[turn.target] += 8 if turn.action == PlayerAction::THROW_GRENADE

              if turn.action == PlayerAction::SHOOT
                damage_list[turn.target] += 2 unless target_turn.action == PlayerAction::DODGE && target_turn.target == player.identifier
              end
            end
          end
        end
      end

      damage_list.select! {|key| @filter.include? key } if @filter
      damage_list
    end


    def filtered_with_condition(&condition_block)
      player_ids = []
      self.each {|player| player_ids << player.identifier if condition_block.call(player) }
      create_filtered_list(player_ids)
    end

    def on_cooldown; filtered_with_condition {|player| player.is_on_cooldown?} end
    def not_on_cooldown; filtered_with_condition {|player| !player.is_on_cooldown?} end

    def dead; filtered_with_condition {|player| player.is_dead?} end
    def not_dead; filtered_with_condition {|player| !player.is_dead?} end

    def with_playstyle(playstyle); filtered_with_condition {|player| player.playstyles.include?(playstyle)} end
    def not_with_playstyle(playstyle); filtered_with_condition {|player| !player.playstyles.include?(playstyle)} end

    def with_max_health(round = nil)
      round ||= self.first.history.length
      player_damages = direct_damages(round)
      filtered_with_condition {|player| player_damages[player.identifier] == player_damages.values.min }
    end

    def with_identifier(identifier)
      matches = self.with_identifiers([ identifier ])
      return nil if matches.empty?
      matches.first
    end

    def with_identifiers(identifiers)
      create_filtered_list(identifiers)
    end
  end

  class PlayerTypes
    GRENADIER = :GRENADIER
    COWBOY = :COWBOY
    SKIDDISH = :SKIDDISH
    AGGRESSOR = :AGGRESSOR
    DEFENSIVE = :DEFENSIVE
    ANTI_GRENADIER = :ANTI_GRENADIER
    PLAYSTYLE_ORDER = [GRENADIER, COWBOY, SKIDDISH, AGGRESSOR, DEFENSIVE, ANTI_GRENADIER]

    def initialize(player_list)
      @players = player_list
    end

    def analyze_playstyles
      return if @players.first.history.length == 0

      PLAYSTYLE_ORDER.each do |playstyle|
        check_fnc = "is_"+playstyle.to_s+'?'
        @players.each {|player| player.playstyles << playstyle if self.send(check_fnc, player) }
      end
    end

    def is_GRENADIER?(player)
      #Grenade on first turn
      #Used more than one grenade
      #Never used gun, only grenade
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if player.history.first.action == PlayerAction::PREPARE_GRENADE
      profiled ||= true if grenade_count > 1
      profiled ||= true if shoot_count == 0 && grenade_count > 0
      profiled ||= false
    end

    def is_COWBOY?(player)
      #Never used grenade, only gun
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if grenade_count == 0 && shoot_count > 0
      profiled ||= false
    end

    def is_SKIDDISH?(player)
      #Dodged more than once
      #Never hurts anybody
      dodge_count = player.history.count {|turn| turn.action == PlayerAction::DODGE }
      attack_count = player.history.count {|turn| turn.is_aggressive? }

      profiled ||= true if dodge_count > 1
      profiled ||= true if attack_count == 0 && player.history.length > 1
      profiled ||= false
    end

    def is_AGGRESSOR?(player)
      #Only shoots person >= most health
      profiled = false
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          profiled = false if !@players.with_max_health(round).include? @players.with_identifier(turn.target)
        end
      end
      profiled
    end

    def is_DEFENSIVE?(player)
      #Only hurts people who hurt them first
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          profiled = false unless target_player.has_attacked?(player, round)
        end
      end
      profiled ||= false
    end

    def is_ANTI_GRENADIER?(player)
      #After a Grenadier has been shown, only shoots grenadier
      shots_fired = 0
      shots_fired_while_holding = 0

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          shots_fired += 1
          shots_fired_while_holding += 1 if target_player.is_holding_grenade?(round)
        end
      end

      (shots_fired > 0 && shots_fired/2.0 <= shots_fired_while_holding)
    end
  end




  def initialize(game_state)
    players_info = game_state.split(' ')
    @player = Player.new(0, players_info.shift)
    @players = PlayerList.new
    @players << @player
    enemy_identifiers = []

    players_info.each_with_index {|info, index| @players << Player.new(index+1, info); enemy_identifiers << index+1; }

    @enemies = @players.with_identifiers(enemy_identifiers  )
  end

  def analyze_playstyles
    types = PlayerTypes.new(@players)
    types.analyze_playstyles
  end

  def find_dodge_target
    armed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).not_on_cooldown().not_dead()

    if armed_aggressors.not_empty?
      return armed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return @enemies[Random.rand(3)] if @player.history.length == 0
    nil
  end

  def find_target
    unarmed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).on_cooldown().not_dead()
    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()
    grenadiers = @enemies.with_playstyle(PlayerTypes::GRENADIER).not_dead()
    cowboys = @enemies.with_playstyle(PlayerTypes::COWBOY).not_dead()
    skiddish = @enemies.with_playstyle(PlayerTypes::SKIDDISH).not_dead()
    defensive = @enemies.with_playstyle(PlayerTypes::DEFENSIVE).not_dead()

    if unarmed_aggressors.not_empty?
      return unarmed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return anti_grenadiers.with_max_health().first if anti_grenadiers.not_empty?
    return grenadiers.with_max_health().first if grenadiers.not_empty?
    return cowboys.with_max_health().first if cowboys.not_empty?
    return skiddish.with_max_health().first if skiddish.not_empty?
    return defensive.with_max_health().first if defensive.not_empty?
    return @enemies.with_max_health().not_dead().first if @enemies.with_max_health().not_dead().length > 0
    nil
  end

  def find_weapon
    return PlayerAction::THROW_GRENADE if @player.is_holding_grenade?

    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()

    return PlayerAction::PREPARE_GRENADE if anti_grenadiers.empty? && @enemies.have_executed_action?(PlayerAction::PREPARE_GRENADE)
    PlayerAction::SHOOT
  end

  def make_decision
    dodge_target = self.find_dodge_target
    target = self.find_target
    weapon = self.find_weapon

    decision ||= PlayerAction.new(PlayerAction::NOTHING) if @player.is_on_cooldown? || @enemies.with_max_health().not_dead().length == 0
    decision ||= PlayerAction.new(PlayerAction::DODGE + dodge_target.identifier.to_s) if dodge_target
    decision ||= PlayerAction.new(weapon + target.identifier.to_s)
    STDOUT.write decision.to_s
  end
end

priority_targets = PriorityTargets.new(ARGV[1])
priority_targets.analyze_playstyles
priority_targets.make_decision

1
私はあなたのアプローチが好きです。それがどうなるか楽しみです。
オーバーアクター14

悲しいことに、G弾兵を作成したバグがあったようです。ああ、次回はもっと良くなる:)
fingerco 14

3

Co病者-Perl

非常にco病に振る舞います。彼が健康であると感じるとき、彼はそう感じない敵を選び、彼を撃ちます。最後のターンに射撃していた敵のボーナスポイント(Nothingこのターンを行っていることが知られており、したがって完全に無防備であるため)。気分が悪くなったとき、彼は隠れて逃げ出し、ときどき誰かを撃ちます。

#!/usr/bin/perl

@allinfo = map { [split/,/] } split / /, $ARGV[1];
@life = map { $_->[0] } @allinfo;
@action = map { @$_>1 ? $_->[-1] : () } @allinfo;

if($life[0] < 3 && rand() < .5 )
{
    printf "D%d", +(sort { ($life[$a]>0)*($action[$a] eq "N") <=> ($life[$b]>0)*($action[$b] eq "N") } 1..3)[2]
}
else
{
    @score = map { $life[$_]>0 ? (5/$life[$_] + 2*($action[$_] =~ /S./)) : 0 } 1..3;
    printf "S%d", +(sort { $score[$a] <=> $score[$b] } 1..3);
}

かなり標準的なPerlコード。ファイルに保存してから実行しperl file argument argument [...]ます。構文を確認しましたが、問題ありませんでしたので、問題ないことを望みます。

E:0除算エラーの可能性を排除しました。


3

ボンバーマン

Rで書かれたボット、コマンドラインは次のようになります:Rscript Bomberman.R arg0 arg1
このボットを書き始めた後、Geobitsはすでにg弾兵を作っていることに気づきましたが、手significantly弾を準備する前に健康が3以上であることを確認して、最後の射手が最初に、そして最も健康的な2番目に、その体力が3未満の場合、危険なプレイヤー(最終ラウンドで死者でも射手でもない)をかわすか、残りのプレイヤーの1人を撃ちます。

input <- commandArgs(TRUE)
history <- do.call(rbind,strsplit(scan(textConnection(input[2]),"",quiet=TRUE),","))
health <- as.integer(history[,1])
last_shooter <- which(grepl("S",history[-1,ncol(history)]))
last_prepare <- which(history[1,]=="P")
if(!length(last_prepare)) last_prepare <- -1
last_throw <- which(grepl("T",history[1,]))
if(!length(last_throw)) last_throw <- 0
most_healthy <- which.max(health[-1])
dead <- which(health[-1]<=0)
inoffensive <- c(last_shooter,dead)
danger <- which(!(1:3)%in%inoffensive)
alive <- which(!(1:3)%in%dead)
if(health[1]>3 & last_throw > last_prepare) out <- "P"
if(last_throw < last_prepare) out <- ifelse(length(last_shooter),paste("T",last_shooter[1],sep=""),paste("T",most_healthy[1],sep=""))
if(health[1]<=3 & last_throw > last_prepare){
    if(length(danger)){
        out <- paste("D",sample(danger,1),sep="")
    }else{
        out <- paste("S",sample(alive,1),sep="")
    }
}
cat(out)

編集

私が見たすべてのログは私のボットのみが出力することを示したので、このボットとあなたのコントローラーの間に何らかの通信上の問題があるようNです。そのため、同じボットがPythonで書き直されました。このボットにも通信の問題がある場合、誰かがそれを見ることができるように。
で呼び出されpython Bomberman.py arg0 arg1ます。

import sys,re,random

history = sys.argv[2]
history = [k.split(",") for k in history.split()]
health = [k[0] for k in history]
last_turn = [k[-1] for k in history]
last_shooter = [i for i,x in enumerate(last_turn) if re.search(r'S[0-3]',x)]
last_prepare = [i for i,x in enumerate(history[0]) if x=='P']
if not len(last_prepare):
    last_prepare = [-1]

last_throw = [i for i,x in enumerate(history[0]) if re.search(r'T[0-3]',x)]
if not len(last_throw):
    last_throw = [0]

most_healthy = [i for i,x in enumerate(health) if x==max(health)]
dead = [i for i,x in enumerate(health) if x<=0]
inoffensive = last_shooter+dead
danger = [k for k in range(1,4) if k not in inoffensive]
alive = [k for k in range(1,4) if k not in dead]
if health[0]>3 and last_throw[-1] > last_prepare[-1]:
    out = 'P'

if last_throw[-1] < last_prepare[-1]:
    if len(last_shooter):
        out = 'T'+random.choice(last_shooter)
    else:
        out = 'T'+random.choice(most_healthy)

if health[0]<=3 and last_throw[-1] > last_prepare[-1]:
    if len(danger):
        out = 'D'+random.choice(danger)
    else:
        out = 'S'+random.choice(alive)

print(out)

ボットの名前は比較的弱いですが、私はアイデアを使い果たしました。誰かがより良い名前を考えることができるなら、コメントしてください:)
plannapus 14

GymnastBomber !!
ランチャー

3

ネオ

前のターンに撃たなかった生きているプレイヤーをかわす。全員が最後のターンに撃った場合、ランダムに生きているプレイヤーを撃ちます ヘッドライトを見ると自殺します。

import java.util.Random;
public class Neo {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;
        Random rand = new Random();
        int turn = list[0].split(",").length;
        if(turn == 49){
            System.out.print("S0");
            return;
        }
        int target=0;
        for(int i=1;i<4;i++)
            if(list[i].length()<2 || (list[i].charAt(0)!='-' && list[i].charAt(list[i].length()-2)!='S'))
                target=i;
        if(target>0){
            System.out.print("D"+target);
            return;
        }
        while(target<1){
            int i=rand.nextInt(3)+1;
            if(list[i].charAt(0)!='-')
                target=i;
        }
        System.out.print("S"+target);
    }
}

私はこの男に手ch弾を投げる人に対してはあまり期待していませんが、射手に対してはかなりうまくいくかもしれません。表示されます。


私は私の答えであなたの定型コードのいくつかを使用しました。大丈夫だと思います。
オーバーアクター14

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.charAt(String.java:658) at Neo.main(Neo.java:17)
es1024 14

@ es1024これでいいので、最初のすべてのターンで何もしません。
ジオビット14

2

二十四世紀半

このPythonエントリは、パッシブプレイヤーまたはアグレッシブプレイヤーが1人だけ残るまでダックアンドダッジし、シュートを開始します。通過する火星人がg弾兵と酔っぱらったトラック運転手の世話をすることを望んでいます。

何か間違ったことをしていない限り、これは機能的なPythonです。確かに、Haskellや友人が私を見つける前に書いたようなPythonのようには見えませんし、何かを変更したとは思いません。しかし、あなたがよく知っているなら、教えてください。

#!/usr/bin/env python
import sys
import random

## ==== Move Types ================================================== ##
def move_type (move):
    if "" == move:
        return "N"
    return move[0]

def is_passive_move (move):
    if "N" == move:
        return True
    if "D" == move_type (move):
        return True
    return False

def is_aggressive_move (move):
    return not is_passive_move (move)

def passive_moves (moves):
    return [m for m in moves if is_passive_move (m)]

def aggressive_moves (moves):
    return [m for m in moves if is_aggressive_move (m)]
## ================================================== Move Types ==== ##

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health, moves):
        self.number = number
        self.health = health
        self.moves  = moves

    def last_move (self):
        if 0 == len (self.moves):
            return ""
        return self.moves[-1]

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())
    moves = [move.strip () for move in x[1:]]

    return Player (number, health, moves)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def can_shoot (player):
    return "S" != move_type (player.last_move ())

def is_passive (player):
    passive_move_count = len (passive_moves (player.moves))
    aggressive_move_count = len (aggressive_moves (player.moves))

    return passive_move_count > (aggressive_move_count + 1)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_who_can_shoot (players):
    return [p for p in players if can_shoot (p)]

def players_who_stand_around (players):
    return [p for p in players if is_passive (p)]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def dodge_one_of_the (potential_shooters):
    chosen_shooter = random.choice (potential_shooters)
    return "D{0}".format (chosen_shooter.number)

def do_nothing ():
    return "N"

def pick_move (game_state):

    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    living_enemies = players_who_can_breathe (enemies)
    if 1 == len (living_enemies):
        return shoot_randomly_at (living_enemies)

    passive_enemies = players_who_stand_around (living_enemies)
    if len (living_enemies) == len (passive_enemies):
        return shoot_randomly_at (passive_enemies)

    potential_shooters = players_who_can_shoot (living_enemies)
    if 0 < len (potential_shooters):
        return dodge_one_of_the (potential_shooters)

    return do_nothing ()
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

として実行:

python twenty-fourth-and-a-halfth-century.py 0 "5 5 5 5"

2

怖い

この投稿は誰もが怖いです。しかし、特に一部の人々は怖いです。だから、誰が最も危険なのかを把握し、それらを撃ちます。複数の敵が最も危険に見える場合、それはランダムに撃ちます。

import sys
import random


def is_alive(player):
    return int(player.split(",")[0]) > 0


# Anyone with a live grenade who is alive is dangerous
def is_dangerous(player):
    return player.count("P") > player.count("T") and \
        int(player.split(",")[0]) > 0


def health(player):
    return int(player.split(",")[0])


# Failing that, healthy people are dangerous
def danger_rating(player):
    return 6 if is_dangerous(player) else health(player)

enemies = sys.argv[2].split()[1:]

highest_danger = max(danger_rating(enemy) for enemy in enemies)
most_dangerous_enemy = random.choice(
    [enemy_num+1 for enemy_num in range(len(enemies))
     if danger_rating(enemies[enemy_num]) == highest_danger])

print("S"+str(most_dangerous_enemy))

これはpython(2または3、どちらでも同じ結果です)として保存scared.py、実行python3 scared.py


2

マニピュレーティブバスタード– Python

手g弾を準備して投げます。時間がない、または敵が少なすぎると考えると、彼は撃ちます。彼が一人の場合、彼は他の男を裏切りようとします。

import sys

def health(p):
    return int(p[0])

def is_alive(p):
    return health(p) > 0

def can_act(p):
    return is_alive(p) and p[-1][0] != 'S'

def can_throw(p):
    return is_alive(p) and p[-1][0] == 'P'

def shot_first(p):
    if len(p) == 1:
        return False
    return p[1][0] == 'S'

def act(a):
    print a
    sys.exit(0)

player = sys.argv[2].split()[0].split(',')
enemies = [e.split(',') for e in sys.argv[2].split()[1:]]
healthiest = sorted(enumerate(enemies, 1), key=lambda e:health(e[1]))[-1]
alive = sum(is_alive(e) for e in enemies)

if alive == 1:
    i, e = healthiest
    if health(e) <= 2 and not can_act(e):
        act('S%d' % i)
    if can_throw(player):
        act('T%d' % i)
    if can_throw(e):
        act('S%d' % i)
    if can_act(e) and shot_first(e) and len(player) < 40:
        act('D%d' % i)
    if len(player) > 45:
        act('P')
    act('S%d' % i)

if can_throw(player):
    i, e = healthiest
    act('T%d' % i)

if len(player) > 45:
    act('P')

if health(player) <= 2 or any(can_throw(e) for e in enemies) or alive == 2:
    i, e = healthiest
    act('S%d' % i)

act('P')

2

オサマ

私は1日かそこらの間これを試してきましたが、今度は投稿し、その間に他の人がどのように進化したかを見てみましょう。

module Main where

import Data.List
import Data.Ord
import System.Environment

words' "" = []
words' s = s' : words' (tail' s'')
  where
    (s', s'') = break (==',') s
    tail' (',':r) = r
    tail' r = r

nRound = length . words'

lastAction = last . words'

health :: String -> Int
health = read . head . words'

alive = (>0) . health

grenadeAge :: String -> Int
grenadeAge p | not (alive p) = 0
             | otherwise = g 0 $ tail $ words' p
  where
    g n (a:b:r) | head a == 'S' = g (if n>0 then n+2 else 0) r
    g 0 ("P":r) = g 1 r
    g n (('T':_):r) | n>0 = g 0 r
    g n (_:r) | n>0 = g (n+1) r
    g n (_:r) = g n r
    g n [] = n

prepared :: String -> Bool
prepared p = alive p && head (lastAction p) /= 'S'

nShotMe = length . filter (=="S0") . words'

getPlayer = (!!)

action players@(me:them) | not (prepared me) = "S2" -- bogus
                         | nRound me >= 49 = "S0"
                         | grenadeAge me >= 1 = 'T':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | any prepared them && nRound me > 0 = 'D':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | otherwise = 'S':(show $ maximumBy (comparing (health . getPlayer players)) l)
  where l = filter (alive . (getPlayer players)) [1..3]



main = do
  players <- fmap (words . head . tail) getArgs
  putStrLn $ action players

でコンパイルしghc -O2 osama.hs、を使用して実行し./players/Osama/osamaます。


2

スナイパー-ルア

最初のターンでランダムな人を撃ち、それから殺すことができるプレイヤーを撃ちます(2または1体力)。どちらも機能しない場合、最後にそれを撃ったプレイヤーを撃とうとします。そうでなければ、ランダムなプレイヤーを撃ちます。で実行lua Sniper.lua

turns = arg[2]
health = string.sub(turns, 1, 1)
--make random numbers random
math.randomseed(io.popen("date +%s%N"):read("*all"))
math.random(); math.random(); math.random()
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end
enemies = Split(turns, " ")
--first turn
if #enemies[1] == 1 then
  print(string.format("S%i",math.random(1,3)))
  os.exit()
end
--kills if possible
for enemy=1,3 do
  if (tonumber(string.sub(enemies[enemy + 1],1,1)) or 0) < 3 and string.sub(enemies[enemy + 1],1,1) ~= "-" then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--shoots the last person that shot at it
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],#enemies[enemy + 1]-1) == "S0" and tonumber(string.sub(enemies[enemy + 1],1,1)) > 0 then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--otherwise shoot a random alive person
local aliveEnemies = {}
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],1,1) ~= "-" then
    aliveEnemies[#aliveEnemies+1]=enemy
  end
end
print(string.format("S%i",math.random(1,#aliveEnemies)))

実際には、最初に追加の引数を使用して実行されます。例えば、lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P"argインデックスを確認する必要がある場合があります。
14

@comperendinous、ありがとう、修正済み
waylon531 14

こんにちは、@ waylon531、Luaについての質問:randomseed math.randoms "math.randomseed(os.time())math.random(); math.random(); math.random()"は、ランダム化するのに十分ではありません脚本?
AndoDaan

1
AndoDaanは、に従ってlua-users.org/wiki/MathLibraryTutorialいくつかのOS常に(同じ数の最初の時間math.randomを返す)と呼ばれています。
waylon531 14

lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberスタックトレースバック:./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
es1024 14

2

ダーウィン

適者の生存は、最も健康な人が死ぬ必要があることを意味します。

根拠

火曜日(12日)の結果のバッチを見ると、3つの明確なグループ分けがあるようです。効果的な自殺 そして役に立たないよりも悪い。生存者は、単純な射撃ベースの戦略を共有しています。他の2、3のボット(SpockCoward)は、最も健康度の低い敵をターゲットにしますが、他のアクションで戦略を複雑にします。これはしません。Simple Shooterと同様に、ターゲットの明確な定義があり、執withに固執しています。結果のどこに収まるかを見るのは面白いでしょう。

#!/usr/bin/env python

import sys
import random

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health):
        self.number = number
        self.health = health

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())

    return Player (number, health)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_by_health (players):
    return sorted (players, key=lambda p: p.health)

def least_healthy_players (players):
    sorted_living_players = \
        players_by_health (players_who_can_breathe (players))
    lowest_living_health = sorted_living_players[0].health
    return [p for p in players if lowest_living_health == p.health]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def do_nothing ():
    return "N"

def pick_move (game_state):
    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    least_healthy_enemies = least_healthy_players (enemies)
    return shoot_randomly_at (least_healthy_enemies)
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

これは、以前のTwenty-F​​ourth-fourth and a Halfth Centuryを少し修正したもので、その呼び出しを共有しています。

python darwin.py 3 "5 5 5 5"

2

ゼニール-C

優先事項:

  1. 残り1対1のシュート
  2. rena弾兵を撃つ
  3. ダッジ
  4. 何も(単に混乱させるため)

でコンパイルしgcc <filename.c>ます。

で実行し./a.out <parameters>ます。

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

int main(int argc, char *argv[]){
    char* input = argv[2];
    int enemyCount=1;
    int aliveCount=0;
    int aliveEnemy=0;

    //default
    char action = 'N';
    int target = NULL;

    const char delim[1] = " ";
    char *token;

    //first turn
    if(strcmp(input,"5 5 5 5")==0){
        printf("D1");
        return 0;
    }

    token = strtok(input, delim);
    token = strtok(NULL, delim); //skip to the first enemy

    while(token != NULL){
        //if someone is alive :
        if(strstr(token,"-")==NULL && token[0]!='0'){
            aliveCount++;
            aliveEnemy=enemyCount;
            //if that person did nothing this turn, take it as a tip that he will shoot next turn, and dodge
            if(strstr(token, "N")!=NULL){
                action = 'D';
                target=enemyCount;
            }

            //if that person prepared a grenade, shoot him down
            if(strstr(token, "P")!=NULL){
                action = 'S';
                target=enemyCount;
            }
        }

        token = strtok(NULL, delim);
        enemyCount++;
    }

    //if there is 1 enemy left, shoot him down
    if(aliveCount==1){
        action='S';
        target=aliveEnemy;
    }

    printf(action=='N'?"N":"%c%d",action,target);

    return 0;
}

1
最初の(整数)引数は、質問で与えられた例がうまくいかない場合、ラウンドカウントを示しません。あなたはスタンドオフ番号82に割り当てられていると思いますからといって最初のターンに自分自身を撮影したいとは思わないでしょう
comperendinous

本当に?D:@comperendinousに感謝します。コードを編集します。
マークガブリエル14

2

InputAnalyzer

このようなゲームの鍵は、すべての対戦相手がどのようにプレイしているかを分析し、それに応じて応答することです。私のボットは、複雑なアルゴリズムを使用して対戦相手を使用することになるので、決定的な勝利をもたらすことができます。

編集:私は今

  1. ライブグレネードを持つプレイヤーをかわす
  2. もう自分でシャウイング/スロー/ダッジを試みません。

import System.Environment   
import Data.Char (ord)
import Data.List.Split

main = do 
    args <- getArgs
    let secondArg = (last args)
    let opt = (argCount secondArg 0)
    let list = (splitOn " " secondArg)
    let enemysToCheck = [1,2,3]
    let target = (avoidShootingSelf (findTarget (last args) 0 0 0 0))
    putStrLn (decide list enemysToCheck opt target)

argCount :: String -> Int -> Int
argCount (s:str) i
    |(length str) == 0 = i `mod` 4
    | otherwise = (argCount str (i + (ord s)))

--myPseudo takes number 0-3, and a possible target and translates it to a command 
myPseudo :: Int -> Int -> String
myPseudo 0 b = "S" ++ (show b)
myPseudo 1 b = "D" ++ (show b)
myPseudo 2 b = "P"
myPseudo 3 b = "T" ++ (show b)

decide :: [String] -> [Int] -> Int -> Int -> String
decide [] [] a b = (myPseudo a b)
decide (x:xs) [] a b = (myPseudo a b)
decide xs (y:ys) a b
    | (liveGrenade z 0) == True = "D" ++ (show y)
    | otherwise = (decide xs ys a b)
    where z = xs!!y

--checks if a player has a live grenade
liveGrenade :: String -> Int -> Bool
liveGrenade [] a = a > 0
liveGrenade (s:str) a
    | s == 'T' = (liveGrenade str (a - 1))
    | s == 'P' = (liveGrenade str (a + 1))
    | otherwise = (liveGrenade str a)

--findTarget picks a target by doing some irrelevant string processing on the 2nd argument
findTarget :: String -> Int -> Int -> Int -> Int -> Int
findTarget [] a b c d = ((maximum [a,b,c,d]) `mod` 4)
findTarget (s:str) a b c d
    | s == 'S' = (findTarget str (a + 1) b c d)
    | s == 'D' = (findTarget str a (b + 1) c d)
    | s == 'P' = (findTarget str a b (c + 1) d)
    | s == 'T' = (findTarget str a b c (d + 1))
    | s == 'N' = (findTarget str a b c (d + 1))
    | otherwise = (findTarget str a b c d)

--Makes sure I do target myself takes int 0-3
avoidShootingSelf :: Int -> Int
avoidShootingSelf 0 = 1
avoidShootingSelf a = a

次のコマンドでボットをコンパイルします(ghcが必要です)

ghc --InputAnalyzer.hsを作成する

実行するシェルコマンドは次のようになります

./InputAnalyzer

注:Windowsでテストしたため、コンパイル/実行に関する問題がある場合はコメントでそう言ってください。正しいコマンドを見つけるために最善を尽くします。


1
それは、Haskellで重み付き擬似乱数ジェネレータを取得する1つの方法だと思います。
14

2

勇気という犬

最初に-目の前で悪者を撃ちます。その後、誰かが手g弾を準備するまでランダムにかわします。それから誰もが彼を撃つとき、私自身の手ren弾を準備し、誰でもそれを投げなさい。しかし、気を散らす人。

編集:思ったとおりに実装されました。以前、スコアは35.9でした。

更新:回避する代わりに時々撃つ

couragethedog.py

import sys
from collections import defaultdict as ddict
from random import choice
args = sys.argv
info = " ".join(args[2:]).strip('"').split(" ")
players = ddict(dict)
for i,s in enumerate(info):
    parts = s.split(",")
    players[i]["health"]=int(parts[0])
    players[i]["last"]=parts[-1]
    players[i]["history"]=parts[1:]
    players[i]["turn"]=len(parts)
me=0
others=[1,2,3]
turn=players[me]["turn"]
alive = filter(lambda p:players[p]["health"]>0,others)
def act():
    if turn is 1:
        return "S%d" % choice(alive)
    if "P" == players[me]["history"][-1]:
        targets = set(alive)
        for i in alive:
            if "P" == players[i]["history"][-2]:
                targets.remove(i)
        return "T%d" % choice(list(targets))
    for i in others:
        if players[i]["history"][-1] is "P":
            return "P"
    if choice([True,False,False]):
        return "S%d" % choice(alive)
    return "D%d" % choice(alive)
print act()

として実行

python couragethedog.py

2

MAD-Java

MADボットは、相互に保証された破壊による脅迫の力を信頼しています。彼は準備ができた手When弾を持っていないときはいつでも、彼はそれを準備します。誰かが彼にダメージを与えようとするか、彼の手ren弾が爆発しようとするまで、彼は可能な砲手をかわします。彼が攻撃された瞬間から、彼はこれまでにこの試合でより多くのダメージを与えようとした人に手rena弾を投げつけます。手g弾が爆発しようとしている場合、彼は主要プレイヤーを爆撃します。MADは、回避することも、手ade弾を直接チャックすることもできず、彼の手ade弾が少なくとも1ターンはまだ有効なときに誰かに打撃を与えることに反対しません。

    import java.util.ArrayList;
import java.util.Random;

public class MAD 
{
    public static void main(String[] args) 
    {
        if(args.length < 2)
        {
            return; // nothing to do here
        }
        String[] players = args[1].split(" ");
        if(players.length < 4 || !isAlive(players[0]))
        {
            return; // nothing to do here
        }
        Random rand = new Random();

        int grenadeExplodes = grenadeExplodes(players[0]);        
        if(grenadeExplodes==-1)
        {
            System.out.print("P"); // I don't feel safe without a prepared grenade in my hand
            return;
        }

        int highestDamage = -1;
        int playerToShoot = -1;        
        for(int i=1; i<4; i++) // did anyone try to hit me?
        {
            int damage = damageAttempted(players[i], 0);
            if(isAlive(players[i]) && (damage>highestDamage || (damage==highestDamage && rand.nextDouble()>0.5)))
            {
                highestDamage = damage;
                playerToShoot = i;
            }           
        }

        if(highestDamage > 0)
        {
            System.out.print("T" + Integer.toString(playerToShoot)); // don't tell me I didn't warn you
            return;
        }

        int highestHealth = -1;
        int healthiestPlayer = -1;      
        for(int i=1; i<4; i++) // who is doing too well for their own good?
        {
            int health = getHealth(players[i]);
            if(health>highestHealth || (health==highestHealth && rand.nextDouble()>0.5))
            {
                highestHealth = health;
                healthiestPlayer = i;
            }
        }

        if(grenadeExplodes==0)
        {
            System.out.print("T" + Integer.toString(healthiestPlayer).charAt(0)); // get this hot head outta here!!
            return;
        }

        // I've got time to flaunt my grenade around

        ArrayList<Integer> playersToDodge = new ArrayList<Integer>();       
        for(int i=1; i<4; i++) // lets see who could shoot me
        {
            if(canMove(players[i]) && grenadeExplodes(players[i])!=0)
            {
                playersToDodge.add(i);
                if(grenadeExplodes(players[i])==-1) // players who have no grenade are more likely to shoot
                {
                    playersToDodge.add(i);
                }
            }
        }

        if(playersToDodge.size()>0)
        {
            System.out.print("D" + Integer.toString(playersToDodge.get(rand.nextInt(playersToDodge.size() - 1))).charAt(0)); // what do we say to would-be gunners?
            return;
        }

        if(grenadeExplodes!=1)
        {
            System.out.print("S" + Integer.toString(healthiestPlayer).charAt(0)); // seems like I can take a free shot at someone
        }
        else
        {
            System.out.print("N"); // wouldn't want to end up with an exploding grenade in my hand while being unable to throw it.
        }

    }

    public static boolean isAlive(String player) 
    {
        return player.charAt(0)!='-'; 
    }

    public static boolean canMove(String player)
    {
        return isAlive(player) && player.charAt(player.length()-2)!='S';
    }

    public static int grenadeExplodes(String player)
    {
        String[] actions = player.split(",");

        if(actions.length>3 && actions[actions.length - 3].charAt(0)=='P' 
            && actions[actions.length - 2].charAt(0)=='T' 
            && actions[actions.length - 1].charAt(0)=='P')
        {
            return 0;
        } 
        else if(actions.length>2 && actions[actions.length - 2].charAt(0)=='P' 
            && actions[actions.length - 1].charAt(0)=='T')
        {
            return 1;
        } 
        else if(actions.length>1 && actions[actions.length - 1].charAt(0)=='P')
        {
            return 2;
        }
        else
        {
            return -1;
        }
    }

    public static int damageAttempted(String player, int target)
    {
        String[] actions = player.split(",");
        int damage = 0;
        char targetChar = Integer.toString(target).charAt(0);
        for(int i=0; i<actions.length; i++)
        {
            if(actions[i].charAt(0)=='S' && actions[i].charAt(1)==targetChar)
            {
                damage += 2;
            } 
            else if (actions[i].charAt(0)=='T')
            {
                if(actions[i].charAt(1)==targetChar)
                {
                    damage += 8;
                }
                else
                {
                    damage += 3;
                }
            }
        }

        return damage;
    }

    public static int getHealth(String player)
    {
        return Integer.parseInt(player.split(",")[0]);
    }
}

このボットのパフォーマンスは低下する可能性がありますが、とにかくアイデアは気に入りました。MADは、他のボットの動作をログに記録し、4つのボット間でより多くのマッチを実行する、よりスマートなボットの分野でおそらくより良い結果をもたらすでしょう。


一部のクレジットはGeobitsに送られ、彼のNeoエントリのボイラープレートコードを盗みました。
オーバーアクター14

あなたはあまりかかりませんでしたが、クレジットは必要ありませんでした:)
Geobits 14

呼び出しjava MAD 43 "5 5 5 5"は何も出力しないようです。
es1024 14

2

サディスト

python

彼の優先事項は、痛みと手rena弾を傷つけることです。彼は最初のターンを引っ張ります。彼はあなたが攻撃できないときに殺すのが好きです。彼はSSS(シングルシンプルシューター)をかわし、引っ張って支配を延長します。彼は、誰にも何もしなかった最初の人を攻撃することさえ選択しました。

彼は手rena弾を使用するため、彼(および他のすべての人)は通常、2番目または3番目のラウンドで生き残ることができません。彼が別の手ren弾とペアになっている場合、誰もが死ぬでしょう。これは私が勝つことを期待していないことを意味しますが、私はPythonを学ぶためにこれを書きました(以前は使用していなかったため、新しい言語の束を紹介しようとしています)。他にもいくつか「プルファースト」がありますので、似ていると感じたら教えてください。ただし、他の人は引っ張ってかわすことをいとわないようです。

import sys    

def ident(thatguy):

    return int(thatguy.split(",")[0])

def health(thatguy):
    return int(thatguy.split(",")[1])

def shooter(thatguy):
    if(len(thatguy.split(","))<3):
        return 1==1
    else: return thatguy.split(",")[2][0]=="S"

def mosthealth(group):
    bigbad=group[0]
    for foe in group:
        if (health(foe)>health(bigbad)): bigbad=foe
    return bigbad

def igotanuke(mine):
    return mine.count("P")-mine.count("T")>0

def guytonuke(allguys,fighters):
    backup=allguys[:]
    for Aguy in backup:
        if(health(Aguy)<4):
            allguys.remove(Aguy)
            if (shooter(Aguy)): fighters.remove(Aguy)

    if(len(allguys)==0): return mosthealth(backup)
    if (len(allguys)==len(fighters)):
        return mosthealth(allguys)
    else:
        for fighter in fighters: allguys.remove(fighter)
        return mosthealth(allguys)

raw = sys.argv[2]
player = raw.split(" ")
thisisme=player.pop(0)
turn = len(player[0].split(","))-1

guys=[]
gunners=[]
c=1
for dude in player:
    dude=str(c)+","+dude
    c+=1
    if (health(dude)>0): 
        guys.append(dude)
        if (shooter(dude)):
            gunners.append(dude)

if (turn==0): print "P"
elif(turn==49): print"S0"
elif(igotanuke(thisisme))&( turn % 2 == 1): print "T"+str(ident(guytonuke(guys,gunners)))
elif(len(guys)<2)&(len(gunners)>0) & (turn % 2 == 1): print P
elif(turn % 2 == 0) & (len(gunners)>0): print "D"+str(ident(mosthealth(gunners)))
elif(turn % 2 == 1) & (len(gunners)>0): print "S"+str(ident(mosthealth(gunners)))
else: print "S"+str(ident(mosthealth(guys)))

私はそれraw_inputがうまくいくとは思わない。sys.argv[2]Pythonエントリのコンセンサスのようです。また、を使用するとpopthisisme=player[0];player.remove(player[0])より単純なものに凝縮することができますthisisme=player.pop(0)
14

@comperendinous Ideoneでコードをテストしていましたが、sys.argvがまったく機能しません(sysのインポートが原因の可能性があります)。それがraw_inputを使用した理由です。後者が機能しない原因となる違いはありますか?もしそうなら、私はおそらくPython用の別のオンラインコンパイラを見つける必要があります。ポップの提案をありがとう!このコマンドでインデックスを指定できることを知りませんでした。今後のpythonコードに使用します。
ケイン14

1
raw_inputから取得STDINしますが、プレーヤーの履歴はコマンドライン引数としてプログラムに渡されるため、が必要sys.argvです。テストのために、を使用して手動で設定できますsys.argv = ["sadist.py", "0", "5 5 5 5"]。そうすれば、電話をかけることができるはずplayer=sys.argv[2].split()です。インポートがsys本当に不可能な場合は、テストのためにドットをドロップしてarrayを呼び出すこともできますsysargv。他のすべてが機能sys.argvし、提出に戻る限り、問題ありません。
14

@comperendinous確認するには、sys.argvを呼び出すと、0のプログラムの名前、1の単一の番号、2で使用する実際の部分を配列として返しますか?それらはすべて文字列です。その情報があれば、適切に編集できるはずです。どうもありがとうございました!
ケイン14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.