Dört Adam Standoff


54

4-Man Standoff

Açıklama

Her nasılsa kendini dört yönlü bir zıtlıkta buldun. Dolu bir silah senin ellerinde duruyor ve bazı el bombaları kemerine bağlı.

Amaç, bir soğukluğun sonunda en fazla sağlığa sahip olmaktır. En fazla bir kişinin sağlık durumu pozitif olduğunda, uzaklaşma sona erer.

Her oyuncunun 5sağlığı vardır ve sağlıkları altına düştüğünde ölür 0. Bir oyuncunun öldüğü sıra, oyuncunun hasar alabileceği son sıradır.

Bir soğukluğun sonunda canlı bir oyuncu varsa, o oyuncu kazanır. Aksi takdirde, sağlığı en düşük negatif olan oyuncu kazanır.

Eylemler

  • Vur : Birine ateş edin.

    • 2 canlı bir düşman vurulduğunda hasar
    • 0 Ölü bir düşman vurduğunda hasar
    • health_at_start_of_turn+2Kendini çekiyorsan zarar. (Bunun sizi en iyi -2sağlıkta bırakacağını unutmayın .)
    • Eğer bir düşman size aynı vuruşta vurursa, kendinizi vurursanız, soğukluğu -4 sağlık ile sonlandırırsınız (kendinizi öldürdüğünüzde diğer oyunculara zarar verirsiniz).
    • Eyleminiz, aşağıdaki dönüş göz ardı edilecektir (ve olduğu varsayılmaktadır Nothing).
  • Dodge : atlatmak için tek rakibin şut deneyin.

  • Hazırlanın : El bombanızı çıkarın ve atmaya hazırlanın.

    • Havaya uçmadan önce atmak için sadece üç sıranız var ( 6kendinize 3hasar, tüm canlı düşmanlara hasar)
    • Açılmamış bir el bombası ile ölmek, el bombasını üç tur atmamaya eşdeğerdir.
  • Atmak : Birine doğru el bombası Chuck ve en iyisini umuyoruz.

    • Hedef 8hayatta kalırsa hasar alır
    • 3Hayatta kalan herkes (kendin dahil) zarar alır
  • Hiçbir şey : Bir dönüş için boş durun ve herkesin ölümünü izleyin.

Giriş

Programınız aşağıdaki bilgilerden geçirilecektir:

  • Her oyuncunun sağlığı
  • Bu oyuncu tarafından soğukluğun başlamasından bu yana yapılan işlemlerin bir listesi Aşağıda, oyuncu başına geçen bilgilerin formatı verilmiştir:

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

Eylemler Çıktı bölümünde belirtilen formatta verilecektir .

Bu gibi 4 dizgiyi bir boşlukla ayıracak ve tek bir argüman olarak geçireceksiniz. Bu dizgelerin sırası:

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

Dizeler ikinci argüman olarak iletilir. İlk argüman, çıkarılmakta olan soğukluğu benzersiz bir şekilde tanımlayan bir tam sayı içerir. Aynı oyuncu grubu arasındaki zıtlığın eşzamanlı olmaması garanti edilir. Bununla birlikte, aynı anda birden fazla zıtlaşma meydana gelecektir .

Örneğin:

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

Şu anda, oyuncu ve ikinci rakip 3 sağlık, ilk rakip 5 sağlık ve üçüncü rakip -2 sağlık ve öldü.

İlk sırada:

  • Oyuncu 1 düşman 2 vurdu
  • Düşman 1 bir el bombası hazırladı
  • Düşman 2 atış oyuncusu
  • Düşman 3 kendini vurdu

İkinci sırada:

  • Tüm oyuncular hiçbir şey yapmadı. (Oyuncu ve düşman 2, önceki turnuvada vurdukları için hiçbir şey yapamaz. Düşman 3 öldü: Nothinggeri kalan kısmı için yapacak .)

Bir soğukluk başında ikinci argümanı: 5 5 5 5.

Çıktı

Bir komut aşağıda listelenen biçimde verilmelidir. Geçersiz bir çıktı 'Hiçbir şey' olarak yorumlanır. Bir hedef gerektiren bir komut (bir tamsayı ile takip edilmelidir 0-3ile 0oyuncu temsil ve 1-3düşman 1-3 temsil eder).

  • S[target]: [Hedef] vuruyor.
  • D[target]: [Hedef] atlatmaya çalışır.
  • P: Bir el bombası hazırlayın.
  • T[target]: El bombasını [hedefe] at.
  • N: Hiçbir şey yapma.

Bir hedefe ihtiyaç duyan, ancak bir hedef arasında olmayan 0ve 3tamamen beslenmeyen bir hedefe beslenen bir komut, tamamen hedef 0(oyuncu) olarak kabul edilir .

