Kebuntuan Empat Orang

54

4-Man Standoff

Deskripsi

Entah bagaimana Anda menemukan diri Anda mengalami kebuntuan empat arah. Senjata yang dimuat terletak di tangan Anda, dan beberapa granat dikaitkan di sabuk Anda.

Tujuannya adalah untuk mendapatkan kesehatan terbanyak di akhir kebuntuan. Kebuntuan berakhir ketika paling banyak satu orang memiliki kesehatan yang positif.

Setiap pemain memiliki 5kesehatan, dan mati ketika kesehatan mereka turun ke / di bawah 0. Giliran pemain yang mati adalah giliran terakhir yang pemain dapat rusak.

Jika ada pemain langsung di akhir kebuntuan, pemain itu menang. Kalau tidak, pemain dengan kesehatan paling tidak negatif menang.

Tindakan

  • Tembak : Tembak seseorang.

    • 2 kerusakan jika menembak musuh yang hidup
    • 0 kerusakan jika menembak musuh yang mati
    • health_at_start_of_turn+2Kerusakan jika menembak diri sendiri. (Perhatikan bahwa ini akan membuat Anda dengan PALING -2kesehatan.)
    • Jika satu musuh menembak Anda pada giliran yang sama Anda menembak diri sendiri, Anda akan mengakhiri kebuntuan dengan -4 kesehatan (Anda masih menerima kerusakan dari pemain lain saat Anda bunuh diri).
    • Tindakan Anda, belokan berikut akan diabaikan (dan dianggap sebagai Nothing).
  • Dodge : Cobalah untuk menghindari tembakan satu lawan.

  • Siapkan : Lepaskan kait granat Anda dan bersiap untuk melemparkannya.

    • Anda hanya memiliki tiga putaran untuk melemparnya, sebelum Anda meledak ( 6kerusakan pada diri sendiri, 3kerusakan untuk semua musuh hidup)
    • Mati dengan granat yang tidak dibuang sama dengan tidak melemparkan granat selama tiga putaran.
  • Lempar : Chuck granat ke arah seseorang dan berharap yang terbaik.

    • Target menerima 8kerusakan jika hidup
    • Semua orang (termasuk Anda sendiri) menerima 3kerusakan jika hidup
  • Tidak ada : Berdirilah diam-diam untuk belokan dan saksikan semua orang mati.

Memasukkan

Program Anda akan melewati informasi berikut:

  • Kesehatan setiap pemain
  • Daftar tindakan yang dilakukan oleh pemain itu sejak awal kebuntuan Di bawah ini adalah format untuk informasi yang dilewati per pemain:

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

Tindakan akan diberikan dalam format yang ditentukan di bagian Output .

Anda akan menerima 4 string seperti itu, dipisahkan oleh spasi, dan diteruskan sebagai argumen tunggal. Urutan string ini adalah:

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

String diteruskan sebagai argumen kedua. Argumen pertama berisi bilangan bulat yang secara unik mengidentifikasi kebuntuan yang diberlakukan. Standoff antara set pemain yang sama dijamin tidak simultan. Namun, beberapa kebuntuan akan terjadi pada saat yang bersamaan.

Sebagai contoh:

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

Saat ini, pemain dan lawan kedua memiliki 3 kesehatan, lawan pertama memiliki 5 kesehatan, dan lawan ketiga memiliki -2 kesehatan dan sudah mati.

Di belokan pertama:

  • Musuh tembakan 1 pemain 2
  • Musuh 1 menyiapkan granat
  • Musuh 2 pemain tembakan
  • Musuh 3 menembak dirinya sendiri

Di belokan kedua:

  • Semua pemain tidak melakukan apa pun. (Pemain dan musuh 2 tidak dapat melakukan apa-apa karena mereka menembak pada giliran sebelumnya. Musuh 3 sudah mati: ia akan melakukannya Nothingselama sisa kebuntuan.)

Argumen kedua pada awal penyanderaan adalah: 5 5 5 5.

Keluaran

Perintah harus ditampilkan dalam format di bawah ini. Output yang tidak valid ditafsirkan sebagai 'Tidak Ada'. Perintah yang membutuhkan target harus diikuti oleh integer ( 0-3, dengan 0mewakili pemain, dan 1-3mewakili musuh 1-3).

  • S[target]: Memotret [target].
  • D[target]: Mencoba menghindari [target].
  • P: Siapkan granat.
  • T[target]: Lempar granat di [target].
  • N: Tidak melakukan apapun.

Perintah yang membutuhkan target, tetapi diberi makan target tidak antara 0dan 3atau tidak diberi makan target sepenuhnya akan dianggap target 0(pemain).

Mencetak gol

Di akhir setiap kebuntuan, pemain menerima skor yang dihitung dengan rumus berikut:

35 + health at end of standoff 