puanlama

Her bölümün sonunda, oyuncular aşağıdaki formüle göre hesaplanan bir puan alırlar:

35 + health at end of standoff 

Bir oyuncu negatif sağlığı ile yaşanan soğukluğa biter durumda, olacak bir skor almak 35 altında . Aşağıdaki noktalar da bonus olarak ödüllendirilir:

  • En sağlık: +4 puan
  • İkinci sağlık: +2 puan
  • Üçüncü sağlık: +1 puan.

Beraberlik durumunda, alt bonus verilir (eğer en fazla sağlığa sahip iki kişiyle bağlanırsa, her ikisine de +2 verilir; en fazla sağlığı olan 3 kişi varsa, +1 ve herkes eşit şekilde biterse, +0).

Nihai puan, tüm bireysel puanların ortalaması hesaplanarak belirlenir.

Kurallar / Detaylar

  • Bir dönüş içindeki olayların sırası aşağıdaki gibidir:
    • Tüm oyuncular kendi eylemlerini yapar.
    • 0 veya daha az sağlığı olan oyuncular ölür.
    • Patlaması gereken kardeşi el bombaları patlayacak (yeni ölen oyuncular hâlâ incindi, çünkü bu hala öldükleri sıra).
  • Girişler arasında işbirliği yok.
  • Her 4 oyuncu grubu arasında üç * zıtlaşma olacaktır. (Oyuncuların sıralaması her soğukluk ile değişebilir).
  • Aşırı miktarda bellek alanı kullanan girdiler diskalifiye edilir.
  • Girişiniz dışındaki dosyalardan okumak veya bunları değiştirmek girişinizi diskalifiye edecektir.
  • Bir sarhoş tarafından sürülen bir kamyonet, maç 50thsonunda henüz sona ermediyse, tüm oyuncuların üzerinden geçecek 50th.
    • Bu kamyon , tüm canlı oyunculara 20 hasar verir.
  • Standoff'lar çabuk oluyor. Programlar 1 saniye sonra kesilir.
  • Programınız, öldükten sonra bile, her fırsatta çağrılacak.
  • Dosyaları yalnızca dizine okuyabilir veya yazabilirsiniz (girişiniz JohnDoe olarak adlandırılmışsa, dosyaları player / JohnDoe / dizinine kaydedebilirsiniz); Ancak, bu komut dosyası çalışırken bu geçerli dizin olmayacak.
  • Zayıflıklar, Arch Linux çalıştıran bir makinede gerçekleşecek (Sürüm 2014.08.01).

Kontrolör GitHub'da mevcuttur .

Lütfen yazınıza aşağıdakileri ekleyin:

  • Botunuz için bir isim
  • Botu çalıştırmak için bir kabuk komutu (örn. java Doe.java) Giriş, komut satırından tek bir argüman olarak geçirilir ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N").
  • Botunuzun kodu
  • Botun nasıl derlenmesi gerektiği (eğer varsa)
  • Dil (ve eğer varsa, özellikle python için)

* Kontrolör altı için çok uzun sürüyor.

sayı tahtası

                      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

Günlükleri: GitHub'da


1
Tam olarak bir el bombanız var mı, yoksa çok var mı? Bir seferde birden fazla el bombası hazırlayabilir misiniz?
isaacg,

2
@Bob EmoWolf'un artık komik olmayan Standart Loopholes'a eklendi . Her ne kadar intihar girişleri gerçekte böyle bir şey yapamaz
es1024

3
Herkese ders: İçmeyin ve araba sürmeyin.
Mark Gabriel

8
@ es1024 İntiharın gerçekten uygulanabilir bir strateji olduğu yerlerde, bir EmoWolf tipi başvuruya gerçekten izin verilmelidir. Özellikle mevcut eylemler açıkça intiharı içerdiğinde! Artık pek bir "kaçamak" değil, değil mi? Ve bu boşlukların çoğunun gerçekte olduğu haksız bir avantaj değil. Ama bu sadece benim düşüncem.
Bob

3
Kontrolörün birkaç kez çalıştırılmasına bağlı olarak oldukça gürültülü görünüyor. Eğer bu yarışma kapanırsa, biraz pürüzsüz hale getirmek için muhtemelen koşu sayısını arttırmalısınız.
Davis Yoshida

Yanıtlar:


7

Gözlemci

Bu adam düşmanlarını analiz ediyor. Amaç, yalnızca bir "agresif" rakip bırakılana kadar hayatta kalmak ve sonra onu destansı bir zıtlıkta öldürmek.

Derleme: javac Observer.javaÇalıştır: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)Bu "isAggressive" işlevinde gerekli bir koşul mu? Bir intihar oyuncusu zaten ölmüş olacak
Cruncher

22

el bombası atan asker

Silahlar abartılıyor. Bir gerçek Scotsman'ın soğukluk şöyledir:

  • Hazırlamak
  • En sağlık ile düşmana at
  • Tekrarlayın (eğer bir mucize ile hala hayattasınız)

Bu önemsiz gibi görünse de, muhtemelen korkunç bir strateji değil . Silah ve el bombaları hem iki dönüş döngüsüne sahip olduğundan, bu çok daha verimli gereğidir 1 damage yolunda.

Elbette, üç rakip de beni ilk raundda vurursa, bu iyi değil. Fakat başka pek bir şey olmazdı.

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

Standart Java yolunda derleyin / çalıştırın:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 Amaçsız dipnot


41
hahaha dipnot
gururlu haskeller

Bir el bombası atmak ve daha sonra çekim daha verimli olduğunu düşünüyorum. Bu strateji ile 4 turda hayatta kalma şansınız uyuşukça düşük. Ama belki 3 (evet, ikisi de 2 alır, ancak çekim için ikinci sıra aksiyondan önce değil, önce)
Cruncher

@Cruncher Muhtemelen haklısın. Eric aynı şeyi sohbette de söyledi. Ona adamımın silahlara inanmadığını ve bu mantığı kullanamayacak kadar inatçı olduğunu söyledim, bu yüzden o stratejiyi yayınladı. Ancak, kesin olarak verilen hasardan söz edersek , bunun hala daha verimli olacağına inanıyorum . Bu , oyunu kazanmanın daha etkili olduğu anlamına gelmez . Üçüncü dönüşte ölsem bile, ikinci el bombam hala sönüyor. Yani o zamana kadar yaşarsam, bu herkese 6+ hasar verir, oyun biter.
Geobits

@ George artık bunu düşündüğüm için, bu daha iyi olabilir. En önemli şey, sen ve rakipler arasındaki delta. El bombası patladığında, kime attığınla +3 delta, gerisi ile de +0 kazanırsın. +3 net. Çekim. Vurduğunuzla birlikte +2 delta kazanır. Geri kalanıyla +0. Sanırım sorun şu ki, siz zaten -3 ölü insanlarla. Eğer biri ölmüşse ateş etmelisiniz :)
Cruncher

2
@codebreaker Hiç çalmadım. Bu bir var gerçek hayat referansı.
Geobits,

16

Asimov'un Kural Numarası 0 Bot - Python

Bir robot insanlığa zarar vermeyebilir veya harekete geçmediğinde insanlığın zarar görmesine izin vermeyebilir.

Oldukça dümdüz, insanların çoğunluğunu korumak için el bombası tuttuğunu gördüğü ilk oyuncuya saldıracak. Hiç kimse insanların çoğunluğu için bir tehdit değilse, hiçbir şey yapmaz.

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

Gibi koş:

python rule0bot.py

2
Robotunuz mantıksız. El bombası tutan oyuncu atarsa, insanlık 8 + 3 + 3 + 3 = 17 hasar alır. Onu atışla öldürürseniz, insanlık 2 + 6 + 3 + 3 + 3 = 17 hasar alır. Her iki senaryoda da, el bombası patlayan her kimse 8 alır ve diğerleri 3 alır (daha önce ölmemişlerse). İnsanlık bir bütün olarak etkilenmez. Yine de hoşuma gitti. +1: D
Geobitler

4
Aslında, insanlık için en iyi senaryo , el bombasının robota atılmasını
ummaktır

1
@Geobits Tehdit eden birini durdurmaya çalışmamak robotların doğasına aykırıdır. Çoğunluğun (diğer ikisinin) incinmesini önlemek için bir el bombası tutan birini durdurmaya çalışacaktır. Ben okudun mu Robot? Bu mantık, Küçük Kayıp Robot ve Evitable Çatışması tarafından desteklenmektedir.
William Barbosa,

Okudum, ama demek istediğim, onları vurmanın burada bitmemesi. El bombası tutarken ölürse, hala patlar. Sadece bu değil, insanlığa verilen toplam zarar aynı kalır. İnsanlığa hiçbir zararı olmayan bir insana doğrudan zarar veriyorsunuz.
Geobits

2
+1 Kyle Kanos'un oylamasına katılmıyorum ve geçersiz kılmak istiyorum. Ayrıca, Geobits bunun insanlığa yardım etmek için hiçbir şey yapmadığını varsaymakta yanlıştır. Elbette, insanlık en kötü durum senaryosunda daha iyi bir şekilde ortaya çıkmayabilir, ancak diğer iki oyuncu el bombası perdesini çekerse o zaman hepsi daha iyi olur.
FreeAsInBeer 11:14

14

Han Solo - Python