Dalam hal seorang pemain mengakhiri kebuntuan dengan kesehatan negatif, mereka akan menerima skor di bawah 35 . Poin-poin berikut juga dihargai sebagai bonus:

  • Sebagian besar kesehatan: +4 poin
  • Kesehatan terbanyak kedua: +2 poin
  • Kesehatan terbanyak ketiga: +1 poin.

Dalam kasus seri, bonus lebih rendah diberikan (jika dua orang mengikat dengan kesehatan terbanyak, keduanya diberikan +2; jika ada 3 orang dengan kesehatan terbanyak, +1, dan jika setiap orang berakhir sama, +0).

Skor akhir ditentukan dengan menghitung rata-rata semua skor individu.

Aturan / Detail

  • Urutan peristiwa dalam satu belokan adalah sebagai berikut:
    • Semua pemain melakukan aksi mereka.
    • Pemain yang memiliki 0 atau kurang kesehatan mati.
    • Granat yang tidak dilempar yang perlu meledak, akan meledak (pemain yang baru meninggal masih terluka, karena ini masih giliran mereka yang mati).
  • Tidak ada kolaborasi antar entri.
  • Tiga * kebuntuan akan terjadi antara setiap set dengan 4 pemain. (Urutan pemain dapat bervariasi dengan setiap kebuntuan).
  • Entri yang mengonsumsi terlalu banyak ruang disk akan didiskualifikasi.
  • Membaca dari atau memodifikasi file selain dari entri Anda akan mendiskualifikasi entri Anda.
  • Sebuah truk, yang dikemudikan oleh seorang pemabuk, akan menabrak semua pemain yang hidup setelah 50thbelokan, jika kebuntuan belum berakhir pada akhir 50thbelokan.
    • Truk ini memberikan 20 kerusakan pada semua pemain live.
  • Kebuntuan terjadi dengan cepat. Program terputus setelah 1 detik.
  • Program Anda akan dipanggil setiap belokan, bahkan setelah Anda mati.
  • Anda dapat membaca atau menulis file hanya ke direktori Anda (jika entri Anda bernama JohnDoe, Anda dapat menyimpan file di direktori pemain / JohnDoe /); namun, ini TIDAK akan menjadi direktori saat ini saat skrip Anda sedang berjalan.
  • Kebuntuan akan terjadi pada mesin yang menjalankan Arch Linux (Rilis 2014.08.01).

Pengontrol tersedia di GitHub .

Harap sertakan yang berikut ini di pos Anda:

  • Nama untuk bot Anda
  • Perintah shell untuk menjalankan bot (mis. java Doe.java) Input akan dilewatkan melalui baris perintah sebagai argumen tunggal ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")
  • Kode bot Anda
  • Bagaimana bot harus dikompilasi (jika ada)
  • Bahasa (dan versi jika berlaku, terutama untuk python)

* Kontroler terlalu lama untuk enam.

Papan angka

                      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

Log: di GitHub

es1024
sumber
1
Apakah Anda memiliki satu granat, atau banyak? Bisakah Anda menyiapkan beberapa granat sekaligus?
isaacg
2
@ Bob Cukup yakin EmoWolf ditambahkan ke Standard Loopholes yang tidak lagi lucu . Meskipun entri bunuh diri mungkin tidak benar-benar melakukannya dengan sangat buruk.
es1024
3
Pelajaran untuk semua orang: Jangan minum dan mengemudi.
Mark Gabriel
8
@ es1024 Jika bunuh diri sebenarnya adalah strategi yang memungkinkan, pengiriman tipe-EmoWolf harus diizinkan. Terutama ketika tindakan yang tersedia secara eksplisit termasuk bunuh diri! Bukan "celah" sekarang, bukan? Dan bukan keuntungan yang tidak adil, yang sebenarnya sebagian besar dari celah itu. Tapi itu hanya pendapat saya.
Bob
3
Berdasarkan menjalankan controller beberapa kali sepertinya cukup berisik. Jika kontes ini pernah ditutup Anda mungkin harus menaikkan jumlah run untuk memuluskannya sedikit.
Davis Yoshida

Jawaban:

7

Pengamat

Orang ini menganalisis musuh-musuhnya. Tujuannya adalah untuk bertahan hidup sampai hanya satu lawan "agresif" yang tersisa, dan kemudian membunuh yang dalam kebuntuan epik.

Kompilasi: javac Observer.javaJalankan: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);
    }
}
CommonGuy
sumber
!player.contains("S" + id)apakah ini syarat yang diperlukan dalam fungsi "agresif"? Pemain yang ingin bunuh diri akan mati
Cruncher
22

Grenadier

Senjata dibesar-besarkan. Sebuah benar kebuntuan Scotsman berjalan seperti ini:

  • Mempersiapkan
  • Lempar musuh dengan paling sehat
  • Ulangi (jika dengan keajaiban Anda masih hidup)