Han önce vuruldu. Bu durumda, önce canlı olan en yakın hedefi seçerek ateş edecek.

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

Gibi koş:

python hansolo.py

Not : Bu Python'da yazdığım ilk şey, bu yüzden herhangi bir python'a özgü kötü uygulama görürseniz, lütfen bana bildirin.


1
pep8 tarzı yöntemin olması gerektiğini gösteriyoris_alive
Daenyth

4
@WilliamBarbosa pep8'e bir göz attı, herkesin kullandığı piton stili bir rehber. legacy.python.org/dev/peps/pep-0008
Daenyth

2
8/11 turunda ortalama sağlığı 0 dan büyük olan tek bot olduğun için tebrikler.
isaacg

6
IMO, "stil rehberleri" programcılara değil kuaförlere yöneliktir.
Kyle Kanos

2
@KyleKanos Yine de bir tutarlılık olması güzel. Yani, bir projenin geliştiricisinin yarısı deve kasası kullanıyorsa ve bunun gibi diğer yarım türleri kullanıyorsa, sonuç "blergh" olur
William Barbosa,

12

EmoCowboy

Neden ölmeyi bekleyelim? Sadece şimdi kendini öldür. Umarım budalaların geri kalanı -2'den çok daha azını esecek.

Puan normalde -2 olacaktır. Bazen -4 kişi beni yarasadan vurmaya karar verirse. Nadiren bundan daha fazlası, bunun mevcut gönderilerin birkaçını geçmesi gerektiği anlamına geliyor.

piton

print('S0')

python EmoCowboy.py

EDIT: Bu bir şaka değil, bu yüzden genellikle bu emo başvurularının üzerine kaşlarını çattı. Bu meşru bir stratejidir. Hayatta olmak ölümcül!


11

barışsever

O gerçek bir şişmiş adam, yanlış kalabalığa yakalandı.

main = putStr "N"

runghc pacifist.hsFarklı çalıştır , ancak verimlilik bir sorunsa, -O3 ile derlemek isteyebilirsiniz.


1
O adlandırmak Lütfen Luigi ve o bir şey kazanacak bakalım!
William Barbosa,

1
@WilliamBarbosa Luigi? Luigi mi dedin ?
Ağustos'ta

7
Lol gibi -O3garip bir fark yaratır.
saat

@tomsmeding runghcYan tarafta yavaş . Aslında benim Linux kutumda 10 kat daha yavaş.
Ray,

5
Bu, şiddetin varlığını ima eder, pasifistimizin başa
çıkmaya

9

Monkey - Python (İlk giriş!)

Maymun gör, maymun yap. Tam olarak rastgele bir oyuncu tarafından gerçekleştirilen son işlemi tekrarlayacaktır.

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

Bu şekilde çalıştırılabilir: "python monkey.py args" Fazladan adım gerekmez.


2
Umarım sana ateş etmemişlerdir! Python, negatif dizi indekslerini destekler, böylece uzunluğu hesaplamanıza ve bir tane çıkarmanıza gerek kalmaz; sadece -1doğrudan kullanın .
comperendinous

@ comperendinous Demek istediğimler listesinde S3. S3'ü uygularsam aptalca ateş etmez. Ayrıca, -1 endeksi son elemanı döndürür mü? Eğer öyleyse, serin! Ekleyeceğimden emin olacağım.
Elias,

Ve ilk (tamsayı) argümanı unutma. İhtiyacınız argv[2]oyuncuların geçmişini olsun.
comperendinous

Umarım Emo Kovboy'la eşleşmemişsindir.
kod

6

Basit Atıcı - Perl (sabit hata)

Bu bot, en sağlık durumu ile rakibini vuruyor. Bu çok basit bir strateji, ama bence gerçekten iyi bir şansı var

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

Bu, bazı örnek girdiler kullanarak nasıl çalıştırılacağıdır:

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

Vay. Basit ve akıllı.
Soham Chowdhury

6

Spock, Python 3.x'te

Bu kod daha ziyade bir deneyden ibarettir (dolayısıyla Spock adını aldı çünkü ... ... o bir vulcan ve bu tür şeylerde oldukça iyiler) ama yine de inşa etmek eğlenceliydi. Tüm bu kodun arkasındaki ana neden, oyunun kuralları göz önüne alındığında, Spock gibi iyi ve mantıklı bir varlığın yapacağı varsayımlardır:


Bu oyunun amacı , kamyon sayesinde sadece ayakta duran herkes tarafından yapılacak olan skoru en üst düzeye çıkarmaktır .

  • Spock'ın izlemesi gereken yönergelerden biri, kamyonun ortaya çıkmasını önlemek ve kamyonun ortaya çıkmadan önce herkesin öldüğünden emin olmaktır.