Meskipun ini tampak sepele, itu mungkin bukan strategi yang mengerikan . Karena senjata dan granat keduanya memiliki siklus dua-turn, ini adalah jauh lebih efisien 1 cara untuk menangani kerusakan.

Tentu saja, jika ketiga lawan menembak saya di babak pertama itu tidak baik. Tapi tidak banyak lagi yang akan terjadi.

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

Kompilasi / jalankan dengan cara Java standar:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 catatan kaki tidak berguna

Geobit
sumber
41
hahaha the catatan kaki
haskeller bangga
Saya pikir melempar granat, dan kemudian menembak lebih efisien. Peluang Anda bertahan 4 putaran dengan strategi ini sangat rendah. Tapi 3 mungkin (ya, keduanya mengambil 2, tetapi giliran kedua untuk pemotretan adalah setelah aksi, bukan sebelumnya)
Cruncher
@Cruncher Anda mungkin benar. Eric mengatakan hal yang sama dalam obrolan. Saya mengatakan kepadanya bahwa pria saya tidak percaya pada senjata dan terlalu keras kepala untuk menggunakan logika itu, jadi dia memposting strategi itu. Namun, saya masih percaya ini lebih efisien , jika kita benar-benar berbicara kerusakan ditangani. Itu tidak berarti itu lebih efektif untuk memenangkan permainan. Bahkan jika saya mati di tikungan ketiga, granat kedua saya masih meledak. Jadi jika saya hidup sampai saat itu, itu dijamin 6+ kerusakan untuk semua orang, game over.
Geobits
@Geobits sekarang saya memikirkannya, ini mungkin lebih baik. Hal yang paling penting adalah delta antara Anda dan lawan. Ketika granat meledak, Anda mendapatkan +3 delta dengan siapa Anda melemparkannya, dan +0 dengan sisanya. Jaring +3. Penembakan. Memberi Anda delta +2 dengan siapa Anda menembak. +0 dengan sisanya. Saya pikir masalahnya adalah Anda -3 dengan orang yang sudah mati. Anda harus menembak jika ada yang mati :)
Cruncher
2
@codebreaker Tidak pernah memainkannya. Itu adalah referensi kehidupan nyata .
Geobits
16

Asimov's Rule Number 0 Bot - Python

Robot mungkin tidak membahayakan umat manusia, atau, karena tidak bertindak, memungkinkan umat manusia untuk terluka.

Cukup lurus ke depan, dia akan menyerang pemain pertama yang dilihatnya memegang granat untuk melindungi mayoritas manusia. Jika tidak ada yang menjadi ancaman bagi sebagian besar manusia, dia tidak akan melakukan apa-apa.

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

Jalankan seperti:

python rule0bot.py
William Barbosa
sumber
2
Robot Anda tidak logis. Jika pemain yang memegang granat melempar, manusia membutuhkan 8 + 3 + 3 + 3 = 17 kerusakan. Jika Anda membunuhnya dengan tembakan, manusia membutuhkan 2 + 6 + 3 + 3 + 3 = 17 kerusakan. Dalam kedua skenario, siapa pun yang memiliki granat meledak pada mereka mengambil 8 dan semua yang lain mengambil 3 (kecuali mereka sebelumnya mati). Kemanusiaan secara keseluruhan tidak terpengaruh. Saya masih menyukainya. +1: D
Geobits
4
Sebenarnya, skenario terbaik bagi umat manusia adalah berharap granat dilemparkan ke robot;)
Geobits
1
@Geobits Tidak mencoba menghentikan seseorang yang ancamannya bertentangan dengan sifat robot. Ini akan mencoba untuk menghentikan seseorang yang memegang granat untuk mencegah mayoritas (dua lainnya) terluka. Sudahkah Anda membaca saya, Robot? Logika ini didukung oleh Little Lost Robot dan The Evitable Conflict.
William Barbosa
Saya sudah membacanya, tetapi yang saya katakan adalah bahwa menembak mereka tidak berhenti di sini. Jika dia mati saat memegang granat, itu masih meledak. Tidak hanya itu, tetapi jumlah total kerusakan yang dilakukan pada umat manusia tetap sama. Anda melakukan kerusakan langsung pada manusia tanpa keuntungan bagi kemanusiaan.
Geobit
2
+1 Saya tidak setuju dengan suara Kyle Kanos dan ingin membatalkannya. Juga, Geobits salah dalam menganggap ini tidak membantu kemanusiaan. Tentu saja, umat manusia mungkin tidak keluar lebih baik dalam skenario terburuk, tetapi jika dua pemain lainnya menembakkan granat yang memegang douche maka mereka semua lebih baik untuk itu.
FreeAsInBeer
14

Han Solo - Python

Han menembak lebih dulu. Dalam hal ini, dia akan menembak lebih dulu dengan memilih target terdekat hidup-hidup.

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

Jalankan seperti:

python hansolo.py

Catatan : Ini adalah hal pertama yang pernah saya tulis dalam Python, jadi jika Anda melihat praktik buruk khusus python, beri tahu saya.