Spock, oyunun geri kalanında oynadığı oyun, ünlü alıntılarıyla özetlenebilir: " Pek çoğunun ihtiyaçları azınlığın ihtiyacından ağır basar ". Başka bir deyişle, Spock, yapanları öldürerek, en az zararın yaşandığından emin olmak zorundadır. O nasıl yapıyor:

  • Hiçbir oyuncu bir el bombası hazırlamadıysa, hala oynayan en az sağlıklı oyuncuyu hedefleyin.
  • El bombası hazırlayan oyuncular varsa, bu hedeflerden en az sağlıklı olanı.

Sebep, en zayıf oyuncuları hedef alarak hasar kaynaklarını sonlandırmamızdır. El bombalarının ardındaki sebep, ne olursa olsun kaybolmaları ve atılmadıkları takdirde daha az zarar vermeleridir.


Ve böylece bu bot çalışıyor. Giriş hataları için kapsamlı bir test yapmadım (bu nedenle lütfen bir şeyler ters giderse beni uyarın) ancak eminim ki çoğu akrabayı çözdüm. Kodun küçük bir bölümünü HanSolo botundan aldım, ancak çoğunlukla karışık bir kod karışıklığı var. Keyfini çıkarın.

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)

Gibi koş:

python spock.py

2014-08-12 - El bombası tespiti ile ilgili
küçük hata düzeltmesi 2014-08-14 - Daha önce işaret ettiği için isaacg sayesinde oyunsonu hakkında küçük hata düzeltildi


Her iki turda birden fazla çekim yapmanıza izin verilmez. Çekimdeki özellikleri okuyun.
isaacg

@isaacg Hatırlatma için teşekkürler (davranışını açıklar), ancak bazı gizli hatalar olduğu görülüyor. Mesela bu Spock'ta InputAnalyser'ı vurmuş olmalıydı çünkü canlı bir el bombası vardı (Solo'nun daha fazla 2 sağlığı olsa bile).
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]olmalı int(player[1][1]).
isaacg,

@ isaacg tekrar, yardımın için teşekkür ederim. Bunu daha önce yapardım, ama bir şeyler içtim. Sonunda Spock, bunun nasıl oynanacağına dair yanlış bir konsepte dayanıyordu, dolayısıyla elde ettiği nispeten düşük puandı. Yeni botlar için bazı fikirlerim var, ama o kadar çok ana fikrimin orijinal olduğundan emin olmak zorundayım.
Doktoro Reichard,

5

Politik Olarak Doğru Silahşör

Çok politik olarak doğru, çünkü hiçbir şeye ayırımcılık yapmaz. Bu yüzden çok akıllı değil.

import random

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

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

Bu ... gerçekten hangi argümanların ona nasıl iletildiği önemli değil. python politicallycorrectgunman.py


Köşeli parantezlerin çıktının bir parçası olması gerektiğini sanmıyorum. Belki de @ es1024 bunu doğrulayabilir. Ve rastgele.choice'i biliyor musun? Bu tür seçimler için harika.
comperendinous

şey sonra göz ardı edilir olsa da, çıkışta eylem ve hedefin önce bir şey olamaz
es1024

Bu es1024 @ daha iyi görünüyor mu?
Geri al

@Undo Evet, şimdi mükemmel çalışıyor
es1024 10:14

7
Sadece kullanamaz random.choice(array)mısın?
user2357112

5

Düz Atıcı

Süvarilerin eğitimli bir parçası ve birçok dilde konuşuyor ama göz kırpıyorsa, Düz Atıcı sadece önündeki düşmanı görebiliyor. Bir at olarak, çekimler arasında beklemeniz gerektiğini anlamıyor.

print('S2')

Perl, Python 2/3, Ruby: Bu at gerçekten bir polgot girişi.

Yine de kazanıyorum. Kaybedemem. Beni vurabilirsin ama beni öldüremezsin. Bay Ed, beni ilgilendirmez!

İçine biraz daha fazla düşünce (ve bazı işlevsel paradigma) eklenmiş bir cevap için bkz. Yirmi Dördüncü ve Yarım Yüzyıl .


5

Anti-grenadier

El bombaları kötü. Çok kötü. Eğer biri bir tane hazırlıyorsa, yapılacak en iyi şey onları vurmaktır. Aksi takdirde takılacağız.

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

Ricochet - Perl

Basit stratejiler bu zorlukta terbiyeli gibi görünüyor, işte bir diğeri. Rastgele yaşayan bir oyuncu vuruyor. Kamyondan kaçınmak için sonunda intihar etme özelliği eklenmiştir.

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

Öyle koş:

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

4

saldırgan

Birinci raundu çeker, 2. raundda en yüksek sağlık rakibini atar, bundan sonra en yüksek sağlık rakibini vurur.

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