William Barbosa
sumber
1
gaya pep8 menyarankan metode Anda harusis_alive
Daenyth
4
@ WilliamBarbosa melihat pep8, ini adalah panduan gaya python yang digunakan semua orang. legacy.python.org/dev/peps/pep-0008
Daenyth
2
Selamat menjadi satu-satunya bot dengan kesehatan rata-rata lebih besar dari 0, di babak 8/11.
isaacg
6
IMO, "panduan gaya" adalah untuk penata rambut, bukan programmer.
Kyle Kanos
2
@KyleKanos Sangat menyenangkan memiliki konsistensi. Maksud saya, jika setengah pengembang proyek menggunakan kasing unta dan separuh lainnya seperti ini, hasilnya akan menjadi "blergh"
William Barbosa
12

EmoCowboy

Kenapa menunggu sampai mati? Bunuh saja dirimu sekarang. Semoga orang-orang bodoh lainnya akan meledakkan satu sama lain hingga -2.

Skor normalnya adalah -2. Terkadang -4 jika orang memutuskan untuk menembak saya dari kelelawar. Jarang lebih dari itu, yang berarti ini harus mengalahkan beberapa kiriman saat ini.

Python

print('S0')

python EmoCowboy.py

EDIT: Ini bukan lelucon, yang umumnya mengapa kiriman emo ini disukai. Ini adalah strategi yang sah. Hidup itu mematikan!

Cruncher
sumber
11

Pasif

Dia pria yang sangat besar, baru saja terjebak dengan kerumunan yang salah.

main = putStr "N"

Jalankan sebagai runghc pacifist.hs, tetapi Anda mungkin ingin mengompilasinya dengan -O3 jika efisiensi merupakan masalah.

mematikan
sumber
1
Silakan ganti namanya Luigi dan mari kita lihat apakah dia akan memenangkan sesuatu!
William Barbosa
1
@WilliamBarbosa Luigi? Apakah Anda mengatakan Luigi ?
Killmous
7
Lol seakan -O3membuat perbedaan besar.
tommeding
@tomsmeding Ini lambat di runghcsamping. Sebenarnya 10 kali lebih lambat di kotak Linux saya.
Ray
5
Itu menyiratkan adanya kekerasan, implikasi yang pasifis kita tidak siap tangani
mematikan
9

Monkey - Python (Entri pertama!)

Monyet lihat, monyet lakukan. Akan mengulangi persis tindakan terakhir yang diambil oleh pemain acak.

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

Dapat dijalankan seperti ini: "python monkey.py args" Tidak diperlukan langkah ekstra.

Elias Benevedes
sumber
2
Saya harap mereka tidak menembaki Anda! Python mendukung indeks array negatif, jadi Anda tidak perlu menghitung panjang dan mengurangi satu; gunakan saja -1secara langsung.
comperendinous
@comperendinous Katakanlah saya S3 dalam daftar mereka. Jika saya menjalankan S3, itu tidak akan menembak saya konyol. Juga, indeks -1 akan mengembalikan elemen terakhir? Jika ya, keren! Saya pasti akan menambahkannya.
Elias Benevedes
Dan jangan lupa argumen (integer) pertama. Anda harus argv[2]mendapatkan sejarah pemain.
comperendinous
Semoga saja Anda tidak cocok dengan Emo Cowboy.
codebreaker
6

Simple Shooter - Perl (bug tetap)

Bot ini menembak lawan dengan paling sehat. Ini adalah strategi yang sangat sederhana, tetapi saya pikir ini memiliki peluang yang layak untuk berhasil.

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

Ini adalah cara menjalankannya menggunakan beberapa contoh input:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
PhiNotPi
sumber
Wow. Sederhana dan pintar.
Soham Chowdhury
6

Spock, dengan Python 3.x

Kode ini lebih merupakan eksperimen meskipun (karena itu dinamai Spock karena ... dia seorang vulkanis, dan mereka cukup pandai dalam hal-hal semacam ini) tetapi tetap senang membangunnya. Alasan utama di balik semua kode ini adalah asumsi yang baik, logis, seperti Spock, akan lakukan, jika diberi aturan permainan:


Tujuan dari permainan ini adalah untuk memaksimalkan skor, yang akan dilakukan oleh semua orang yang hanya berdiri diam, yang tidak mungkin, karena truk.

  • Salah satu arahan yang harus diikuti Spock adalah mencegah truk agar tidak muncul, memastikan semua orang kecuali satu orang mati sebelum truk muncul.

Cara Spock bermain di sisa permainan dapat disimpulkan dengan kutipan terkenalnya: " Kebutuhan banyak orang lebih penting daripada kebutuhan beberapa orang ". Dengan kata lain, Spock harus memastikan bahwa paling sedikit kerusakan yang diderita, dengan membunuh mereka yang melakukannya. Bagaimana dia melakukannya:

  • Jika tidak ada pemain yang menyiapkan granat, targetkan pemain yang paling tidak sehat yang masih bermain.
  • Jika ada pemain yang menyiapkan granat, dari target itu yang paling tidak sehat.