Bunun gibi çalıştırın. / Agg ID "5 5 5 5".


4

Ninja

Sadece rastgele vurulmaktan kaçınmaya çalışıyorum.

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

olarak çalıştırmak

lua ninja.lua

Args gerekli değildir, ancak sorun olmadan eklenebilir.


2
@KyleKanos Ninja kendi atışlarını atlattı mı?
skeggse

2
@distilledchaos: ... evet, evet yapacak.
Kyle Kanos,

4

İsim : PriorityTargets

Kabuk Komutu : yakut PriorityTargets.rb 5 [game_state]

Dil : Yakut V2.1.2

Açıklama : PriorityTargets ortak oyun stilleri bulmaya çalışır. Daha sonra, bu oyun tarzlarına dayanarak, kime saldırmak istediğini ve hangi silahı kullanacağına karar verir.

Not : İlk Kod Golf gönderimi! Diğer bildirimlerden çok daha büyük çünkü biraz çıldırdım.

#!/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
Yaklaşımını seviyorum, nasıl olacağını görmek için sabırsızlanıyorum.
overactor,

Ne yazık ki, bir Grenadier yaratan içinde bir böcek olduğu anlaşılıyor. Ah iyi, bir dahaki sefere daha iyi yapacak :)
fingerco

3

Korkak - Perl

Çok korkakça davranır. Kendini sağlıklı hissettiğinde, kendini hissetmeyen ve onu vuran bir düşman seçer. Son dönüşü gerçekleştiren düşmanlar için bonus puanları (çünkü Nothingbu dönüşü yaptıkları ve kesinlikle savunmasız oldukları biliniyor ). Kendisi o kadar iyi olmadığını hissettiğinde, gizlice saklamak için siper alır, bazen birini vururdu.

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

Oldukça standart Perl kodu; bir dosyaya kaydedin ve sonra çalıştırın perl file argument argument [...]. Sözdizimini kontrol ettim ve sorun yoktu, bu yüzden bununla ilgili bir sorun olmadığını umuyorum.

E: 0 hatayla bölünme potansiyelini ortadan kaldırdı.


3

Bombacı

Bot R'de yazılmalı, komut satırı şöyle olmalı: Rscript Bomberman.R arg0 arg1
Bu botu yazmaya başladıktan sonra Geobits'in daha önce bir grenadier yaptığını fark ettim ama benimkinin oldukça farklı olduğunu düşünüyorum, çünkü sağlıklarının el bombası hazırlamadan önce 3'ün üstünde olup olmadığını kontrol ediyor, önce son atıcı ve en sağlıklı ikinci ve sağlığının 3'ün altında olması durumunda, tehlikeli oyuncudan (son turda ne ölü ne de atıcı) kaçacak veya kalan oyuncudan birini vuracaktır.

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)

Düzenle

Baktığım tüm günlükler botumun yalnızca çıktı gösterdiğini gösterdi, çünkü bu bot ve kontrol cihazınız arasında bir iletişim sorunu var gibi görünüyor N. Öyleyse, bu aynı bot ama Python'da yeniden yazıldı, umarım eğer bu da bir iletişim sorunu yaşarsa, birileri onu görecektir.
İle çağrılacak 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)

Botun ismi göreceli olarak zayıf, ama daha iyi bir isim düşünebilecek biri varsa lütfen yorum
yapmayı bıraktım

GymnastBomber !!
Cruncher

3

Neo

Son dönüşü yapmayan canlı bir oyuncuyu atlat. Hayatta kalan herkes son sırada vurursa, rastgele yaşayan bir oyuncu vur. Farları gördüğünde intihar et.

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

Bu adamdan el bombası kıkırdamalarına karşı pek bir şey beklemiyorum, ama atıcılara karşı oldukça iyi işe yarayabilir. Göreceğiz.


Ben de senin Demirbaş kodunun bir kısmını kullanılan Cevabıma . Umarım herşey yolundadır.
otorractor

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 Şimdi gitmeniz iyi olmalı ve her ilk fırsatta hiçbir şey yapmayacak
Geobits,

2

Yirmi Dördüncü ve Yarım Yüzyıl

Bu Python girişi yalnızca pasif oyuncular veya tek bir agresif oyuncu kalana kadar soluklaşır ve soluklaşır, sonra ateş etmeye başlar. Geçen bir Marslı'nın kız çocuklarına ve sarhoş kamyon şoförlerine bakmasını umuyor.

Yanlış bir şey yapmadığım sürece, bu işlevsel Python. Kesinlikle Haskell ve arkadaşları beni bulmadan önce yazdığım bir Python gibi gözükmüyor ve hiçbir şeyi yerinde değiştirdiğimi sanmıyorum. Ama daha iyisini biliyorsan, lütfen bana söyle.

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

Olarak çalıştırmak:

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

2

korkmuş

Bu başvuru herkesten korkuyor. Ama özellikle bazı insanlardan korkuyor. Bu yüzden kimin en tehlikeli olduğunu anlar ve onları vurur. Birden fazla düşman en tehlikeli görünüyorsa, rastgele birine ateş eder.

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

Bu python (2 veya 3, her ikisinde de aynı sonuçtur.) Farklı kaydet scared.py, çalıştırpython3 scared.py


2

Manipülatif Piç - Python

El bombası hazırlar ve atar. Zamanın olmadığını veya çok az düşman olduğunu düşünüyorsa, ateş eder. Yalnızsa, diğer adamı yenmeye çalışır.

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

Usame

Bunu bir gündür deniyorum, şimdi bu sırada başkalarının nasıl geliştiğini görmenin ve yayınlamanın zamanı geldi.

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

İle derleyin ghc -O2 osama.hs, sonra çalıştırın ./players/Osama/osama.


2

Keskin Nişancı - Lua

İlk dönüşte rastgele bir kişiyi vurur, sonra öldürebileceği tüm oyuncuları vurur (2 veya 1 sağlık). Bunlardan hiçbiri çalışmazsa, en son çıkan oyuncuyu vurmaya çalışır, aksi takdirde rastgele bir oyuncu vurur. İle koş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)))

Aslında önce ekstra bir argümanla çalıştırılacak; ör lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". argDizininizi kontrol etmeniz gerekebilir .
comperendinous

@ comperendinous, teşekkürler, şimdi düzeltildi
waylon531

Merhaba, @ waylon531, Lua hakkındaki soru: randomseed math.randoms "math.randomseed (os.time ()) math.random (); senaryo?
AndoDaan

1
AndoDaan göre lua-users.org/wiki/MathLibraryTutorial bazı OS hep denir () aynı numaralı ilk kez Math.random döndürür.
waylon531

lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberyığın geri izleme:./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
es1024

2

Darwin

En zinde olanın hayatta kalması, en az sağlıklı ölmek gerektiği anlamına gelir.

gerekçe

12 Ekim Salı günü alınan sonuç grubuna bakıldığında, üç ayrı grup var gibi görünüyor: hayatta kalanlar; etkili bir intihar; ve faydasızdan da kötüsü. Hayatta kalanlar basit atış tabanlı stratejileri paylaşıyorlar. Diğer birkaç bot ( Spock , Coward ) en az sağlıklı düşmanı hedef alırken , stratejilerini diğer eylemlerle de karmaşıklaştırıyorlar. Bu değil. Gibi basit Shooter , bu hedefin net bir tanıma sahip ve acımasız onunla yapışır. Sonuçlara nerede uyduğunu görmek ilginç olacak.

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

Bu sadeleştirilmiş, benim daha önceki biraz değiştirilmiş bir versiyonu Yirmi Dördüncü ve Halfth Yüzyıl ve bunun çağırma paylaşır:

python darwin.py 3 "5 5 5 5"

2

Zaenille - C

Öncelikler:

  1. 1'e 1 kaldıysa vur
  2. Grenadiers ateş
  3. Atlatmak
  4. Hiçbir şey (sadece bazılarını karıştırmak için)

İle derleyin gcc <filename.c>.

İle koş ./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
Birinci (tamsayı) argümanı, eğer soruda verilen örnekler geçilecek bir şeyse, tur sayısını göstermez. Eğer soğukluk numarasına 82. atanmış ediyorum sırf İlk dönüşte kendini vurmak istemem
comperendinous

Gerçekten mi? D: @ comperendinous teşekkürler. Kodu düzenleyecektir.
Mark Gabriel,

2

InputAnalyzer

Bunun gibi bir oyunun anahtarı, tüm rakiplerinizin buna göre nasıl tepki verdiğini analiz etmektir. Botum, rakiplerimi kullanmayla sonuçlanacak karmaşık algoritmalar kullanmaktan, kesin bir zafer kazanma avantajım oluyor!

Düzenleme: şimdi

  1. canlı bombası olan herhangi bir oyuncuyu atlatmak
  2. artık kendimi vurmaya / atmaya / atlatmaya çalışmayacak.

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