Alasannya adalah bahwa, dengan menargetkan pemain terlemah, kami mengakhiri sumber kerusakan. Alasan di balik granat adalah bahwa mereka terlepas terlepas dan mereka melakukan lebih sedikit kerusakan jika mereka tidak dilempar.


Dan bot ini berfungsi. Saya belum menguji secara ekstensif untuk kegagalan input (jadi tolong ingatkan saya jika ada sesuatu yang salah) tapi saya yakin saya berhasil mengatasi sebagian besar kekusutan. Saya mendasarkan sebagian kecil kode dari bot HanSolo tetapi sebagian besar kode berantakan. Nikmati.

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)

Jalankan seperti:

python spock.py

2014-08-12 - Perbaikan bug minor terkait deteksi granat
2014-08-14 - Perbaikan bug minor tentang endgame, terima kasih kepada isaacg untuk menunjukkannya sebelum

Doktoro Reichard
sumber
Anda tidak diizinkan menembak lebih dari sekali setiap dua putaran. Baca spek tentang pemotretan.
isaacg
@isaacg Terima kasih atas pengingatnya (yang menjelaskan perilakunya), tetapi tampaknya ada beberapa bug laten. Misalnya dalam Spock ini harus menembak InputAnalyser karena dia punya granat hidup (bahkan jika Solo akan memiliki lebih 2 kesehatan).
Doktoro Reichard
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
player[1][1]seharusnya int(player[1][1]).
isaacg
@isaacg lagi, saya ucapkan terima kasih atas bantuannya. Saya akan melakukan ini lebih cepat tetapi saya sudah dibanjiri banyak barang. Spock pada akhirnya dibangun di atas konsep yang salah arah tentang bagaimana ini akan dimainkan, maka skor yang relatif lebih rendah ia dapatkan. Saya memang punya beberapa ide untuk bot baru, tetapi dengan begitu banyak saya sekarang harus memastikan bahwa ide utama adalah asli.
Doktoro Reichard
5

Penembak yang benar secara politis

Benar secara politis, karena tidak mendiskriminasi apa pun. Jadi itu tidak terlalu pintar.

import random

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

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

Itu ... tidak terlalu penting argumen apa yang diteruskan padanya bagaimana. python politicallycorrectgunman.py

Batalkan
sumber
Saya tidak berpikir kurung kotak seharusnya menjadi bagian dari output. Mungkin @ es1024 dapat mengkonfirmasi itu. Dan apakah Anda tahu tentang random.choice? Ini bagus untuk pilihan semacam ini.
comperendinous
tidak mungkin ada apapun sebelum aksi dan target dalam output, meskipun apapun setelahnya diabaikan
es1024
Apakah itu terlihat lebih baik @ es1024?
Undo
@ Tidak, Ya, berfungsi dengan baik sekarang
es1024
7
Tidak bisakah Anda menggunakan saja random.choice(array)?
user2357112
5

Penembak lurus

Dia adalah bagian terlatih dari kavaleri dan berbicara dalam banyak bahasa tetapi, karena berkedip, Straight Shooter hanya dapat melihat satu musuh di depannya. Menjadi kuda, dia tidak mengerti bahwa Anda harus menunggu di antara tembakan.

print('S2')

Perl, Python 2/3, Ruby: kuda ini benar-benar entri poligot.

Saya tetap menang. Saya tidak bisa kalah. Anda bisa menembak saya tetapi Anda tidak bisa membunuh saya. Mister Ed tidak peduli padaku!

Untuk jawaban yang memiliki sedikit pemikiran (dan beberapa paradigma fungsional) dimasukkan ke dalamnya, lihat Twenty-Fourth and Halfth Century .

comperendinous
sumber
5

Anti-granater

Granat itu buruk. Sangat buruk. Jadi, jika ada yang menyiapkan, yang terbaik adalah menembak mereka. Kalau tidak, kita akan jalan-jalan saja.

-- 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")
Kyle Kanos
sumber
4

Ricochet - Perl

Strategi sederhana tampaknya dilakukan dengan baik dalam tantangan ini, jadi inilah yang lain. Ini menembak pemain hidup acak. Ini memiliki fitur tambahan bunuh diri pada akhirnya untuk menghindari truk.

@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";

Jalankan seperti itu:

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

Agresor

Menarik di babak pertama, melempar lawan kesehatan tertinggi di babak 2, menembak lawan kesehatan tertinggi setelahnya.

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

Jalankan ini seperti ./agg ID "5 5 5 5".

Eric Tressler
sumber
4

Ninja

Hanya menghindari secara acak mencoba menghindari tertabrak.

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

jalankan sebagai

lua ninja.lua