Botu aşağıdaki komutla derleyin (ghc'ye ihtiyacınız var)

ghc - makee GirişAnalyzer.hs

Çalıştırılacak Shell Komutu aşağıdaki gibi olmalıdır

./InputAnalyzer

Not: Windows'ta test ettim, bu nedenle compling / running ile ilgili herhangi bir sorun yaşarsanız, lütfen yorum içinde belirtin ve doğru komutu bulmak için elimden geleni yapacağım.


1
Sanırım bu Haskell'de ağırlıklı bir yalancı ve jeneratör üretmenin bir yolu.
comperendinous

2

Cesaret adlı köpek

İlk şey - görünürde kötü adamları vur. Sonra biri el bombası hazırlayana kadar rastgele kaçın. Sonra herkes ona ateş ettiğinde, el bombamı hazırla ve herhangi birine at. Ama dikkat dağıtıcı adam.

Düzenleme: Şimdi olması gerektiği gibi uygulandı. Daha önce skor: 35.9

Güncelleme: Bazen atlatmak yerine vuruyor

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

Olarak çalıştırmak

python couragethedog.py

2

MAD - Java

MAD bot karşılıklı güvence imha yoluyla yıldırma gücüne güveniyor . Ne zaman hazır bir el bombası yoksa, bir tane hazırlar. Daha sonra birisi ona zarar vermeye çalışıncaya veya el bombası patlamak üzere olana kadar olası topçulardan kaçar. Saldırıya girdiği andan itibaren, bu maçta kendisine daha fazla hasar vermeye çalışan el bombalarını çalıyor . El bombası patlayacaksa, baştaki oyuncuyu bombalar. MAD, bir bombayı atlatmak veya doğrudan el sıkmak için hiçbir şey olmadığında birisine ateş etmeye karşı değildir ve el bombası en az bir tur atmak için hala iyidir.

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

Bu Bot muhtemelen düşük performans gösterecek, ancak yine de bu fikri sevdim. MAD muhtemelen diğer botların davranışlarını kaydeden daha akıllı botlara sahip bir alanda daha iyi sonuç verir ve daha fazla maç 4 bot arasında gerçekleşir.


Bir miktar kredi Geobits'e gidiyor, Neo'nun girişinin bazı kazan plaka kodlarını çaldım.
otorractor

Fazla
para almadın

java MAD 43 "5 5 5 5"Hiçbir şey çıkmıyor gibi görünüyor.
es1024

2

Sadist

piton

Önceliği ağrı ve el bombası incinmek. İlk sırayı alıyor. Saldıramazsan öldürmeyi seviyor. Hakimiyetini uzatmak için kaçıp çekerek SSS'ler (tek basit atıcılar) ile oyuncaklar. İlk önce kimseye hiçbir şey yapmayanlara saldırmayı bile seçti.

El bombası kullandığından, o (ve diğerleri), genellikle ikinci veya üçüncü rauntta hayatta kalamazlar. Başka bir el bombası ile eşleştirilmişse, herkes ölecek. Bu, kazanmayı beklemiyor olmam anlamına gelir ancak bunu python öğrenmek için yazdım (daha önce hiç kullanmadım ve bir sürü yeni dile giriş yapmaya çalışıyorum). Birkaç "ilk önce" çekin, öyleyse çok simüle olduğunu düşünüyorsanız bana bildirin. Diğerleri, ancak çekip sonra atlamak için istekli görünmüyor.

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

Bunun işe raw_inputyarayacağını sanmıyorum . sys.argv[2]Python girişleri için fikir birliği gibi görünüyor. Bunun için kullanımı daha da kolaylaştıracak popolanı bulabilirsiniz . thisisme=player[0];player.remove(player[0])thisisme=player.pop(0)
19

@comperendinous Kodu Ideone'da test ediyordum ve sys.argv hiç çalışmıyor (muhtemelen sys alma nedeniyle). Bu yüzden raw_input kullandım. İkincisinin çalışmamasına neden olacak bir fark var mı? Öyleyse muhtemelen python için başka bir çevrimiçi derleyici bulmam gerekecek. Pop ile öneri için teşekkür ederiz! Dizinin belirtilmesine izin veren komutun farkında değildim. Gelecekteki python kodları için kullanacağım.
kaine

1
raw_inputçeker STDIN, ancak oyuncu geçmişi programınıza komut satırı argümanı olarak aktarılır, bu yüzden ihtiyacınız var sys.argv. Test uğruna, sadece elle ile ayarlayabilirsiniz sys.argv = ["sadist.py", "0", "5 5 5 5"]. O zaman arayabilirsin player=sys.argv[2].split(). Alma işlemi sysgerçekten mümkün değilse , test etmek için noktayı bile düşürebilir ve diziyi çağırabilirsiniz sysargv. Her şey işe yaradığı ve başvurunuza geri döndüğünüz sürece sys.argv, iyi olmalı.
19

@comperendinous, eğer sys.argv'yi çağırırsam, bir dizi olarak programın ismi, 1'deki tek sayı ve 2'de kullandığım asıl parça olarak geri dönecek mi? Hepsi dizgedir. Bu bilgi ile doğru şekilde düzenleyebilmeliyim. Çok teşekkür ederim!
kaine
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.