Args tidak perlu, tetapi dapat ditambahkan tanpa masalah.

Kyle Kanos
sumber
2
@KyleKanos akankah Ninja menghindari tembakannya sendiri?
skeggse
2
@distilledchaos: ... ya, ya dia akan.
Kyle Kanos
4

Nama : Target Prioritas

Perintah Shell : ruby ​​PriorityTarget.rb 5 [game_state]

Bahasa : Ruby V2.1.2

Deskripsi : PriorityTarget mencoba menemukan gaya permainan umum. Ia kemudian memutuskan, berdasarkan pada gaya permainan itu, siapa yang ingin diserang dan senjata apa yang digunakan.

Catatan : Pengiriman Golf Kode Pertama! Jauh lebih besar daripada kiriman lainnya karena saya menjadi sedikit gila.

#!/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 [email protected]_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
fingerco
sumber
1
Saya suka pendekatan Anda, saya berharap untuk melihat bagaimana itu akan dilakukan.
overactor
Sayangnya, tampaknya ada bug di dalamnya yang menciptakan Grenadier. Ah, akan lebih baik lain kali :)
fingerco
3

Pengecut - Perl

Bertindak sangat pengecut. Ketika dia merasa sehat, dia memilih musuh yang tidak merasakannya dan menembaknya. Poin bonus untuk musuh-musuh yang menembakkan belokan terakhir (karena mereka diketahui melakukan Nothingbelokan ini dan karenanya sama sekali tidak berdaya). Ketika dia merasa tidak begitu baik, dia berlari mencari perlindungan untuk menyelamatkan kulitnya, kadang-kadang menembak seseorang.

#!/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);
}

Kode Perl standar yang cantik; simpan di beberapa file lalu jalankan perl file argument argument [...]. Saya telah memeriksa sintaks dan tidak masalah, jadi saya harap tidak ada masalah dengan ini.

E: menghilangkan potensi pembagian dengan kesalahan 0.

Ramillies
sumber
3

Pembom

Bot ditulis dalam R, baris perintah harus: Rscript Bomberman.R arg0 arg1
Saya sadar setelah mulai menulis bot ini yang Geobits sudah membuat grenadier tapi saya pikir saya secara signifikan berbeda, dalam hal ini memeriksa kesehatan adalah di atas 3 sebelum menyiapkan granat, melemparkannya di penembak terakhir pertama, dan yang paling sehat kedua, dan jika kesehatannya di bawah 3 itu akan menghindari pemain berbahaya (tidak mati atau penembak di babak terakhir) atau menembak salah satu pemain yang tersisa.

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)

Sunting

Tampaknya ada beberapa masalah komunikasi antara bot ini dan pengontrol Anda karena semua log yang saya lihat menunjukkan bahwa bot saya hanya menghasilkan N. Jadi, ini bot yang sama tetapi ditulis ulang dengan Python, dengan harapan bahwa jika bot ini juga memiliki masalah komunikasi, seseorang akan melihatnya.
Untuk dipanggil dengan 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
sumber
Nama bot ini relatif lemah, tetapi saya kehabisan ide, jika ada yang bisa memikirkan nama yang lebih baik, silakan komentar :)
plannapus
GymnastBomber !!
Cruncher
3

Neo

Dodge pemain hidup yang tidak menembak giliran terakhir. Jika semua orang menembakkan giliran terakhir, tembak pemain yang hidup secara acak. Bunuh diri saat melihat lampu depan.

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

Saya tidak berharap banyak dari orang ini terhadap granat-chuckers, tetapi melawan penembak itu mungkin bekerja dengan cukup baik. Kita lihat saja nanti.

Geobit
sumber
Saya menggunakan beberapa kode boilerplate Anda dalam jawaban saya . Saya harap tidak apa-apa.
overactor
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
@ es1024 Harusnya baik untuk pergi sekarang, dan tidak akan melakukan apa-apa di setiap belokan pertama.
Geobits
2

Abad Dua Puluh Empat dan Setengah

Entri Python ini menghindari dan menghindari sampai hanya pemain pasif atau satu pemain agresif tetap, kemudian mulai menembak. Ia berharap seorang warga Mars yang lewat merawat para granat dan pengemudi truk yang mabuk.

Kecuali saya telah melakukan sesuatu yang salah, ini adalah Python fungsional. Jelas tidak seperti jenis Python yang saya tulis sebelum Haskell dan teman-teman menemukan saya, dan saya tidak berpikir saya telah mengubah apa pun di tempatnya. Tetapi jika Anda lebih tahu, tolong beri tahu saya.

#!/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))

Jalankan sebagai:

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

Takut

Kiriman ini takut semua orang. Tapi ini terutama membuat takut sebagian orang. Jadi dia tahu siapa yang paling berbahaya, dan menembak mereka. Jika beberapa musuh terlihat paling berbahaya, ia menembak secara acak.

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

Ini adalah python (2 atau 3, hasil yang sama di kedua.) Simpan sebagai scared.py, jalankan denganpython3 scared.py

isaacg
sumber
2

Bajingan Manipulatif - Python

Mempersiapkan dan melempar granat. Jika dia pikir tidak ada waktu atau ada terlalu sedikit musuh, dia menembak. Jika dia sendirian, dia mencoba mengakali pria lain.

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')
fhyqrkka
sumber
2

Osama

Saya sudah mencoba ini selama satu hari atau lebih, sekarang saatnya untuk memposting dan melihat bagaimana yang lain telah berevolusi sementara itu.

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

Kompilasi dengan ghc -O2 osama.hs, lalu jalankan menggunakan ./players/Osama/osama.

TheSpanishInquisition
sumber
2

Sniper - Lua

Pada belokan pertama ia akan menembak orang secara acak, lalu akan menembak pemain mana pun yang dapat membunuh (2 atau 1 kesehatan). Jika tidak ada yang berhasil, ia akan mencoba menembak pemain yang menembaknya terakhir, jika tidak maka akan menembak pemain acak. Jalankan denganlua 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)))
waylon531
sumber
Ini sebenarnya akan dijalankan dengan argumen ekstra terlebih dahulu; misalnya lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P",. Anda mungkin perlu memeriksa argindeks Anda .
comperendinous
@comperendinous, terima kasih, perbaiki sekarang
waylon531
Hai, @ waylon531, pertanyaan tentang Lua: the randomseed math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" tidak cukup untuk mengacak naskah?
AndoDaan
1
AndoDaan, menurut lua-users.org/wiki/MathLibraryTutorial beberapa OS selalu mengembalikan nomor yang sama dengan saat pertama kali math.random () dipanggil.
waylon531
lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberstack traceback:./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
es1024
2

Darwin

Kelangsungan hidup yang terkuat berarti yang paling tidak sehat harus mati.

Alasan

Melihat kumpulan hasil dari Selasa (12), tampaknya ada tiga pengelompokan yang berbeda: selamat; bunuh diri yang efektif; dan lebih buruk dari tidak berguna. Para penyintas berbagi strategi sederhana berdasarkan penembakan. Sementara beberapa bot lainnya ( Spock , Coward ) akan menargetkan musuh yang paling tidak sehat, mereka juga mempersulit strategi mereka dengan tindakan lain. Yang ini tidak. Seperti Simple Shooter , ia memiliki definisi yang jelas tentang target dan tetap menggunakannya tanpa henti. Akan menarik untuk melihat di mana itu cocok dengan hasilnya.

#!/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))

Ini adalah versi stripped-down, sedikit dimodifikasi dari Twenty-Fourth and Halfth Century saya yang sebelumnya , dan membagikan doanya :

python darwin.py 3 "5 5 5 5"
comperendinous
sumber
2

Zaenille - C

Prioritas:

  1. Tembak jika sisa 1 lawan 1
  2. Tembak granat
  3. Menghindari
  4. Tidak ada (hanya untuk membingungkan)

Kompilasi dengan gcc <filename.c>.

Jalankan dengan ./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;
}
Mark Gabriel
sumber
1
Argumen (bilangan bulat) pertama tidak menunjukkan jumlah bulat, jika contoh yang diberikan dalam pertanyaan adalah apa saja. Anda tidak ingin menembak diri sendiri pada belokan pertama hanya karena Anda telah ditugaskan ke nomor kebuntuan 82.
comperendinous
Benarkah? D: Terima kasih @comperendinous. Akan mengedit kode.
Mark Gabriel
2

InputAnalyzer

Kunci permainan seperti ini adalah menganalisis bagaimana semua lawan Anda bermain untuk merespons sesuai. Bot saya akan melakukan hal itu dengan menggunakan algoritma yang rumit yang akan menghasilkan penggunaan lawan saya berubah menjadi keuntungan saya memberikan kemenangan yang menentukan!

Sunting: Saya sekarang

  1. hindari setiap pemain yang memiliki granat hidup
  2. tidak akan lagi berusaha untuk shoow / melempar / menghindar diriku.

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

Kompilasi bot dengan perintah berikut (Perlu memiliki ghc)

ghc --membuat InputAnalyzer.hs

Perintah Shell untuk dijalankan harus sebagai berikut

./InputAnalyzer

Catatan: Saya menguji pada windows jadi jika Anda memiliki masalah tentang compling / running silakan katakan demikian dalam komentar di dan saya akan melakukan yang terbaik untuk mengetahui perintah yang benar.

Sahar Rabinoviz
sumber
1
Yah, saya kira itu salah satu cara untuk mendapatkan generator pseudorandom terbobot di Haskell.
comperendinous
2

Anjing bernama Keberanian

Hal pertama - tembak orang jahat saat melihatnya. Kemudian menghindar secara acak sampai seseorang menyiapkan granat. Lalu ketika semua orang menembaknya, siapkan granat saya sendiri dan lemparkan ke siapa pun. Tapi pria pengalih perhatian.

Sunting: Sekarang diimplementasikan seperti yang saya pikir seharusnya. Sebelumnya, skornya adalah: 35,9

Dimutakhirkan: Terkadang menembak bukannya menghindar

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

Jalankan sebagai

python couragethedog.py
loa_in_
sumber
2

MAD - Jawa

Bot MAD percaya pada kekuatan intimidasi melalui penghancuran yang saling meyakinkan . Setiap kali dia tidak memiliki granat siap, dia menyiapkan satu. Dia kemudian menghindari kemungkinan penembak sampai seseorang mencoba untuk memberikan kerusakan padanya atau granatnya akan meledak. Dari saat dia diserang, dia melemparkan granat ke siapa pun yang telah mencoba memberikan lebih banyak kerusakan padanya pertandingan ini sejauh ini. Jika granatnya akan meledak, dia mengebom pemain terkemuka. MAD tidak menentang menembaki seseorang ketika tidak ada yang bisa dihindari atau langsung melemparkan granat dan granatnya masih bagus untuk setidaknya satu putaran.

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

Bot ini kemungkinan akan berkinerja buruk, tetapi saya tetap menyukai gagasan itu. MAD mungkin akan melakukan yang lebih baik dalam bidang dengan bot yang lebih pintar yang mencatat perilaku bot lain dan dengan lebih banyak pertandingan yang berjalan antara 4 bot.

overactor
sumber
Beberapa kredit harus masuk ke Geobits, saya mencuri beberapa kode plat boiler dari entri Neo-nya.
overactor
Anda tidak mengambil banyak, tidak perlu kredit :)
Geobits
Panggilan java MAD 43 "5 5 5 5"tampaknya tidak menghasilkan apa-apa.
es1024
2

Sadis

ular sanca

Prioritasnya adalah menyebabkan rasa sakit dan granat terluka. Dia menarik belokan pertama. Dia suka membunuh ketika kamu tidak bisa menyerang. Dia bermain-main dengan SSS (penembak tunggal sederhana) dengan menghindari dan menarik untuk memperpanjang dominasi. Dia bahkan memilih untuk menyerang orang-orang pertama yang tidak melakukan apa pun pada siapa pun.

Karena dia menggunakan granat, dia (dan orang lain) tidak akan selamat dari putaran kedua atau ketiga. Jika dia dipasangkan dengan granat lain, semua orang akan mati. Ini berarti saya tidak berharap untuk menang, tetapi saya menulis ini untuk belajar python (tidak pernah menggunakannya sebelumnya dan saya mencoba untuk mendapatkan pengantar ke sekelompok bahasa baru). Ada beberapa yang lain, "tarik dulu" jadi jika Anda merasa itu terlalu mirip, beri tahu saya. Yang lain tampaknya tidak mau menarik dan kemudian menghindar.

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)))
kaine
sumber
Saya tidak berpikir itu raw_inputakan berhasil. sys.argv[2]tampaknya menjadi konsensus untuk entri Python. Anda mungkin juga menemukan gunanya pop, yang akan memungkinkan Anda untuk mengembun thisisme=player[0];player.remove(player[0])menjadi lebih sederhana thisisme=player.pop(0).
comperendinous
@comperendinous Saya sedang menguji kode di Ideone dan sys.argv tidak bekerja sama sekali (kemungkinan karena mengimpor sys). Itu sebabnya saya menggunakan raw_input. Apakah ada perbedaan yang akan menyebabkan yang terakhir tidak berfungsi? Jika demikian, saya kemungkinan akan perlu menemukan kompiler online lain untuk python. Terima kasih atas sarannya dengan pop! Saya tidak menyadari bahwa perintah memungkinkan indeks untuk ditentukan. Saya akan menggunakannya untuk kode python di masa depan.
kaine
1
raw_inputmenarik dari STDIN, tetapi sejarah pemain diteruskan ke program Anda sebagai argumen baris perintah, itulah sebabnya Anda perlu sys.argv. Demi pengujian, Anda bisa mengaturnya secara manual sys.argv = ["sadist.py", "0", "5 5 5 5"]. Maka Anda harus bisa menelepon player=sys.argv[2].split(). Jika mengimpor sysbenar-benar tidak mungkin, untuk pengujian Anda bahkan dapat menjatuhkan titik dan memanggil array sysargv. Selama semuanya berjalan dan Anda kembali ke sys.argvkiriman Anda, itu akan baik-baik saja.
comperendinous
@comperendinous untuk mengkonfirmasi, jika saya memanggil sys.argv itu akan kembali sebagai array nama program dalam 0, nomor tunggal dalam 1 dan bagian yang sebenarnya saya gunakan dalam 2? Mereka semua adalah dawai. Dengan info itu saya harus dapat mengeditnya dengan benar. Terima kasih banyak!
kaine