Mağara adamı düelloları (veya: seni keskin bir sopayla dürttüm)


151

Mağara adamı deli. Diğer mağara adamı sopa alır ama sopa benim içindi. Mağara adamı savaşı !


Açıklama

Mağara adamı, diğer mağara adamı bıçaklamak için keskin bir çubuğa ihtiyaç duyar. Diğer mağara adamı da keskin bir sopa ile bıçaklamaya çalışmaktadır. Mağara adamı, sopayı keskinleştirebilir, sopayla dürtebilir veya kurnaz çubukları engelleyebilir.

Mağara adamı başka bir mağara adamı keskin bir sopa ile dürttü, diğer mağara adamı kaçtı ve bana zafer kazandı. Ama diğer mağara adamı dürttüğümde akıllıca engellerse, çubuğum körelir ve bir kez daha keskinleşmem dışında hiçbir şey olmaz.

Mağara adamı tembel. Ayrıca, mağara adamı aptal. Mağara adamı ne yapacağını bilmiyor, bu yüzden mağara adamı ne yapacaklarını anlatmak için ... ... fantezi tekno bilgisayar programına ihtiyaç duyuyorlar.

Giriş

Programınızın girdisi, Skeskinleşmenin (örneğin mağara adamı sopasını keskinleştirdi), Pdürtmenin ve Bblokun durduğu anlamına gelen olayların geçmişi olacak . Giriş, her iki tarafın da tarihi olacaktır (siz ve rakip), bu nedenle siz ve rakip hareketleri bir virgül ( ,) ile ayrılacaktır .

Örnek giriş:

SPB,SBB

Bu, oyuncunun sopasını keskinleştirdiği, daha sonra dürttüğü, daha sonra bloke ettiği ve rakibinin keskinleştiği, daha sonra bloke ettiği ve tekrar bloke ettiği anlamına gelir.

1. turda hiçbir giriş almayacaksınız.

Çıktı

Çıktı, girişe çok benzer (çünkü mağara adamı çok akıllı değildir). Programınız Skeskinleştirme, Pdürtme ve Bbloklama için çıktı vermelidir . Çıktının yalnızca ilk karakteri dikkate alınacak ve diğer girdiler B(blok) komutu olarak değerlendirilecektir.

  • S: keskinleştirmek

    Keskinleştirme sırasında mağara adamı çubuğunun keskinliği 1 artar ve çubuk 1 ekstra dürtme alır. Her bir kurcalama çubuğun keskinliğini 1 oranında azaltır ve eğer çubuğun keskinliği 0 ise, oynaması çok sıkıcıdır. Netlik 0'dan başlar. Netlik 5'e çıkarsa, çubuk bir kılıçtır! (Aşağıya bakınız.)

    Eğer keskinleştikçe rakip dürterse (ve> 0 keskinliği varsa), rakip kazanır!

  • P: dürtme

    Alay ederken mağara adamı çubuğunun keskinliği 1 kat azalır ve rakibinizi dürtürsünüz! Rakibiniz keskinleşiyorsa, kazandınız! Eğer rakip atarsa, sopanız rakibin sopasına vurur ve her ikisi de sıkıcı olur (1 "keskinlik birimi" ile). Rakip engelliyorsa, çubuğunuzun sıkıcı olması dışında hiçbir şey olmuyor.

    Çubuğunuzun keskinliği 5 veya daha fazla olduğunda dürterseniz, çubuğunuz bir kılıç olur ve her zaman kazanırsınız! (Rakibiniz aynı zamanda bir kılıcı olmadığı ve seçtiği sürece P; bu durumda, ikisi de sıkıcı hale gelir ve keskinlikleri 5'in altına düşerse sopalara geri dönebilir.)

    0 netliği ile dürtemezsiniz. Yaparsanız, hiçbir şey olmaz.

  • B: blok

    Engellediğin zaman, rakibini dürttüğünde hiçbir şey olmuyor. Rakibiniz dürtme yapmıyorsa blok hiçbir şey yapmaz.

    Engellemek, bir tane bile olsa kılıçtan korunmaz!

Kurallar ve kısıtlamalar

Ek kurallar:

  • Verilerinizi kaydetmek istiyorsanız, programınız dosyaları kendi klasöründe okuyabilir ve yazabilir (çalmak yok!), Ancak bunun dışında hiçbir şeye erişemezsiniz (ve mağarada vahşi doğada internet bağlantısı yoktur).
    • Dosyalar hakkında önemli not : Dosyaları kaydederseniz, dizine kaydetmeyi unutmayın players/YourBotsName/somefile.foo! Programınız için geçerli çalışma dizini programınızın olmayacak!
  • Mağaracılar adil: Bir programın başka bir program için belirli bir kodu olamaz ve programlar birbirine yardım edemez. (Birden fazla programınız olabilir, ancak birbirleriyle hiçbir şekilde etkileşime giremezler.)
  • Mağara adamı yargıcı sabırlı değil. Eğer mağara bir galibiyete karar vermek için her biri 100'den fazla tur alırsa, hakem sıkılır ve her iki mağara kaybeder.

Programınız bir kuralı ihlal ederse veya şartnameye uymuyorsa, program diskalifiye edilir, kaldırılır playerlist.txtve tüm düellolar baştan başlar. Eğer programınız diskalifiye edilirse mağara adamı lideri (ben!) Programınızın yazısına yorum yapacak ve nedenini açıklayacaktır. Herhangi bir kuralı ihlal etmiyorsanız, programınız büyük tabloya eklenecektir. (Programınız lider panosunda değilse, yayınınız hakkında açıklayıcı bir yorum yoktur ve programınızı aşağıdaki "Son güncelleme" saatinden önce yayınladınız, mağara adamı liderine bildirin! Belki de unuttu.)

Gönderinize lütfen ekleyin:

  • Bir isim.
  • Bir kabuk komutu programı çalıştırmak için (örn. java MyBot.java, ruby MyBot.rb, python3 MyBot.py, Vb.)
    • Not: girdiler buna komut satırı argümanı olarak eklenecektir.
    • Mağara adamı Ubuntu 14.04 kullanıyor, bu nedenle kodunuzun üzerinde serbestçe çalıştığından emin olun.
  • Kodunuz seçtiğiniz dilin farklı sürümlerinde farklı şekilde çalışıyorsa, bir sürüm numarası.
  • Kodunuz (açıkçası).
  • Gerekirse, kod nasıl derlenir?

Denetleyici kodu / testi, örnek bot

Mağara adamı lideri kontrol kodunu C ++ 'da yazdı ve Github deposuna gönderdi . Orada programınızı çalıştırabilir ve test edebilirsiniz.

Aşağıdaki cevaplarda çok, çok basit bir program (1 satır!) Da yayınlanmıştır .

Puanlama ve afiş

Puanlama kolaydır. Hangi mağara adamı kazanırsa kazanır. Her mağara adamı karşı 3 düellodan sonra en çok puan alan mağara adamı yeni mağara adamı lideri olur!

150     Watson
147     SpeculativeSylwester
146     Gruntt
141     BashMagnon
126     ChargerMan
125     PrisonRules
124     ViceLeader
122     MultiMarkov
122     CaveDoctor
120     RegExMan
120     Hodor
117     FancyTechnoAlgorithm
116     Semipatient
113     Watcher
108     BobCaves
105     MinimaxMan
104     Oracle
102     MaybeMarkov
97      Nash
95      Sicillian
95      Feint
95      Basilisk
94      SharpMan
93      Darwin
91      Nigel
91      JavaMan
88      Entertainer
88      CarefulBot
85      CaveMonkey
84      SSBBP
82      SirPokealot
79      MasterPoker
77      Unpredictable
76      IllogicalCaveman
75      SharpenBlockPoke
75      HuddleWolfWithStick
72      WoodenShield
68      PokeBackBot
68      PatientBlacksmith
66      PatientWolf
58      MonteCarloMan
58      BlindFury
56      BinaryCaveman
55      PokeBot
55      CavekidBlocks
53      Swordmaster
53      Blocker
52      NakedEarlyNerd
52      ModestCaveman
50      LatePokeBot
40      Trickster
39      SwordLover
38      ForeignCaveman
36      Swordsmith *
28      Touche
27      WantASword
27      FoolMeOnce
24      PeriodicalCavemanCicada
11      Aichmophobic

(bu afiş otomatik olarak oluşturuldu)

Bir işaret ile işaretlenmiş oyuncular bir *noktada bir çeşit hata veya istisna attı; Bu oyuncuların ayrıca yayınları hakkında bir yorumu var.

Herhangi bir nedenle testlerde dahil edilemedi oyuncular (bu oyuncuların problemi açıklayan yayınlarına bir yorum olacaktır): Monkey, Elephant, FacileFibonacci, StudiousSylwester.

Son güncelleme: Ağustos 3 00:15 (UTC).


Henüz kimsenin minimax stratejisini bulmaya çalışmadığı görülüyor. Yapılacak açık bir şey gibi görünüyor.
user2357112

@ user2357112 Minimax'ın burada bir gelişme olduğunu sanmıyorum. Yani, bir minimax uygulaması tasarlayabilirsiniz, ancak mantık çok basit olduğundan, aynı kesin davranış sonlu durumlu bir makine ile ifade edilebilir. (yani, rakip donuk hale gelinceye kadar bot asla keskinleşmeyecektir, çünkü eğer yaparsa, rakibin minimize etme hareketi dürtmek olacaktır ve kaybedersiniz, bot her zaman bir kılıcımız olana kadar bloke eder çünkü botumuz için maksimum hareket her zaman engellemek, vb olmak)
HuddleWolf

3
Girişlerin birçoğu hesaplamalarında negatif netliğe izin veriyor gibi görünüyor. Yazılan kurallar, sıfır netlikle dürttüğünüzde hiçbir şeyin olmadığını söylüyor. Bu "hiçbir şey", keskinliğinizin azalmak yerine sıfır kaldığı anlamına mı geliyor?
Sparr

6
Bu ihtiyacı Burada olmak: dresdencodak.com/comics/2009-09-22-caveman_science_fiction.jpg Belki hayal gidiş alacak. :)
Evi1M4chine

2
Bu hala açık mı? İnsanların yeni gönderimler eklediğini görüyorum, ancak afişin güncellendiğini görmüyorum.
ASCIIThenANSI

Yanıtlar:


35

Darwin - C

Yine de kimin stratejiye ihtiyacı var? Bir grup mağarayı birbirine geçirin ve gerisini doğal seleksiyona bırakın!


Mağara adamı ilkel beyni için çok basit bir model kullanıyoruz: hafızası yok ve sadece rakibinin ve çubuğunun keskinliğini hesaba katar. Bunlar, sonlu bir düzende ikili polinom değişkenleri olarak kullanılır. Her eylemde (blok, keskinleştirme ve dürtme) sonucu, bu eylemi seçmenin göreceli olasılığını belirleyen ilişkili bir polinom vardır. Orada olanların hepsi bu kadar --- bazı rasgele katsayılar ile başla ve yinelemeli şekilde optimize et.

Bot:

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

/* magic numbers */
#define SWORD_SHARPNESS 5
#define PROGRAM_DIM 4 /* polynomial order + 1 */
#define DEFAULT_FILENAME "players/Darwin/program"

typedef double real;
typedef real program[PROGRAM_DIM][PROGRAM_DIM];
typedef program caveman_brain[3];

typedef char action; /* S, B or P */
/* encodes a pair of actions */
#define ACTION_PAIR(a1, a2) (((int)(a1) << (sizeof(action) * 8)) | (a2))

real eval_program(const program p, double x, double y) {
    real v = 0;
    int i, j;

    for (i = 0; i < PROGRAM_DIM; ++i) {
        real w = 0;
        for (j = 0; j < PROGRAM_DIM; ++j)
            w = x * w + p[i][j];
        v = y * v + w;
    }

    if (v < 0)
        v = 0;
    return v;
}
void read_program(FILE* f, program p) {
    int i, j;
    for (i = 0; i < PROGRAM_DIM; ++i) {
        for (j = 0; j < PROGRAM_DIM; ++j) {
            double v;
            fscanf(f, "%lg", &v);
            p[i][j] = v;
        }
    }
}

int blunt(int* s) {
    int temp = *s;
    if (temp)
        --*s;
    return temp;
}
void sharpen(int* s) { ++*s; }
/* takes two sharpness/action pairs and updates the sharpness accordingly.
 * returns negative value if first caveman wins, positive value if second
 * caveman wins and 0 otherwise. */
int act(int* s1, action a1, int* s2, action a2) {
    switch (ACTION_PAIR(a1, a2)) {
        case ACTION_PAIR('B', 'B'): return 0;
        case ACTION_PAIR('B', 'S'): sharpen(s2); return 0;
        case ACTION_PAIR('B', 'P'): return blunt(s2) >= SWORD_SHARPNESS ? 1 :
                                                                          0;
        case ACTION_PAIR('S', 'B'): sharpen(s1); return 0;
        case ACTION_PAIR('S', 'S'): sharpen(s1); sharpen(s2); return 0;
        case ACTION_PAIR('S', 'P'): sharpen(s1); return *s2 > 0 ? 1 : 0;
        case ACTION_PAIR('P', 'B'): return blunt(s1) >= SWORD_SHARPNESS ? -1 :
                                                                          0;
        case ACTION_PAIR('P', 'S'): sharpen(s2); return *s1 > 0 ? -1 : 0;
        case ACTION_PAIR('P', 'P'): {
            int t1 = blunt(s1), t2 = blunt(s2);
            if (t1 >= SWORD_SHARPNESS && t2 < SWORD_SHARPNESS)
                return -1;
            else if (t2 >= SWORD_SHARPNESS && t1 < SWORD_SHARPNESS)
                return 1;
            else
                return 0;
        }
    }
}
/* processes a pair of strings of actions */
int str_act(int* s1, const char* a1, int* s2, const char* a2) {
    for (; *a1 && *a2; ++a1, ++a2) {
        int winner = act(s1, *a1, s2, *a2);
        if (winner)
            return winner;
    }
    return 0;
}

double frandom() { return (double)rand() / RAND_MAX; }

/* chooses an action based on self and opponent's sharpness */
action choose_action(const caveman_brain b, int s1, int s2) {
    double v[3];
    double sum = 0;
    double r;
    int i;
    for (i = 0; i < 3; ++i) {
        v[i] = eval_program(b[i], s1, s2);
        sum += v[i];
    }
    r = frandom() * sum;
    if (r <= v[0])
        return 'B';
    else if (r <= v[0] + v[1])
        return 'S';
    else
        return 'P';
}

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

int main(int argc, const char* argv[]) {
    const char* filename = DEFAULT_FILENAME;
    const char *a1, *a2;
    FILE* f;
    caveman_brain b;
    int s1 = 0, s2 = 0;
    int i;

    srand(tick_count()); rand();

    a1 = argc > 1 ? argv[1] : "";
    if (*a1) {
        a2 = strchr(a1, ',');
        if (a2 == NULL) {
            printf("invalid input!\n");
            return 1;
        }
        ++a2;
    } else
        a2 = a1;

    if (argc > 2)
        filename = argv[2];

    f = fopen(filename, "r");
    if (f == NULL) {
        printf("failed to open `%s'\n", filename);
        return 1;
    }
    for (i = 0; i < 3; ++i)
        read_program(f, b[i]);
    fclose(f);

    str_act(&s1, a1, &s2, a2);
    printf("%c\n", choose_action(b, s1, s2));

    return 0;
}

İle derleyin: gcc darwin.c -odarwin -w -O3. İle çalıştırın: ./darwin <history>.

Bot adında bir dosyadan katsayılarını okur programiçinde players/Darwin(farklı bir dosya ikinci komut satırı argümanı olarak belirtilebilir) dizinine. Bu program iyi görünüyor:

0.286736 0.381578 -0.128122 1.33933 
0.723126 0.380574 1.21659 -0.9734 
0.924371 0.998632 -0.0951554 0.744323 
-0.113888 -0.321772 -0.260496 -0.136341 

0.280292 -0.699782 -0.246245 1.27435 
-1.24563 -0.959822 -0.745656 0.0347998 
-0.917928 -0.384105 0.319008 -0.70434 
0.484375 0.802138 0.0967234 0.638466 

0.406679 0.597322 1.39409 0.902353 
-0.735946 0.742589 0.955567 0.643268 
-0.503946 0.446167 1.002 0.328205 
0.26037 0.113346 0.0517265 -0.223298 

Olarak kaydet players/Darwin/program.

Aşağıda, programbot tarafından kullanılabilecek dosyalar üreten bir program bulunmaktadır ( programyukarıdaki dosyayı kullanıyorsanız derlenmesi gerekmez ):

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

/* magic numbers */
#define SWORD_SHARPNESS 5
#define MAX_TURN_COUNT 100
#define PROGRAM_DIM 4 /* polynomial order + 1 */
#define CAVEMAN_COUNT 500
#define GENERATION_COUNT 12
#define DUEL_COUNT 8
#define ERROR_BACKOFF 0.5
#define DEFAULT_FILENAME "players/Darwin/program"

typedef double real;
typedef real program[PROGRAM_DIM][PROGRAM_DIM];
typedef program caveman_brain[3];

typedef char action; /* S, B or P */
/* encodes a pair of actions */
#define ACTION_PAIR(a1, a2) (((int)(a1) << (sizeof(action) * 8)) | (a2))

real eval_program(const program p, double x, double y) {
    real v = 0;
    int i, j;

    for (i = 0; i < PROGRAM_DIM; ++i) {
        real w = 0;
        for (j = 0; j < PROGRAM_DIM; ++j)
            w = x * w + p[i][j];
        v = y * v + w;
    }

    if (v < 0)
        v = 0;
    return v;
}
void write_program(FILE* f, const program p) {
    int i, j;
    for (i = 0; i < PROGRAM_DIM; ++i) {
        for (j = 0; j < PROGRAM_DIM; ++j)
            fprintf(f, "%g ", p[i][j]);
        fprintf(f, "\n");
    }
    fprintf(f, "\n");
}

int blunt(int* s) {
    int temp = *s;
    if (temp)
        --*s;
    return temp;
}
void sharpen(int* s) { ++*s; }
/* takes two sharpness/action pairs and updates the sharpness accordingly.
 * returns negative value if first caveman wins, positive value if second
 * caveman wins and 0 otherwise. */
int act(int* s1, action a1, int* s2, action a2) {
    switch (ACTION_PAIR(a1, a2)) {
        case ACTION_PAIR('B', 'B'): return 0;
        case ACTION_PAIR('B', 'S'): sharpen(s2); return 0;
        case ACTION_PAIR('B', 'P'): return blunt(s2) >= SWORD_SHARPNESS ? 1 :
                                                                          0;
        case ACTION_PAIR('S', 'B'): sharpen(s1); return 0;
        case ACTION_PAIR('S', 'S'): sharpen(s1); sharpen(s2); return 0;
        case ACTION_PAIR('S', 'P'): sharpen(s1); return *s2 > 0 ? 1 : 0;
        case ACTION_PAIR('P', 'B'): return blunt(s1) >= SWORD_SHARPNESS ? -1 :
                                                                          0;
        case ACTION_PAIR('P', 'S'): sharpen(s2); return *s1 > 0 ? -1 : 0;
        case ACTION_PAIR('P', 'P'): {
            int t1 = blunt(s1), t2 = blunt(s2);
            if (t1 >= SWORD_SHARPNESS && t2 < SWORD_SHARPNESS)
                return -1;
            else if (t2 >= SWORD_SHARPNESS && t1 < SWORD_SHARPNESS)
                return 1;
            else
                return 0;
        }
    }
}
/* processes a pair of strings of actions */
int str_act(int* s1, const char* a1, int* s2, const char* a2) {
    for (; *a1 && *a2; ++a1, ++a2) {
        int winner = act(s1, *a1, s2, *a2);
        if (winner)
            return winner;
    }
    return 0;
}

double frandom() { return (double)rand() / RAND_MAX; }
double firandom() { return 2.0 * rand() / RAND_MAX - 1.0; }

/* chooses an action based on self and opponent's sharpness */
action choose_action(const caveman_brain b, int s1, int s2) {
    double v[3];
    double sum = 0;
    double r;
    int i;
    for (i = 0; i < 3; ++i) {
        v[i] = eval_program(b[i], s1, s2);
        sum += v[i];
    }
    r = frandom() * sum;
    if (r <= v[0])
        return 'B';
    else if (r <= v[0] + v[1])
        return 'S';
    else
        return 'P';
}

typedef struct {
    caveman_brain brain;
    int sharpness;
    int score;
} caveman;
void init_caveman(caveman* c, const caveman* m, double e) {
    int p, i, j;
    c->score = 0;
    for (p = 0; p < 3; ++p) {
        for (i = 0; i < PROGRAM_DIM; ++i) {
            for (j = 0; j < PROGRAM_DIM; ++j) {
                c->brain[p][i][j] = m->brain[p][i][j] + firandom() * e;
            }
        }
    }
}
int duel(caveman* c1, caveman* c2) {
    int winner;
    int turn;
    c1->sharpness = c2->sharpness = 0;
    for (turn = 0; turn < MAX_TURN_COUNT; ++turn) {
        winner = act(&c1->sharpness,
                     choose_action(c1->brain, c1->sharpness, c2->sharpness),
                     &c2->sharpness,
                     choose_action(c2->brain, c2->sharpness, c1->sharpness));
        if (winner)
            break;
    }
    if (winner < 0)
        ++c1->score;
    else if (winner > 0)
        ++c2->score;
    return winner;
}

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

int main(int argc, const char* argv[]) {
    const char* filename = DEFAULT_FILENAME;
    FILE* f;
    caveman* cavemen;
    caveman winner;
    int gen;
    double err = 1.0;
    int i;

    srand(tick_count()); rand();
    memset(&winner, 0, sizeof(caveman));

    if ((cavemen = (caveman*)malloc(sizeof(caveman) * CAVEMAN_COUNT)) == NULL) {
        printf("not enough memory!\n");
        return 1;
    }

    for (gen = 0; gen < GENERATION_COUNT; ++gen) {
        int i, j, k;
        const caveman* leader;

        printf("[Gen. %d / %d] ", gen + 1, GENERATION_COUNT);
        fflush(stdout);

        for (i = 0; i < CAVEMAN_COUNT; ++i)
            init_caveman(&cavemen[i], &winner, err);

        for (i = 0; i < CAVEMAN_COUNT; ++i) {
            for (j = i + 1; j < CAVEMAN_COUNT; ++j) {
                for (k = 0; k < DUEL_COUNT; ++k)
                    duel(&cavemen[i], &cavemen[j]);
            }
        }

        leader = cavemen;
        for (i = 1; i < CAVEMAN_COUNT; ++i) {
            if (cavemen[i].score > leader->score)
                leader = &cavemen[i];
        }

        printf("Caveman #%d wins with %d victories in %d duels\n",
               leader - cavemen + 1,
               leader->score, (CAVEMAN_COUNT - 1) * DUEL_COUNT);

        memcpy(&winner, leader, sizeof(caveman));
        err *= ERROR_BACKOFF;
    }

    free(cavemen);

    if (argc > 1)
        filename = argv[1];
    printf("Dumping brain to `%s'\n", filename);
    f = fopen(filename, "w");
    if (f == NULL) {
        printf("failed to open `%s'\n", filename);
        return 1;
    }
    for (i = 0; i < 3; ++i)
        write_program(f, winner.brain[i]);
    fclose(f);

    return 0;
}

İle derleyin: gcc genprog.c -ogenprog -w -O3. İle çalıştırın: ./genprog [output-filename].


Watson

Kazanan mağara adamının DNA'sı nedir? Belki de bu dostun cevabı vardır:

# That's the actual logic. Initialization goes below.
def run():
    if his_sharpness[-10] - turn / 15 + 1 + turn % 3 - his_sharpness[-6] < 0:
        act(B=0, S=0, P=100) # 7.21% chance
    elif his_sharpness[-6] + 1 - his_sharpness[-2] < 0:
        act(B=0, S=0, P=100) # 4.15% chance
    elif his_history[-3] - my_history[-1] <= 0 and my_sharpness[-1] - turn / 10 <= 0:
        act(B=0, S=100, P=0) # 11.34% chance
    elif his_sharpness[-1] == 0:
        act(B=0, S=100, P=0) # 27.84% chance
    else:
        act(B=100, S=0, P=0) # 49.46% chance

# Boring stuff go here...

import sys, random

# Actions
block, sharpen, poke, idle = range(4)

# Converts textual history to internal format
def convert_history(textual_history):
    return ["BSP".index(action) for action in textual_history]

# Calculates sharpness after performing an action sequence
def calculate_sharpness(history):
    return history.count(sharpen) - history.count(poke)

# Returns a list containing the sharpness at the end of each turn
def sharpness_history(history):
    return [calculate_sharpness(history[:i + 1]) for i in range(len(history))]

# Acts based on the probability distribution (B%, S%, P%)
def act(B, S, P):
    r = random.random() * 100
    print "BSP"[(r >= B) + (r >= B + S)]

# Setup data
textual_history = sys.argv[1] if len(sys.argv) > 1 else ","
my_history, his_history = (convert_history(h) for h in textual_history.split(','))
my_sharpness, his_sharpness = (sharpness_history(h) for h in (my_history, his_history))
turn = len(my_history)
my_history, his_history = ([idle] * 16 + h for h in (my_history, his_history))
my_sharpness, his_sharpness = ([0] * 16 + s for s in (my_sharpness, his_sharpness))

# Make a move
run()

Çalıştır: python Watson.py

Watson, genetik bir algoritmanın ürünüdür. Darwin'in aksine, genetik veriler bu kez küçük bir alana özgü küçük bir dilde yazılmış (burada Python'a çevrilmiş) gerçek bir programdır.


Basit Sıra Büyük Oyuncuları Yener

Bu küçük dost, özellikle liderlere karşı şaşırtıcı şekilde (ya da belki de şaşırtıcı şekilde değil) iyi yapıyor:

import sys
print "Simple Sequence Beats Big Players".split(' ')[
    len(sys.argv[1]) / 2 % 5 if len(sys.argv) > 1 else 0
]

Çalıştır: python SSBBP.py


Bunu nasıl derler ve çalıştırırım? Ayrıca, soruda belirtildiği gibi, sadece players/Darwindizindeki dosyaları okuyabilir / yazabilirsiniz .
Doorknob

@Doorknob: düzeltildi.
DarwinBot

Bu kodu derlerken bu derleme hatalarını alıyorum . (
14.04

@Doorknob: Sabit. Şimdi çalışmalıyım.
DarwinBot

Şimdi anlıyorum undefined reference to `fmax'. - Karar - Boşver, Gerçekten ihtiyacım vardı -lm.
Doorknob

50

Tahmin edilemeyen mağara adamı

me, he = (ARGV[0] || ' , ').split(',')

@possible_actions = %w[Sharpen Poke Block]

class String

  def sharpness
    @sharpness ||= count('S') - count('P')
  end

  def has_pointy_stick
    (1..4).cover? sharpness
  end

  def has_sword
    sharpness >= 5
  end

  def scary
    sharpness > 0
  end

end

def no action
  @possible_actions.delete(action)
end

def do!
  puts @possible_actions.sample[0]
end

no 'Block' if not he.has_pointy_stick

no 'Poke' if not me.scary

no 'Sharpen' if me.has_sword

no 'Block' if me.has_sword

do!

Bu mağara adamı her turda rastgele seçiyor, ancak ona bazı eylemlerin bazen anlam ifade etmediğini çok açıkladım. Farklı bir mantık ifade etmek istiyorsanız bu kodu kopyalamaktan çekinmeyin.

Bu Ruby, 'unpredictable.rb' olarak kaydedin ve ruby unpredictable.rb


Aslında, no 'Block'rakibimin kılıcı varsa da olmalı.
njzk2

İlk “Blok” yok aslında şunları kapsar: sivri uçlu kılıç bir kılıç değildir.
histocrat

2
Neden ve ifadeleri unlessiçin kullanmıyorsunuz ? ( )no 'Block'no 'Pokeno 'Block' unless he.has_pointy_stick
wchargin

25

Mağara Doktoru - Lua

“Yeni yabancılara yenildim, onları incelemek için onları yere serdim”

Mağara doktoru kadar çok hasta gördüğünüzde mağara adamı ruhunu gerçekten anlamaya başlarsınız (ya da umarım). Mağara doktorunun oyunu saf bir stratejidir, rakibini silahsızlandırmak için engellediği dürtüleri bekler, ancak rakibinin bir kılıç yapmaya yaklaşmasına izin vermez. Keskinleştirmenin ne zaman güvenli olduğunu tahmin etmeye çalışır, böylece üst eli kaybetmez.

caveman={havePointyStick=function (t)     
   local pointy=0   
   for i in t.stick:gmatch("[SP]") do
    if i=="S" then 
      pointy=pointy+1
    elseif pointy>0 then
      pointy=pointy-1
    end   
   end 
 t.sharp=pointy>0
 t.lastmove=t.stick:sub(t.stick:len())
 return pointy 
 end,
    Stupid=function (stick)--I put way to much effort in this...
      o = {} 
      setmetatable(o, caveman)
      o.smartness=0
      o.stick=stick
      caveman.__index = caveman
      return o
    end,
     Smart= function (stick)
      o ={} 
      setmetatable(o, caveman)
      o.smartness=100
      o.stick=stick
      caveman.__index = caveman
      return o
    end
       }


    if arg[1]==nil then  
       print("S")
    else   
      split=arg[1]:find(",")  
      me=caveman.Smart(arg[1]:sub(0,split-1)) 
      he=caveman.Stupid(arg[1]:sub(split+1)) 
      mesharp=me:havePointyStick()  
      hesharp=he:havePointyStick()
      if not he.sharp and mesharp<5 then print("S")--Go for the sword  
      elseif mesharp>4 or me.stick:len()>93 then
         if (mesharp>0) then print("P")--We're losing/about to win or time's running out
         else print("S")--uh-oh
         end
      else 
         u,g,h=he.stick:match("(B+)S+(B+)S+(B+)$")
         g,u,h=he.stick:match("(P+)S+(P+)S+(P+)$")
         if u~=nil and u==g and g==h then 
            if not me.sharp then print("S")
            else print("P")
            end
         elseif me.stick:match("SBSB$")~=nil then print("B")
         elseif he.stick:len()>7 and he.stick:match("P")==nil and me.lastmove~="S" then print("S")
         else
         b,u,h=he.stick:match("(B*)(S+)(B*)$")
         if u~=nil then
             if (h:len()>3 and me.lastmove=="B") or (b:len()>h:len() and b:len()>0 and h:len()>0) then print("S")
             else print("B")
             end
          else print("B")
          end   
      end   
   end 
end

Çalıştır: lua CaveDoctor.lua


3
Bu mevcut lider tablosunda sadece iki kez kaybediyor? oO
justhalf

Revizyon 5, birçok hata atar; bu nedenle revizyon 4, mevcut davalara dahil olandır.
Doorknob

@Doorknob Sanırım hepsini düzelttim, yine de gerçek mantıkta sadece bir değişiklik oldu.
Nexus,

20

ForeignCaveman

ForeignCaveman'ın ne söylediğin hakkında hiçbir fikri yok. O sadece ... bir şeyler yapıyor.

javac ForeignCaveman.java sonra java ForeignCaveman

public class ForeignCaveman {

    public static void main(String[] args) {
        int m = (int) (Math.random()*3);
        switch(m) {
            case 0: System.out.println('B'); 
                    break;
            case 1: System.out.println('P'); 
                    break;
            case 2: System.out.println('S'); 
                    break;
        }
   }
}

11
Bu muhtemelen ne kadar kötü olduğu için çok fazla artıracak
Kevin L

19

Yardımcısı Lider

Kapı tokmağı ♦ liderdir. Ben lider olmak istiyorum! Lider olmak için süper akıllı programı takip edin!

Derleme: javac ViceLeader.javaçalıştırın: java ViceLeader.

public class ViceLeader {

    public static void main(String[] args) {
        if (args.length == 0 || !args[0].contains(",")) {
            System.out.print("S");
            return;
        }
        String[] history = args[0].split(",");
        int mySharpness = getSharpness(history[0]);
        int enemySharpness = getSharpness(history[1]);

        // enough sharpness to strike until end of game
        if (100 - history[0].length() <= mySharpness) {
            System.out.print("P");
            return;
        }

        // sharpen while secure
        if (enemySharpness == 0) {
            System.out.print("S");
            return;
        }

        // enemy blocks the whole time and I didn't use this tactic on last turn
        if (isBlocker(history[1]) && history[0].charAt(history[0].length() - 1) != 'S') {
            System.out.print("S");
            return;
        }

        // TAKE HIM OUT!
        if (enemySharpness == 4 || mySharpness >= 5) {            
            System.out.print("P");
            return;
        }

        // enemy sharpens the whole time => sharpen to strike on next turn
        if (isSharpener(history[1])) {
            System.out.print("S");
            return;
        }

        System.out.print("B");
    }

    private static int getSharpness(String history) {
        int sharpness = 0;
        for (char move : history.toCharArray()) {
            if (move == 'S') {
                sharpness++;
            } else if ((move == 'P' && sharpness > 0) || move == '^') {
                sharpness--;
            }
        }
        return sharpness;
    }

    private static boolean isBlocker(String history) {
        if (history.length() < 3) {
            return false;
        }
        for (int i = history.length() - 1; i > history.length() - 3; i--) {
            if (history.charAt(i) != 'B') {
                return false;
            }
        }
        return true;
    }

    private static boolean isSharpener(String history) {
        if (history.length() < 3) {
            return false;
        }
        for (int i = history.length() - 1; i > history.length() - 3; i--) {
            if (history.charAt(i) != 'S') {
                return false;
            }
        }
        return true;
    }
}

Bu neden if (enemySharpness <= 4 || mySharpness >= 5)vs değil ==?
durron597,

@ durron597 Çünkü düşmanı sadece bir sonraki dönüşe kılıç tutabiliyorsa (ki büyük olasılıkla yapacağı gibi) kılıcına çevirmek istiyorum. VizeLeader sık ​​sık dürtmez , doğru zamanda yapar .
CommonGuy

Fakat bir kılıcın var ve rakibin ...
durron597

@ durron597 Hayır, bu bir OR ifadesidir. "Kılıcım varsa rakibini dürtmek VE eğer yakında kılıcı alacaksa" demek.
CommonGuy

7
Aman Tanrım. Başka bir fincan kahve alma zamanı :) Veya yeni kontakt lensler
durron597

15

Belki Markov 2.1

Diğer mağara adamının ne yapacağını tahmin etmek için Markov Zincirlerini kullandığını düşünüyorum, ancak Markov Zincirleri hakkındaki wikipedia sayfasına kısaca baktım ve çok fazla metni olduğuna karar verdim.

30 tur boyunca hayatta kalmaya çalışır ve daha sonra şu anki durum değişiklikleriyle birlikte bir tablo oluşturur ve diğer mağara adamının ne yapacağını düşündüğü şeye tepki verir.

Kod bir sürü gereksiz ifade içeriyor, ancak oldukça iyi çalışıyor.

DÜZENLE

Mantıkta bir hata tespit edildi. Şimdi aslında bir kılıcı olduğunda bir şeyler yapıyor.

$ python3 players/MaybeMarkov/MaybeMarkov.py

import sys, itertools
from operator import itemgetter
from collections import defaultdict

SHARPEN, POKE, BLOCK, HALP = 'SPB?'

all_actions = SHARPEN, POKE, BLOCK
always = 1

def do(action):
    print(action)
    exit(0)

if len(sys.argv) < 2:
    do(SHARPEN)

class status:
    def __init__(self, actions):
        self.step = len(actions)
        self.last = actions[-1]
        self.sh = self.sharpness = actions.count(SHARPEN) - actions.count(POKE)
        self.dull = self.sharpness <= 0
        self.has_sword = self.sharpness >= 5
        self.actions = actions
        self.ratio = {act:actions.count(act)/self.step for act in all_actions}
        self.can_do = set(all_actions)

        if self.dull:
            self.can_do.remove(POKE)

    def can(self, action):
        return action in self.can_do


me, he = map(status, sys.argv[-1].split(','))
turns = me.step

if he.has_sword:
    if me.can(POKE)                :do(POKE)
    if always                      :do(SHARPEN)

if me.has_sword:
    if he.last != POKE and me.last == BLOCK :do(POKE)
    if he.can(POKE)                :do(BLOCK)
    if always                      :do(POKE)

if not he.can(POKE)                :do(SHARPEN)

if turns <= 4                      :do(BLOCK)
if turns < 30:
    if he.ratio[SHARPEN] == 1:
        if me.can(POKE)            :do(POKE)
        if always                  :do(SHARPEN)
    if always                      :do(BLOCK)

if turns > 97:
    do(POKE)

def react_on(action):
    do({
        HALP    : BLOCK,
        SHARPEN : POKE,
        POKE    : BLOCK,
        BLOCK   : SHARPEN
    }[action])

states = tuple(itertools.product(all_actions, all_actions))
change = defaultdict(lambda:defaultdict(lambda:0))
count  = defaultdict(lambda:0)

for i in range(1, turns):
    prev = me.actions[i-1], he.actions[i-1]
    now  = me.actions[i]  , he.actions[i]
    change[prev][now] += 1
    count[prev] += 1

current = change[me.last, he.last]
prediction = HALP

if len(current) is 0:
    do(BLOCK)

if len(current) is 1:
    if tuple(current.values())[0] > turns / 7:
        prediction = tuple(current.keys())[0][1]

counts = itemgetter(1)

if len(current) > 1:
    key1, value1 = max(current.items(), key=counts)
    current[key1] *= 0.9
    key2, value2 = max(current.items(), key=counts)
    if key1 == key2:
        prediction = key1[1]

react_on(prediction)

14

PeriodicalCicadaCaveman

Bu oldukça akıllı mağara adamı belli bir böcek çalışmış ve kimsenin Cicada sayısının avantajlarından yararlanmak için yaşam tarzlarını ayarlayamayacağını fark etmiştir.

Yaşamının çoğu için gizler / engeller, ancak zaman zaman dürtme. Kılıçlara karşı savunmasız olduğundan ve keskin bir sopayla bütün bir döngü harcadığından, ancak sopanızı tamamen körleştirdiğinde keskinleştiğinden emin misiniz? Bu tam olarak diğerlerinin beklediği şey ... bu ağustosböceği değil

derlemek için: mcs program.cs mono program.exe'yi çalıştırmak için

public class PeriodicalCicadaCaveman
{
  const int Periodic = 13; //Could be 17
  public static void Main(string[] args)
  {
    if (args.Length == 0) 
    {
          System.Console.WriteLine("S");
          return;
    }
    var arg1 = args[0];
    if(arg1.Length == 0) 
    {
        //Always start with a sharp stick
        System.Console.WriteLine("S");
        return;
    }
    var myHistory = arg1.Split(',')[0];
    var theirHistory = arg1.Split(',')[1];
    int sharpness = 0;
    int timeElapsed =  myHistory.Length;

    for(int i = 0; i < timeElapsed; i++)
    {
        if(myHistory[i] == 'S')  
        {
            sharpness++;
        }
        if(myHistory[i] == 'P')
        {
            sharpness--;
        }
    }

    if((myHistory.Length % 13) == 0 
            || timeElapsed > 90 // Running out of time! To hell with the routine
        )
    {
        //The Secada strikes!
        if(sharpness > 1)
        {
            System.Console.WriteLine("P");
            return;
        }
        else
        {
            System.Console.WriteLine("S"); 
            return;
        }
    }
    System.Console.WriteLine("B"); 

  }

}

Düzenleme: Keskinliği değiştirdi-- kod ... ya dürttüğümde kazandım ya da çubuğum duller oldu

Düzen2: Bobs önerisine eklendi

Düzenleme: Sadece keskinlikte 2 iken dürtmek için değiştirildi, sopa hiç sıfır değilse, diğer adam bir kılıç yapabilir.


1
Ubuntu'da koşuyorum; bu Mono altında derlenir mi? Eğer öyleyse, onu nasıl derlerim ve nasıl çalıştırırım?
Doorknob

Dürüst olmak gerekirse, bilmiyorum. Ben sadece yatmaya başlıyorum. Yarın sabah işte Java'ya yeniden yazabilirim. Java kodu neredeyse aynı olmalıdır.
Mikey Mouse

5
@Doorknob mcs program.csonu derleyecek, mono programçalıştıracak, ancak foo.Dump();s ile değiştirmeniz gerekecek System.Console.WriteLine(foo);(ya da bir uzatma yöntemi eklemelisiniz public static void Dump(this string value) { System.Console.WriteLine(value); }).
Bob,

@Bob Teşekkürler dostum, uzatma yönteminize ekledim.
Mikey Mouse

Üzgünüz, gerçek varsayılan dosya ismi mcsoluşturuyor <filename>.exe, mesela program.csolur program.exe. Yani run komutu olacaktır mono program.exe. (Daha önceki
Bob

14

FancyTechnoAlgorithm

Fantezi tekno bilgisayar programı için fantazi tekno algoritması.

Mağara adamı savaşı kaybetmeye devam eder. Mağara adamı kızgın. Yani mağara adamı bilgisayar okuluna gidip algoritma yapmayı öğrenir.

import random, sys  # Need import some advanced techno code

if __name__ == '__main__':  # If fancy techno computer program is main

    try:  # Me try use fancy techno algorithm!

        me, he     = sys.argv[1].split(",")
        mePointy   = me.count("S") - me.count("P")
        hePointy   = he.count("S") - he.count("P")
        meCanPoke  = mePointy > 0
        heCanPoke  = hePointy > 0
        meHasSword = mePointy >= 5
        heHasSword = hePointy >= 5
        meScary    = meCanPoke + meHasSword 
        heScary    = heCanPoke + heHasSword

        # Me donno fancy coding math algoritm.
        # Math confuse. Me code work, me happy.
        if he[-6:] == "SB"*3:
            print "SP"[meCanPoke]
        elif (len(he) > 30 and he[-3:].count("B") > 2) or \
             (hePointy > 2 and he.count("SSBB") > 0 and he.count("BBS") > 0):
            if meHasSword:
                print "P"
            else:
                print "SB"[me[-1] == "S"]
        elif hePointy > 3 and he.count("BBS") > 2:
            print "SP"[me[-1] == "S"]
        else:
            print random.choice(\
                [["S", "SP", "P" ],\
                 ["B", "B" , "P" ],\
                 ["S", "P" , "P" ]][heScary][meScary])

    except:  # Fancy techno algorithm Failed... Me just sharpen.
        print "S"

Python 2 programı. Koşmak:python fancytechnoalgorithm.py


Bu, giriş olmadığında kırılır (ilk dönüşte). Bununla nasıl baş etmek istediğinizi bilmiyorum, bu yüzden ilk test aşamasından çıkarmak zorunda kalacağım.
Doorknob

@Doorknob İlk giriş için "," veya "" mi? Sanırım ondan ikincisi.
Vectorized

İlk girdi için, argüman olmayacak (olarak çalıştırılacak python StickSharpener.py).
Doorknob

@Doorknob Düzenledim. Şimdi işe yarayıp yaramadığını gör.
Vectorized

Tamam, teşekkürler! Bunu bir sonraki davaya dahil edeceğim.
Doorknob

14

İzleyici

Rakibinin hareketlerini izler, her zaman grev yapmadan önce ellerini göstermelerini sağlar. Özellikle bir kılıç için çalışmayı ihmal edenler için hazırlanmıştır.

import sys, random

if len(sys.argv) > 1:
    history_self, history_other = sys.argv[1].split(',')
else:
    history_self = history_other = ""

def sharpness(history):
    ret = 0
    for action in history:
        if action == 'S':
            ret += 1
        elif action == 'P' and ret > 0:
            ret -= 1
    return ret

def weighted_random(dict):
    i = random.randrange(sum(dict.values()))
    for k, v in dict.items():
        i -= v
        if i < 0:
            return k

def action(history_self, history_other):
    sharpness_self = sharpness(history_self)
    sharpness_other = sharpness(history_other)
    if sharpness_self >= 5:
        return 'P'
    elif sharpness_other == 0:
        return 'S'  #Guaranteed safe
    elif sharpness_other == 1:
        #If the opponent isn't interested in a sword, time is on our side
        block_count = len(history_self) - len(history_self.rstrip('B'))
        if block_count > 3 and random.randrange(block_count) > 3:
            return 'S'
        else:
            return 'B'
    elif sharpness_other >= 5:
        return 'S'
    else:
        #Search for a weakness
        for i in range(10, 2, -1):
            if history_other[-i:] == history_other[-i*2:-i]:
                predicted_action = history_other[-i]
                if predicted_action == 'S':
                    if sharpness_self > 0:
                        return 'P'
                    else:
                        return 'S'
                elif predicted_action == 'B':
                    return 'S'
                elif predicted_action == 'P':
                    return 'B'
        #Presumably the opponent is random - respond with some educated randomness
        if sharpness_self == 0:
            return random.choice(['S','S','B'])
        return weighted_random({
            'S': sharpness_self,
            'B': 1,
            'P': sharpness_other,
        })

if __name__ == "__main__":
    print(action(history_self, history_other))

Dosya adı: watcher.py

Koşmak: python watcher.py

basilikos

Ona çok yakından bakanları yok etmek istiyor. Tutarlı bir şekilde İzleyiciyi yener, ancak genel olarak daha da kötüye gidecektir.

import sys, random

if len(sys.argv) > 1:
    history_self, history_other = sys.argv[1].split(',')
else:
    history_self = history_other = ""

def sharpness(history):
    ret = 0
    for action in history:
        if action == 'S':
            ret += 1
        elif action == 'P' and ret > 0:
            ret -= 1
    return ret

def action(history_self, history_other):
    sharpness_self = sharpness(history_self)
    sharpness_other = sharpness(history_other)
    if sharpness_self >= 5:
        return 'P'
    elif len(history_self) < 13:
        return 'SBBSBPSBBSBPP'[len(history_self)]
    elif 5 + 5 * sharpness_self < random.randrange(len(history_self)):
        return 'S'
    elif sharpness_other == 0:
        if sharpness_self == 0 or random.randrange(sharpness_self) == 0:
            return 'S'
        else:
            return 'P'
    elif sharpness_other == sharpness_self:
        return 'P'
    else:
        return 'B'

if __name__ == "__main__":
    print(action(history_self, history_other))

Dosya adı: basilisk.py

Koşmak: python basilisk.py

Nash

Risklerini ve ödüllerini hesaba katan bir olasılıkla her hareketi seçerek rakibinin seçimlerini alakasız hale getirmeye çalışır

import sys, random

if len(sys.argv) > 1:
    history_self, history_other = sys.argv[1].split(',')
else:
    history_self = history_other = ""

movemap = [ [(1.000000,0.000000),(0.473863,0.526137),(0.394636,0.605364),(0.490512,0.509488),(1.000000,0.000000)],
        [(0.695328,0.000000,0.304672),(0.275953,0.582347,0.141700),(0.192635,0.700391,0.106974),(0.196343,0.689662,0.113995),(0.289968,0.544619,0.165413)],
        [(0.570635,0.000000,0.429365),(0.236734,0.570126,0.193139),(0.167197,0.687133,0.145670),(0.173139,0.667169,0.159693),(0.264911,0.475316,0.259773)],
        [(0.490512,0.000000,0.509488),(0.196309,0.578888,0.224803),(0.135744,0.692358,0.171898),(0.140638,0.663397,0.195965),(0.220709,0.426989,0.352302)],
        [(1.000000,0.000000,0.000000),(0.147944,0.636760,0.215296),(0.089478,0.737358,0.173165),(0.087259,0.704604,0.208137),(0.128691,0.435655,0.435655)]  ]

def sharpness(history):
    ret = 0
    for action in history:
        if action == 'S':
            ret += 1
        elif action == 'P' and ret > 0:
            ret -= 1
    return ret

def action(history_self, history_other):
    sharpness_self = sharpness(history_self)
    sharpness_other = sharpness(history_other)
    if sharpness_self >= 5:
        return 'P'
    elif sharpness_other >= 5:
        return 'S'
    moves = movemap[sharpness_self][sharpness_other]
    v = random.random()
    if v < moves[0]:
        return 'S'
    elif v < moves[0] + moves[1]:
        return 'B'
    else:
        return 'P'

if __name__ == "__main__":
    print(action(history_self, history_other))

Bu tam olarak Nash dengesi değil (strateji oluşturucumun kararsızlığı var), ama yakın.

Merak uğruna, işte bu botun her oyunda kazanma ihtimalinin tahminleri:

map = [ [0.50000000,0.26337111,0.15970733,0.08144046,0.00000000,0.00000000],
        [0.73662889,0.50000000,0.37879183,0.28035985,0.16622410,0.00000000],
        [0.84029267,0.62120817,0.50000000,0.39441630,0.26038353,0.00000000],
        [0.91855954,0.71964015,0.60558370,0.50000000,0.35246401,0.00000000],
        [1.00000000,0.83377590,0.73961647,0.64753599,0.50000000,0.00000000],
        [1.00000000,1.00000000,1.00000000,1.00000000,1.00000000,0.50000000] ]

Dosya adı: nash.py

Koşmak: python nash.py

Çalım

Rakibinin savunmasını test etmek için hızlı bir saldırı ile açılır.

import sys, random

if len(sys.argv) > 1:
    history_self, history_other = sys.argv[1].split(',')
else:
    history_self = history_other = ""

def sharpness(history):
    ret = 0
    for action in history:
        if action == 'S':
            ret += 1
        elif action == 'P' and ret > 0:
            ret -= 1
    return ret

def action(history_self, history_other):
    sharpness_self = sharpness(history_self)
    sharpness_other = sharpness(history_other)
    if sharpness_self >= 5:
        return 'P'
    elif len(history_self) < 2:
        return 'SP'[len(history_self)]
    elif history_other[1] == 'P':
        # Fierce fight
        if sharpness_self == 0:
            return 'S'
        elif history_self[-(1 + history_self.count('P'))] == 'S':
            return 'P'
        else:
            return 'B'
    else:
        # Smart guy
        if sharpness_other == 1:
            return 'B'
        elif history_self[-1] != 'S' or history_self[-4:] == 'BSBS':
            return 'S'
        elif history_other.count('S') > history_other.count('B'):
            return 'P'
        else:
            return 'B'

if __name__ == "__main__":
    print(action(history_self, history_other))

Dosya adı: feint.py

Koşmak: python feint.py

LatePokeBot

PokeBot'un küçük kardeşi. Asla zayıflık göstermez, ama büyük kardeşi gibi savaşmaya çalışır.

import sys, random

if len(sys.argv) > 1:
    history_self, history_other = sys.argv[1].split(',')
else:
    history_self = history_other = ""

def sharpness(history):
    ret = 0
    for action in history:
        if action == 'S':
            ret += 1
        elif action == 'P' and ret > 0:
            ret -= 1
    return ret

def action(history_self, history_other):
    sharpness_self = sharpness(history_self)
    return 'SSP'[sharpness_self]

if __name__ == "__main__":
    print(action(history_self, history_other))

Dosya adı: latepokebot.py

Koşmak: python latepokebot.py


:Basilisk'te bir eksikti ; Bunu senin için düzelttim
Doorknob

Bu gönderi bir noktada bir çeşit hata veya istisna attı; Bir sonraki denemelerden önce bunu düzeltmek isteyebilirsiniz. (Basiliks bir)
Doorknob

@Doorknob İzleyici ve Mağara Doktoru tarafından yapılan varsayımlara bakarak ve bu varsayımların çok yanlış gitmesine neden olacak bir dizi bularak Basilisk'in başlangıç ​​sırasını seçtim. Bu "mağara adamı adil" kuralını ihlal ediyor mu?
Brilliand

Nash'e git! P = 0 seçeneklerinden kaçınmak için tüm botlara karşı tam olarak yarısını kazan!
aschepler

12

PokeBot

Ruby'de yazıldı.

puts((ARGV.shift || "P,").match(/(.),/)[1] == "P" ? "S" : "P")

İle koş ruby pokebot.rb.

Bu bot çok akıllı değil; Ortalama mağara adamının kendi başına ne yapacağı ile ilgili.


9

PatientWolf v2.0

Körelirse keskinleşir, düşmanın bir sonraki dönüşünde bir kılıcı olacaksa dürter veya düşmanın donuk olması durumunda, aksi halde bloke eder.

my ($me,$him) = split(/,/,$ARGV[0]);
if(!defined $me) {
    print "S";
    exit;
}
my $mysharpness =()= ($me =~ /S/g);
$mysharpness -= ($me =~ /P/g);
my $opponentsharpness =()= ($him =~ /S/g);
$opponentsharpness -= ($him =~ /P/g);
if($mysharpness == 0) {
    print "S";
} elsif($opponentsharpness <= 0 || $opponentsharpness == 4) {
    print "P";
} else {
    print "B";
}

İle koş

perl patientwolf.pl

EDIT: bir hatayı işaret ettiği için @sylwester sayesinde


Her iki geçmişi de virgülle ayırarak yalnızca tek bir tartışma aldığınız için yanlış bir şekilde ayrıştırıyorsunuz. Örneğin. keskin bir sopa olduğunu düşündüğünden beri bunu PatientWolf.pl SB,SPyapar P.
Sylwester

@Sylwester doğru değil. İlk satır, ilk argümanı bana $ a, ikinci argümanı $ 'a atar
müthiş

CavemanDuel programı sadece bir tane olmak üzere iki argüman kullanmaz. Örneğin. perl patientwolf.pl "SB,SP". Yapmalısın my($me,$him) = split/,/ $ARGV[0];ve if( @ARGV ) {print "S";exit}.
Sylwester

@Sylwester ok Neye bulaştığını görüyorum. OP’den veya denetleyici koduna attığım hızlı bakıştan net değildi. Bunu kısa zamanda düzelteceğim
müthiş

9

İkili mağara adamı

Keskinleştir, Kes, Tekrarla

Engellemenin sissies için olduğu fikrine dayanarak, bu mağara adamı kalan iki seçenek arasında geçiş yapar.

public class BinaryCaveman { 

    public static void main(String[] args) {
        int timelapse = 0;
        if(args.length>0)
        {
            timelapse = ((args[0].length() - 1) / 2);
        }
        switch(timelapse % 2) 
        {
            case 0: System.out.println('S'); 
                    break;
            case 1: System.out.println('P'); 
                    break;
        }
    }
}

İle derleyin javac BinaryCaveman.java

İle koş java BinaryCaveman

EDIT: String Arrays'deki Maceralar ..... args.length () hata atar. args.length her zaman 1 değerini döndürür. args [0] .length () dizideki ilk dizenin uzunluklarını döndürür.

EDIT 2: Doorknob, Brilliand ve Sylwester'ın yardımları sayesinde güncellendi. Teşekkürler beyler.


@ MartinBüttner Tek bir oyuncu tarafından sadece geçmiş başvuruların sayısını almak için arıları - 2'ye bölmeyi unuttum. Bunu düzeltdim. Dorknob'un teslimiyetini anlayamıyorum, Ruby neredeyse bana saçma sapan. Her zaman keskinleştirme ile başlar mı?
Red_Shadow

Evet, bu da o son hareket olup olmadığını kontrol eder Pya Sve tersini yapar. Ve eğer henüz bir tarih yoksa, tarihin olacağını iddia eder P,(o zaman onu önce yapar S).
Martin Ender

Aynı çıktıyla sonuçlanan iki farklı yaklaşım. Bu kurallara aykırı mı?
Red_Shadow

Muhtemelen hayır, sadece size bildiririm.
Martin Ender

2
@Doorknob bunun olması gerektiğini düşünüyorum args[0].length(), değil args.length.
Brilliand

8

CavekidBlocks

Ağlayan ve korkmuş bir mağara çocuğu kolay bir av gibi görünebilir. Güzel yüzünün seni kandırmasına izin verme çünkü nasıl engelleneceğini biliyor.

import sys, math, random
def count(a):
    s = 0
    for i in range(len(a)):
        if a[i] == 'P': s-=1
        elif a[i] == 'S': s+=1
        if s < 0: s = 0
    return s
kid = []
scary_adult = []
what2do = 'Sharpen the Stick! Why not? Adult may be doing the same. DONT trust adults!'
if len(sys.argv) > 1:
    kid, scary_adult = sys.argv[1].split(",")
    kid_stick_sharpness = count( kid )
    scary_adult_stick_sharpness = count( scary_adult )
    if (scary_adult_stick_sharpness >= 2):
        what2do = "Block! Block! Block! Adult's stick looks scary sharp."
    elif (kid_stick_sharpness > 0):
        what2do = 'Point your Stick to the adult. It may scary him.'
    else:
        what2do = 'Sharpen the Stick!'

    # Roll d20 for a courage check.
    dice = random.randint(1,20)
    if (dice > 15): what2do = 'Poke the adult! Critical Hit!'
    elif (dice <= 5): what2do = 'Block! Block! Block!'
print(what2do[0])

İle koş python3 cavekidblocks.py

ChargerMan

Bu mağara adamı çok muhafazakar. Silahını şarj etmeye çalışacağım ve sadece gerektiğinde saldırıları yapacağız.

import sys, math, random
def countSharpness(a):
    s = 0
    for i in range(len(a)):
        if a[i] == 'P': s-=1
        elif a[i] == 'S': s+=1
        if s < 0: s = 0
    return s
def getHistory():
    me = ""
    him = ""
    if len(sys.argv) > 1:
        me, him = sys.argv[1].split(",")
    return me,him
if __name__ == '__main__':
    me, him = getHistory()
    me_s = countSharpness(me)
    him_s = countSharpness(him)
    answer = 'B'
    # First Case
    if (len(me) == 0):
        answer = 'S'
    # I have a sword
    elif (me_s == 5):
        answer = 'P'
    # Cant let he gets a sword
    elif (him_s == 4):
        answer = 'P'
    # His sword is dull
    elif (him_s == 0):
        # He may try to sharp
        # Cant attack? Sharp my stick
        if (me_s == 0): answer = 'S'
        else:
            if (random.randint(0,33) != 0): answer = 'S'
            else: answer = 'P'
    elif (len(him) % 5 == 0):
        # Decide what to do based on the
        # opponent last 3 movements.
        hist = him[-3:]
        # Does he like to block?
        if (hist.count('B') >= 2): answer = 'S'
    print(answer)

İle koş python3 chargerman.py

düzenbaz

Trickster nasıl savaşılacağını bilmiyor, bu yüzden diğer mağara adamlarını şaşırtmaya çalışıyor.

import sys, math
a = "PPS"
i = 0
if (len(sys.argv) > 1): i = math.floor(((len(sys.argv[1])-1)/2) % 3)
print(a[i])

İle koş python3 trickster.py

Maalesef, acc74 kararından sonra , Trickster artık planlandığı gibi çalışmıyor.


4
Bu hileci programı kötü
Nexus

@Nexus Ben de öyle olsa. Ne yazık ki Trickster düellolarda iyi iş çıkarmıyor.
wendelbsilva

7

Hodor

Hodor çok agresif değil. Grev yapmak için iyi bir fırsat olmadığı sürece kalkanında kalmayı sever.

Şununla derleyin: javac Hodor.javave çalıştırın:java Hodor

kod:

public class Hodor {
    public static void main(String[] args){

        String previousMoves = null;

        //account for no input
        if(args.length == 0){
            System.out.print('S');
            System.exit(0);
        }else{
            previousMoves = args[0];
        }

        //declare variables
        char action = 'S';
        int enemySharpens = 0, enemyPokes = 0, myPokes = 0, mySharpens = 0;
        String[] movesArray = previousMoves.split(",");
        char[] enemyMoves = movesArray[1].toCharArray(), myMoves = movesArray[0].toCharArray();

        //determine enemy sharpness
        for(int i=0; i<enemyMoves.length; i++){
            if(enemyMoves[i] == 'S'){
                enemySharpens++;
            }else if(enemyMoves[i] == 'P'){
                enemyPokes++;
            }
        }

        //block if opponent can poke, else sharpen
        if(enemySharpens - enemyPokes > 0){
            action = 'B';
        }else{
            action = 'S';
        }

        //determine my sharpness
        for(int i=0; i<movesArray[0].length(); i++){
            if(myMoves[i] == 'P'){
                myPokes++;
            }else if(myMoves[i] == 'S'){
                mySharpens++;
            }
        }

        //poke as much as possible if the game is about to end
        if((mySharpens-myPokes) > (100-enemyMoves.length)){
            action = 'P';
        }

        try{
            //sharpen if opponent blocks 2 times in a row and I didn't just sharpen
            if((enemyMoves[enemyMoves.length-1] == 'B') && (enemyMoves[enemyMoves.length-2] == 'B') && (myMoves[myMoves.length-1] != 'S')){
                action = 'S';
            }
            //poke if opponent sharpens twice in a row
            if((enemyMoves[enemyMoves.length-1] == 'S') && (enemyMoves[enemyMoves.length-2] == 'S')){
                action = 'P';
            }
            //poke if the opponent just sharpened/blocked then poked, has a blunt stick, and my stick isn't blunt
            if((enemyMoves[enemyMoves.length-2] != 'P') && (enemyMoves[enemyMoves.length-1] == 'P') && (enemySharpens-enemyPokes == 0) && (mySharpens - myPokes > 0)){
                action = 'P';
            }
        }catch (ArrayIndexOutOfBoundsException e){
            //not enough info
        }

        //poke if we have a sword
        if(mySharpens-myPokes > 4){
            action = 'P';
        }

        System.out.print(action);
    }
}

Düzenleme: küçük kod güncellemesi


Bu gönderi bir noktada bir çeşit hata veya istisna attı; Bir sonraki denemelerden önce bunu düzeltmek isteyebilirsiniz.
Doorknob

1
İle deneyin SB,BB. Diğer mağara insanları ilk yaramazlıkta düştüğünde Hodor da yaramazlık yapar.
Sylwester

7

Spekülatif Sylwester - Perl5

Spekülatif Sylwester, kılıç arayıcılarını kalıplara bakarak çıkarmak istiyor ve rakibin engelleme ihtimalinin yüksek olduğu durumlarda rakibin keskinleşmesi ve keskinleşmesi ihtimalinin olduğu durumlarda dürtüyor. Bununla birlikte, bir sonraki hamlede kendisinin keskinleşeceğini tahmin edebileceği bir şans varsa ve keskinleşmeye karar verdiğimizde daha temkinli olduğumuzda bunu yapmayacaktır.

Rakibi kör olduğu zaman agresif olmaya çalışır, ancak sonuçta sonuçsuz bir kılıç için tasarruf etmeye başlar.

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

## Valid operations
my $SHARPEN = "S";
my $POKE    = "P";
my $BLOCK   = "B";

## It will also print resolution to stderr
my $VERBOSE = 0;

my $first_move = not @ARGV;
my ($me, $you) = split(',', $ARGV[0]) unless( $first_move );

## What do I do?
me_do($SHARPEN, "beginning") if $first_move;
me_do($POKE, "end is near") if  almost_over() || sword($me);
me_do($SHARPEN, "you sword") if !sword($me) && sword($you);
me_do($POKE, "you repeat") if consecutive_sharpens($you) && sharp($me);
me_do(blunt_move(), "you blunt stick") if not sharp($you); 
me_do(aggressive_move(), "me think you sharpen") if sharpen_next($you) && !sharpen_next($me);
me_do($SHARPEN, "me think you block") if you_block_next() && very_little_chance_me_sharpen_next();
me_do($BLOCK, "me have no idea you do");

sub almost_over {
  sharp($me) >= (100 - length($you));
}

sub sharp {
  my $history = shift;
  my $sharp = 0;
  foreach my $s ( split('',$history) ) {
    $sharp++ if( $s eq "S");
    $sharp-- if( $s eq "P" && $sharp > 0);
  }
  return $sharp;
}

sub sword {
  my $me = shift;
  sharp($me) >= 5;
}

sub num_pokes {
  my $me = shift;
  $me =~ s/[^P]//g; #/ SO highlight bug?
  length($me);
}

sub consecutive_sharpens {
  my $you = shift;
  $you =~ m/SS+$/
}

sub sharpen_next {
  my $you = shift;
  $you =~ /([^S]+)S\1S\1$/;
}

sub you_block_next {
  $you =~ /([^B]+B*)B\1B\1$/ || $you =~ /B{4}$/;
}

sub very_little_chance_me_sharpen_next {
  $me !~ /S$/ && ( $me !~ /([^S]+)S\1$/ || $me =~ /^SB+SB+$/ ); 
}

sub blunt_move {
  my $sword_move = sword($me) ? $POKE : $SHARPEN;
  ( $me =~ m/(?:PS){5,}/ || sharp($me)*7 < num_pokes($me) ? $sword_move : aggressive_move() );
}

sub aggressive_move {
  sharp($me)? $POKE : $SHARPEN;
}

sub me_do {
  my ($stick_operation, $reason) = @_;
  my $arg = ( $first_move ? "" : "$me,$you" );
  my $resolution = "$stick_operation me do because $reason ($arg)";
  print "$resolution\n";
  err($resolution);
  exit;
}

sub err {
  my($str) = @_;
  print STDERR "SpeculativeSylwester:$str\n" if $VERBOSE;
}

Linux üzerinde çalıştırmak için bunu playerlist.txt dosyasına eklemeniz yeterli:

perl players/SpeculativeSylwester/SpeculativeSylwester.pl

Facile Fibonacci - R6RS Şeması

İlk hamlenin yanı sıra, Facile Fibonacci, Fibonacci sayısı olduğunda (0'dan başlayarak) blokları engeller PPSS..ve 8'i PSSbir kılıçla kazanmak için sonsuz bir sekansa geçtiğinde değişir .

#!r6rs
(import (rnrs base)
        (only (rnrs) fold-left display command-line))

(define %SHARPEN "S")
(define %POKE    "P")
(define %BLOCK   "B")

(define (fibonacci? n)
  (let loop ((a 1) (b 1))
    (cond ((> a n) #f)
          ((= a n) #t)
          (else (loop b (+ a b))))))

(define (poke? num-sp)
  (if (< num-sp 8)
      (even? (div num-sp 2))
      (= 2 (mod num-sp 3))))

(define (split-string x)
  (let ((len (div (string-length x) 2)))
    (substring x 0 len)))

(define (num-sp x)
  (fold-left (lambda (a x)
               (if (eqv? x #\B) a (+ a 1)))
               0
               (string->list x)))

(define (advanced-strategy me)
  (cond ((fibonacci? (string-length me)) %BLOCK)
        ((poke? (num-sp me)) %POKE)
        (else %SHARPEN)))

(define (decide args)
  (if (= (length args) 1)
      %SHARPEN
      (advanced-strategy (split-string (cadr args)))))

;; The dirty imperative code:
(display (decide (command-line)))

Sadece ikarus'u kurmak apt-get install ikarusve playerlist.txt dosyasına eklemek için:

ikarus --r6rs-script players/FacileFibonacci/FacileFibonacci.scm

Çalışkan Sylwester - Perl5

Çalışkan Sylwester, Spekülatif Sylwester ile aynı taktiği kullanıyor, ancak yanlış bir seçim yapabileceği yeri belirlemek için önceki oyunlara da bakıyor.

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

## Valid operations
my $SHARPEN = "S";
my $POKE    = "P";
my $BLOCK   = "B";

## It will also print resolution to stderr
my $VERBOSE = 0;

my $path = $0; # "players/StudiousSylwester/StudiousSylwester.pl";
my $first_move = not @ARGV;
my ($me, $you) = split(',', $ARGV[0]) unless( $first_move );

## What do I do?
me_do($SHARPEN, "beginning") if $first_move;
me_do(consult_history($POKE, "end is near")) if  almost_over() || sword($me);
me_do(consult_history($SHARPEN, "you sword")) if sword($you);
me_do(consult_history($POKE, "you repeat")) if consecutive_sharpens($you) && sharp($me);
me_do(consult_history(blunt_move(), "you blunt stick")) if not sharp($you);
me_do(consult_history(aggressive_move(), "me think you sharpen")) if sharpen_next($you) && !sharpen_next($me);
me_do(consult_history($SHARPEN, "me think you block")) if you_block_next() && very_little_chance_me_sharpen_next();
me_do(consult_history($BLOCK, "me have no idea you do"));

sub almost_over {
  sharp($me) >= (100 - length($you));
}

sub sharp {
  my $history = shift;
  my $sharp = 0;
  foreach my $s ( split('', $history) ) {
    $sharp++ if( $s eq "S");
    $sharp-- if( $s eq "P" && $sharp > 0);
  }
  return $sharp;
}

sub sword {
  my $me = shift;
  sharp($me) >= 5;
}

sub num_pokes {
  my $me = shift;
  $me =~ s/[^P]//g; #/ SO highlight bug?
  length($me);
}


sub consecutive_sharpens {
  my $you = shift;
  $you =~ m/SS+$/
}

sub sharpen_next {
  my $you = shift;
  $you =~ /([^S]+)S\1S\1$/;
}

sub you_block_next {
  $you =~ /([^B]+B*)B\1B\1$/ || $you =~ /B{4}$/;
}

sub very_little_chance_me_sharpen_next {
  $me !~ /S$/ && ( $me !~ /([^S]+)S\1$/ || $me =~ /^SB+SB+$/ );
}

sub blunt_move {
  my $sword_move = sword($me) ? $POKE : $SHARPEN;
  ( $me =~ m/(?:PS){5,}/ || sharp($me)*7 < num_pokes($me) ? $sword_move : aggressive_move() );
}

sub aggressive_move {
  sharp($me)? $POKE : $SHARPEN;
}


sub consult_history {
  my ($suggested_move, $why) = @_;
  my $mylen = length($me);

  # By demanding 5 or more there are 81 (- illegals)
  # different possibilities. Below that and
  # we are shooting in the dark.
  return @_ if( $mylen <= 4 );

  my $override = $suggested_move;
  my @lines = ();
  my %matches      = (P => 0, B=> 0, S=> 0);
  my %match_prefix = (P => 0, B=> 0, S=> 0);
  my $file = "$path.prefix";
  my $sem = "$path.sem";
  my $found_session = 0;

  # Since Judge is running multiple instances at the same time we flock
  open(LOCK, "> $sem") || die ("$path error while open $sem: $!");
  flock(LOCK, 2);

  if( -e $file ) {
    open(FH, $file) || die("$path: error while open $file: $!");

    my $prevyou = substr($you,0,-1);
    while(my $ln = <FH>){
      if ( $ln =~ m/^$me(.).*,$you(.?).*$/ ) {
         # Match that ends here is either a win or a loss depending on my choice
     my $key = ($2 eq "" ? ( $1 eq $POKE ? $SHARPEN : $POKE ) : $2);
     $matches{$key}++;
     $match_prefix{$1}++;
      }
      if( $ln =~ m/^$me,$prevyou$/ ) {
        $found_session++;
    next;
      }
      $found_session++ if( $ln =~ m/^$me.*,$prevyou.*$/ );
      push @lines,$ln;
    }
  }

  my $num_matches = (grep { $matches{$_} != 0 } keys %matches);
  unless( $num_matches || $found_session || $mylen == 5 ) {
    err("WARNING: You have not started this game from the beginning. This will not be a valid outcome! ($me,$you)");
  }

  if( $num_matches == 1 ) {
    my $match_val = (grep { $matches{$_} != 0 } keys %matches)[0];
    if( $match_val eq $BLOCK && !sharp($me)) {
      $override = $SHARPEN;
      $why = "me know u block";
    } elsif ( $match_val eq $SHARPEN ) {
      $override =  aggressive_move();
      $why = "me know u sharpen";
    } elsif ( $match_val eq $POKE && !sword($me) ) { 
      $override = $BLOCK;
      $why = "me know u poke";
    }

  } elsif($num_matches > 1 && $mylen > 6 ) {
    # if the chances are overwelming we are not poked we might as well sharpen
    # if we are wrong here we loose
    if( $matches{$POKE} * 4 < ($matches{$BLOCK}+$matches{$SHARPEN}) && !sword($me)){
      $override = $SHARPEN;
      $why = "me think u block/sharpen";
    }
    # if chances for sharpening is higher than poke/block we go for it with any stick
    if( $matches{$SHARPEN} > 2*($matches{$BLOCK}+$matches{$POKE}) && sharp($me) ) {
      $override = $POKE;
      $why = "me think u sharpen";
    }

    # if the chances for poke is overwelming, we might consider blocking
    if( $matches{$POKE} > 2*($matches{$BLOCK}+$matches{$SHARPEN}) && !sword($me)){
      $override = $BLOCK;
      $why = "me think u poke";
    }
  }

  unless ( $match_prefix{$override} ) {
    open( FH, "> $file") ||     die("$path: error while open $file: $!");
    push @lines, "$me$override,$you\n";
    foreach my $line ( sort @lines ) {
      print FH $line;
    }
  }

  my $stats = join("",map {"$_=>$matches{$_} "} keys %matches);

  if( $override ne $suggested_move ) {
     $why .= ". stats: $stats, original choice: $suggested_move";
  }

  close FH;
  close LOCK;

  return ( $override, $why );
}

sub me_do {
  my ($stick_operation, $reason) = @_;
  my $arg = ( $first_move ? "" : "$me,$you" );
  my $resolution = "$stick_operation me do because $reason ($arg)";
  print "$resolution\n";
  err($resolution);
  exit;
}

sub err {
  my($str) = @_;
  print STDERR "StudiousSylwester:$str\n" if $VERBOSE;
}

Linux üzerinde çalıştırmak için bunu playerlist.txt dosyasına eklemeniz yeterli

perl players/StudiousSylwester/StudiousSylwester.pl

Çalışkan düzenleme

$0Perl ile çalıştırıldığında perl betiğinin tam yolu olmamakla ilgili problemleri tekrar edemiyorum . Değişikliklerinizi de çektim ve CavemanDuels src’inde hiçbir değişiklik görmedim ve rapor ettiğiniz herhangi bir sorun olmadan 20 + kez çalıştırıyorum. Senaryoyu çalıştırırken çalıştırmak yerine bash betiği veya perl argümanı olarak kaynaklamış olabileceğinden korkmaya başladım. Emin olmak için daha fazla bilgiye ihtiyacım var. Bir test olarak bunu yaptım ve aynı sonucu alıp almadığınızı görmek için aynısını yapabilirsiniz:

echo '#!/usr/bin/perl
print "$0\n\n";' > testcmd.pl;
perl ./testcmd.pl;           # outputs ./testcmd.pl
bash -c "perl ./testcmd.pl"; # outputs ./testcmd.pl
bash -c ./testcmd.pl;        # outputs an error since it's not executable
chmod 755 ./testcmd.pl;
./testcmd.pl;                # outputs ./testcmd.pl
bash -c ./testcmd.pl;        # outputs ./testcmd.pl since it's executable

Program makinemde benimle işbirliği yapmak istemiyor, bu yüzden Fibonacci'yi test edemedim. Çalışması için çalışmaya devam edeceğim, ancak başka bir dile çevirebilseniz harika olurdu.
Doorknob

Çünkü çalışkan biri de, çalışmak için görünmüyor $0olan bashbir bash komut satırında (kontrolör yapar) çağrıldığında. players/StudiousSylwester/foo.txtYine de sadece kod yazabilirsin .
Doorknob

@Doorknob Nasıl yükleneceğini ikarusekledim $0ve Studious için düşüncelerimi ekledim .
Sylwester,

6

Demirci'nin

Keskin bir sopa gerekir. Eğer keskin bir çubuk varsa, dürtün. Bana acı hissetmiyorum.

program Swordsmith
   implicit none
   integer :: mySharp,ierr,arg_count
   logical :: lExist
   character(38) :: filename = "players/Swordsmith/SwordsmithSharp.txt"

! check argument counts for initialization of storage file
   arg_count = command_argument_count()
   if(arg_count == 0) then
      inquire(file=filename,exist=lExist)
      mySharp = 0
      if(lExist) then
         open(unit=10,file=filename,status='replace')
      else
         open(unit=10,file=filename,status='new')
      endif
      write(10,*) mySharp
      close(10)
   endif

! open, read, & close the file for mySharp
   open(unit=10,file=filename,status='old')
   read(10,*) mySharp
   close(10)

! make decision
   if(mySharp < 5) then
      print '(a1)',"S"
      open(unit=10,file=filename,status='replace')
      mySharp = mySharp + 1
      write(10,*) mySharp
      stop
   endif
   print '(a1)',"P"
end program Swordsmith

Farklı kaydet swordsmith.f90ile derlemek gfortran -o swordsmith swordsmith.f90, normal bir yürütülebilir olarak yürütmek,: ./swordsmith.


Bu, gerçek çıktıdan önce bir boşluk (``) basıyor gibi görünüyor. Bunu nasıl düzelteceğimi bilmiyorum, bu yüzden bu gönderimi ilk test aşamasından çıkarmak zorunda kalacağım.
Doorknob

Ayrıca, dosya yolunuzu düzelttim; Çalıştıkları sırada geçerli çalışma dizini çıkıyor programınızın değil . Oh, ve "yeni örnek" derken "her oyunu" kastediyorsanız, bunu yapamam çünkü bunun için denetleyici programının özel bir şekilde kasetlenmesi gerekir; Bunu kendi kodunuzla yapmak isteyebilirsiniz.
Doorknob

@Doorknob: Kodumu güncelledim: çıktı tek bir karakter, ilk çalıştırmada varolan bir dosyayı siler ve dosya oynatıcı dizinindedir.
Kyle Kanos

Tamam, teşekkürler! Bu gönderi şimdi lider panosuna dahil edildi.
Doorknob

@Doorknob: Harika! Berbat ilk ben değilim. Ayrıca: Fortran kullanıcılarının Vampires gibi olduklarından eminim, bu yüzden yakında Fortran'da kodlamaya başlayacağınızdan eminim! Muahahahaha!
Kyle Kanos

5

PatientBlacksmith

Bu bot R ile yazılmıştır, Rscript PatientBlacksmith.Ronu tetiklemek için kullanınız .

args <- commandArgs(TRUE)
if(length(args)){
    input <- strsplit(strsplit(args,split=",")[[1]],"")
    me <- input[[1]]
    opponent <- input[[2]]
    sharpness <- 0
    for(i in seq_along(opponent)){
        if(opponent[i]=="S") sharpness <- sharpness + 1
        if(opponent[i]=="P") sharpness <- sharpness - 1
        }
    out <- ifelse(sharpness>0,"B","S")
    bfree <- me[me!="B"]
    r <- rle(bfree) #run length encoding
    S_sequence <- r$length[r$value=="S"]
    P_sequence <- r$length[r$value=="P"]
    if(!length(P_sequence)) P_sequence <- 0
    if(tail(S_sequence,1)==5 & tail(P_sequence,1)!=5) out <- "P"
}else{out <- "S"}
cat(out)

Rakip çubuğun keskinliğini ölçer: keskin olduğunda bloklar, aksi halde keskinleştirmek için zaman ayırın. Kendi netliği 5'e ulaştığında, netlik bitene kadar dürtün.


Bu, hiçbir giriş yapıldığında kırılır (ilk dönüşte); Nasıl düzelteceğimi bilmiyorum bu yüzden testin 1. turundan çıkarmam gerekecek.
Doorknob

@Doorknob düzeltildi.
plannapus

5

Cezaevi Kuralları, Haskell

Mağara adamı, mağara adamı ve diğer mağara adamı konuşmalı, çubuğunu paylaşmalı. Ancak, hey ho, kavga etmek gerekirse, cezaevi kurallarıyla savaşın. Patronu bulun ve saldırın.

Şimdi ViceLeader Alpha Caveman; mağara adamı savaşmalı. Diğer mağara adamı sonra kavga eder. Mağara adamım kaybederse endişelenmeyin; Yine de çok kıllı.

import System.Environment


-- Tell caveman next move

next move
    | end with sharp stick  = poke with (what have)
    | they no poky          = sharpen stick
    | me have sword         = poke with sword
    | soon them have sword  = try poke or sharpen
    | soon have own sword   = fear pokes
    | think them want sword = sharpen stick
    | getting bored now     = sharpen stick
    | otherwise             = block poky stick


-- How fancy techno computer program know?

    where
        end with sharp stick = pokiness my stick >= moves before fight boring
        they no poky  = pokiness their stick == 0
        me have sword = pokiness my stick >= 5
        soon "them" have sword = pokiness their stick == 4
        soon have "own" sword  = pokiness my stick == 4
        try poke or sharpen = if pokiness my stick > 0
                              then poke with stick
                              else sharpen stick
        fear pokes = count 2 (block poky stick) and (sharpen stick)
        think them want sword = pokiness their stick == 3
        getting bored now = those last 2 mine same

        what have
            | me have sword = sword
            | otherwise     = stick



-- Rest not for caveman - only techno computer

        moves before time up = time - (length . fst $ move)

        and   = my
        mine  = my
        my    = fst move
        their = snd move

        before = "before"
        bored  = "bored"
        boring = "boring"
        have   = "have"
        no     = "no"
        now    = "now"
        own    = "own"
        pokes  = "pokes"
        same   = "same"
        sharp  = "sharp"
        them   = "them"
        want   = "want"


fight = 100


main = do
    movesHistoryEtc <- getArgs
    putStrLn . next . basedOn $ movesHistoryEtc


basedOn = movesOfEachCaveman . history

history []    = ""
history (h:_) = h

movesOfEachCaveman "" = ("", "")
movesOfEachCaveman h  = (\(a, b) -> (a, tail b)) . span (/= ',') $ h


sharpened = 'S'
poked     = 'P'
blocked   = 'B'

times m = length . filter (== m)


with  = "WITH"
poky  = "POKY"
sword = "SWORD"
stick = "STICK"

sharpen stick    = "SHARPEN " ++ stick
block poky stick = "BLOCK " ++ poky ++ " " ++ stick
poke with stick  = "POKE " ++ with ++ " " ++ stick


pokiness stick is = foldl countPokiness 0 stick

countPokiness pokyPoints 'P'
    | pokyPoints > 0         = pokyPoints - 1
    | otherwise              = 0
countPokiness pokyPoints 'S' = pokyPoints + 1
countPokiness pokyPoints  _  = pokyPoints


allLast n x xs = all (== x) $ take n . reverse $ xs

those previous n moves same = ((length moves) >= n)
                           && (allLast n (last moves) moves)

count n firstMoves moveHistory lastMove = if allLast n fm moveHistory
                                          then lastMove
                                          else firstMoves
    where fm = head firstMoves

Haskell ile yazılmış (işlevsel programlamaya gidin!), Bu yüzden prisonrules.hs olarak kaydedin , sonra:

ghc prisonrules.hs

Ve şu şekilde koş:

prisonrules [history]

4

Ona JavaMan diyoruz

compile: javac JavaMan.java
run: java JavaMan SPB,SBB

not: Kod golf oynamak istemiyorum .. ama eğer bir golfçüyseniz ve boşlukları / ekstra çizgiler gözlerinizi kanaştırırsa .. değiştirmek için çekinmeyin

public class JavaMan
{
    public static void main(String[] args)
    {
        // input: SPB,SBB
        // me, enemy
        // S: sharpen, P: poke, B: block

        if (args.length == 0)
        {
            System.out.println("S");
        }
        else
        {
            String[] states = args[0].split(",");
            Player me = new Player(states[0].toCharArray());
            Player enemy = new Player(states[1].toCharArray());  //fixed thanks to Roy van Rijn

            if (me.hasSword())
            {
                System.out.println("P");
            }
            else if (!enemy.canPoke())
            {
                if (me.canPoke() && (Math.random() * 95) < states[0].length())
                {
                    System.out.println("P");
                }
                else
                {
                    System.out.println("S");
                }
            }
            else if (enemy.hasSword())
            {
                if (me.canPoke())
                {
                    System.out.println("P");
                }
                else
                {
                    System.out.println("S");
                }

            }
            else if (enemy.canPoke())
            {
                if (me.canPoke())
                {
                    if ((Math.random() * 95) < states[0].length())
                    {
                        System.out.println("P");
                    }
                    else
                    {
                        System.out.println("B");
                    }
                }
                else
                {
                    if ((Math.random() * 95) < states[0].length())
                    {
                        System.out.println("S");
                    }
                    else
                    {
                        System.out.println("B");
                    }
                }
            }
            else
            {
                System.out.println("S");
            }
        }
    }

}

class Player
{
    int sharpLevel;

    public Player(char[] state)
    {
        sharpLevel = 0;
        for (char c : state)
        {
            switch (c)
            {
            case 'S':
                sharpLevel++;
                break;
            case 'P':
                sharpLevel--;
                break;
            case 'B':
                break;
            default:
                System.out.println(c);
            }
        }
    }

    public boolean hasSword()
    {
        return sharpLevel > 4;
    }

    public boolean canPoke()
    {
        return sharpLevel > 0;
    }
}

4
Tepenin Kralı meydan okumaları için yapılan başvurular golf oynamak anlamına gelmediğinden endişelenmeyin. ;)
Martin Ender

Adını JavaMan olarak değiştirdim, çünkü "Caveman" afişde bulunamayacak kadar jenerik. Umarım senin için sorun olmaz; değilse, sadece başka bir şeyle değiştirin.
Doorknob

1
Bu, hiçbir giriş yapıldığında kırılır (ilk dönüşte); Bununla nasıl başa çıkmak istediğinizi bilmiyorum bu yüzden ilk test aşamasından çıkarmak zorunda kalacağım.
Doorknob

Sabit ve isim değişikliği benimle iyi
user2813274

1
Sanırım devleti ayrıştırmakta bir hata yaptınız, hem 'ben' hem de 'düşman' aynı hamleleri alıyor: eyaletler [0]
Roy van Rijn

4

Derin düşünceler, C

Mağara adamı kodu. Mağara adamı düşünüyorum. Mağara adamı yapar.

// DeepThoughts.c
#include <stdio.h>  // Me need for plan
#include <string.h> // Me need for memory

// Me count sharps. If me still here, pokes no work
int is_pointy(char *past){
    int pointy = 0;     // Stick dull
    while(*past){
        switch(*past ++){
            case 'S': pointy ++; break;
            case 'P': if(pointy > 0) pointy --;
        }
    }
    return pointy;
}

// Me brain
int main(int argc, char *argv[]){
    int me_pointy = 0;  // Is 0, stick dull. Is 5, has sword
    int you_pointy = 0; // Same to you
    int me_last;        // Me last plan
    int you_last;       // Same to you
    char *you;          // You past
    int when;           // Time
    int me_plan;        // Me deep thought

    // Me remember
    if(argc > 1){
        you = strchr(argv[1], ',');     // Me find you past in me arg
        *you ++ = 0;
        when = strlen(argv[1]);         // Time is passing
        me_pointy = is_pointy(argv[1]); // Me look at me past
        you_pointy = is_pointy(you);    // Same to you
        me_last = argv[1][when - 1];    // Why me do that?
        you_last = you[when - 1];       // Same to you
    }

    // Me has deep thoughts. Me make plan
    if(me_pointy >= 5) me_plan = 'P';       // Me has sword
    else if(you_pointy == 0) me_plan = 'S'; // Me safe. You stick dull
    else if(when == 1) me_plan = 'P';       // Me shoot first (more thought)
    else if(me_pointy == 1 && when < 42) me_plan = 'B';  // Me try for sharper (deeper thought)
    else if(me_pointy > 0) me_plan = 'P';   // Me stick not dull
    else if(me_last == 'P') me_plan = 'B';  // Me in trouble
    else me_plan = 'S';                     // Me cross toes

    // Me do plan
    putchar(me_plan);
    return 0;
}

Ben test yapıyorum. Daha fazla düşünce daha iyi.


1
Mağara adamı için +1 var isimleri ve yorumları: P Ayrıca, güzel program c:
kedi

3

Nigel

Nigel, saldırıya uğramaktansa, taktiksel olmayı tercih eden, savunmacı yaşlı bir mağara adamıdır.

Bu bir PHP betiği, çağırmak php nigel.php

<?php
// Seed the random number generator
srand(time());

// Simple function output chosen move
function move($m)
{
    echo $m;
    echo "\n";
    exit;
}

// Make stick sharp if first move
if (sizeof($argv) == 1)
    move("S");

// Grab the list of moves
$moves = explode(",", $argv[1]);    
$mySharpness = 0;
$opSharpness = 0;

// Loop through all previous moves and calculate sharpness
for ($i=0; $i<strlen($moves[0]); $i++)
{
    $myMove = substr ($moves[0], $i, 1);
    $opMove = substr ($moves[1], $i, 1);
    if ($myMove == "S")     $mySharpness++;
    if ($opMove == "S")     $opSharpness++; 
    if ($myMove == "P" && $mySharpness > 0)     $mySharpness--;
    if ($opMove == "P" && $opSharpness > 0)     $opSharpness--;     
}

// We somehow have a sword.. ATTACK!
if ($mySharpness > 4)
    move("P");

// Opponent is blunt, guarenteed upgrade!
if ($opSharpness < 1)
    move("S");          

// If we're sharp, either block or poke, unless OP is near a sword
if ($mySharpness > 0)
{
    // Oppenent is halfway to a sword.. ATTACK!
    if ($opSharpness > 2)
        move("P");  

    if (rand(0,1) == 0)     move("P");
    else                    move("B");
}

// If we're blunt, either sharpen or block
else
{
    if (rand(0,1) == 0)     move("S");
    else                    move("B");  
}

?>

3

Aichmophobic - Lua

Ara sıra seni dürter, ama sadece bir çubuk çok keskinleşene kadar. Bu olduğunda, panikleyecek ve cenin pozisyonuna kıvrılacak.

if arg[1] == nil then
  response = "S"
elseif not arg[1]:match('SSSSS') == nil then
  --PANIC
  response = "B"
else  
  --Minds his own business and goes where he pleases
  math.randomseed(os.time())
  local rand = math.random();

  response = rand > 0.6 and "P" or "S"
end

print(response)

Şununla çalıştır:

lua aichmophobic.lua


2
Çıktınızın büyük harflerle yazılması gerekir; Bunu senin için düzelttim. (Ayrıca, bu gönderimin adını bin kere yanlış
yazdım

3

Bob Mağaraları

Bob Mağaraları mağaradaki en zeki adamlardan biridir. Bir eliyle saymayı öğrendi (diğeri sopasını tutmakla meşgul). Bu Taş Devri Olimpiyatlarını biliyor ve katılmak istedi.

Başlıca stratejisi, keskin bir sopası olana veya diğer mağara adamı da sivri olanı olana kadar sopasını bloklamak ve keskinleştirmek. Bu durumda Bob Caves onu dürtmeye çalışıyor!

import java.util.Random;

public class BobCaves {

    public static void main(String[] args) {
        int mySharpness = 0;
    int otherSharpness = 0;

    //Boc counts
    if (args.length > 0) {
        String[] ss = args[0].split(",");
        mySharpness = howSpiky(ss[0]);
        otherSharpness = howSpiky(ss[1]);
    }
    // Bob thinks!
    Random rn = new Random();
    if (mySharpness == 0 && otherSharpness == 0){
        System.out.println( "S");
    }
    if (otherSharpness == 0 && mySharpness < 5 && mySharpness > 0){
        if (rn.nextBoolean()){
            System.out.println("P");
        } else {
            System.out.println("S");
        }
    } 

    if (mySharpness >= 5 || (otherSharpness >= 2 && mySharpness > 0)) {
        System.out.println("P");
    }

    if (rn.nextInt(5) > 3) {
        System.out.println("S");
    } 

    System.out.println("B");
    }

    private static int howSpiky(String s1) {
        int count = 0;
        char[] c1 = s1.toCharArray();
        for (int i = 0; i < c1.length; i++) {
        if (c1[i] == 'S') {
                count++;
            } else if (c1[i] == 'P'){
                count --;
            }
        }
        return count;
    }

}

İle derleyin javac BobCaves.javave çalıştırınjava BobCaves

Düzenleme: Bob artık herhangi bir blok olduğunda sayar! ( Mikey Mouse'a teşekkürler ). Ayrıca diğer mağara adamı çubuğu künt olduğunda sopasını keskinleştirir.

Düzenleme 2: Geliştirilmiş sayma yöntemi (tekrar Mikey için teşekkürler).

Düzenleme 3: Bob'u biraz daha agresif hale getirmek.


2
Bob, Poke: Block'un kendi keskinliği üzerindeki sayma etkisini unutur. Üç "S" s demek, hiçbir şekilde 3 kat daha keskin değildir. S'deki her "P", bilenmemiş çubuk anlamına gelir. Huh huh huh ... "Çiş" mağara adamı şaka ...
Mikey Mouse

@MikeyMouse Bob aynı fikirde. Bob, tekniğini geliştirmek için cadı doktorunu ziyaret edecek. Bob minnettar!
Averroes

1
Cadı doktoru Bob'a iyi öğretir. Ama Poke: Poke senaryosundan bahsetmeyi unutma. Sopa o zaman körelir. Bob'un rakibin hareketini düşünmesine gerek yok. Bob Poke, sopa künt olsun. Her ikisi de körelir: rakip dürter, rakip blokta veya rakip başına. Rakip Head'de, Bob kazanır ve künt sopa ile mağara etrafında dans edebilir.
Mikey Mouse

1
@MikeyMouse Bob saymayı bilir. Bob'un okumayı öğrenmesi gerekiyor. Tekrar teşekkürler!
Averroes

3

Gruntt

Gruntt savunmada. Gruntt, diğer mağara hareketlerini nasıl dürteceğini bilmek için analiz eder. Sonra gözlerinin içine dürter. Gruntt hoş bir mağara adamı değil.

public class Gruntt {

public static void main(String[] args) {
    System.out.println(whatToDo(args));
}

private static String whatToDo(String[] args){
    int mySharpness = 0;
    int otherSharpness = 0;

    if (args.length > 0) {
        String[] ss = args[0].split(",");
        mySharpness = howSpiky(ss[0]);
        otherSharpness = howSpiky(ss[1]);
    } else {
        return "S";
    }

    if (mySharpness >= 5){
        return "P";
    }

    String res = wowoo(args[0].split(",")[1]);
    if ("P".equals(res) && mySharpness > 0) {
        return "P";
    } else if ("P".equals(res) && mySharpness == 0) {
        return "S";
    } else if ("S".equals(res) && !args[0].split(",")[0].endsWith("S")) {
        return "S";
    }

    if (otherSharpness == 4 && !args[0].split(",")[0].endsWith("P")){
        return "P";
    }

    if (otherSharpness == 0){
        return "S";
    }

    return "B";

}

private static int howSpiky(String s1) {
    int count = 0;
    char[] c1 = s1.toCharArray();
    for (int i = 0; i < c1.length; i++) {
    if (c1[i] == 'S') {
            count++;
        } else if (c1[i] == 'P'){
            count --;
        }
    }
    return count;
}

private static String wowoo(String s){
    String s1 = "";
    String s2 = "";

    if (s.length() >= 4){
        s1 = s.substring(s.length() - 4);
    }

    if (s.length() >= 3){
        s2 = s.substring(s.length() - 3);
    }

    if ("SPSP".equals(s1)){
        return "P";
    } else if ("SSS".equals(s2)){
        return "P";
    } else if ("BBBB".equals(s1)){
        return "S";
    } else if ("SBSB".equals(s1)){
        return "P";
    }

    return null;
}

}

İle derleyin javac Gruntt.javave çalıştırınjava Gruntt


Bu ArrayOutOfBoundsException, ilk dönüşe bir atar ve bazen diğer dönüşlerde birden fazla eylem çıkarır.
Doorknob

@Doorknob Ops! Sabit, teşekkürler!
Averroes

3

Bir kuş mu? Bir uçak mı? RegExMan!

Süper sıkıcı dizilerini özel ilkel RegEx-power ile analiz etmeye çalışıyor!

#!/usr/bin/env python
import sys, re

def whatAmIDoing(opnHist, meSharp, opnSharp) :

    match = re.search(r"([PSB]{3,})\1$", opnHist)    ### Super RegEx ftw!

    if meSharp >= 5 :
        return "P"
    if opnSharp == 4 and meSharp > 0 :
        return "P"
    if match :
        opnStrat = match.group()
        if opnStrat[0] == "S" :
            if meSharp > 0 :
                return "P"
            else :
                return "S"
        elif opnStrat[0] == "B" :
            return "S"
    if opnSharp <= 0 :
        return "S"
    return "B"

try :
    hist = sys.argv[1].split(",")
    sharp = map(lambda h : h.count("S") - h.count("P"), hist)
    answer = whatAmIDoing(hist[1], *sharp)
except Exception :
    answer = "S"
finally :
    print(answer)

Python 2.7 ile yazılmış, koşmak python RegExMan.py [history]


3

Sicillian

Ama bu çok basit! Tek yapmam gereken diğer mağara adamı hakkında bildiklerimden ilahi olmak: O engelleyen, keskinleştiren veya dürten bir tür mağara adamı mı? Şimdi, akıllı bir mağara adamı dürter ya da engellerdi, çünkü sadece büyük bir aptalın keskinleşip kendini saldırıya maruz bırakacağını bilecekti. Ben aptal değilim, bu yüzden açıkça bilemiyorum. Fakat diğer mağara adamı benim aptal olmadığımı bilmeli ve buna güvenecekti, bu yüzden açıkça dürtemez ya da engelleyemem!

Çalıştır:

javac Sicillian.java
java Sicillian

Kod:

public class Sicillian {

    public static void main(String[] args) {

        if (args.length == 0) System.out.println("S");
        else {
            //get and analyze history
            String[] history = args[0].split(",");
            Caveman vizzini = new Caveman(history[0].toCharArray());
            Caveman fool = new Caveman(history[1].toCharArray());
            Think divine = new Think(history[0].toCharArray(),history[1].toCharArray());

            //The Sicillian always thinks and makes a logical decision before acting...
            char onlyAFool = divine.clearly(vizzini.getSharpness(),fool.getSharpness());

            //Never go in against a Sicillian when death is on the line!
            if(onlyAFool == 'S') {
                if(!vizzini.weaponless()) poke();
                else sharpen();
            }
            else if(onlyAFool == 'P') {
                if(vizzini.hasSword()) poke();
                else block();
            }
            else if(onlyAFool == 'B') sharpen();

            else {          // Inconceivable!

                //if he's a sharpener, poke him where it hurts!
                if(fool.isSharpener()) {
                    if(vizzini.getSharpness() >= 2) poke();  //don't ever go weaponless, else you give him the advantage
                    else sharpen();
                }               
                //if he's a blocker, get sword and break through his defense
                else if(fool.isDefensive()) {
                    if(vizzini.hasSword()) poke();
                    else sharpen();
                }
                // fool doesn't have a disposition to do anything in particular
                else {
                    //he could be sharpening and blocking to get a sword in which case his sharpness will be higher
                    //or a random, which will average a lower sharpness
                    if (fool.getSharpness() <= 2) { //assume random
                        if(vizzini.hasSword()) poke();
                        else if(fool.weaponless()) sharpen();
                        else block();
                    }
                    else {
                        if(vizzini.hasSword()) poke();
                        else if(vizzini.getSharpness() > fool.getSharpness()) sharpen();    //we can win race to sword
                        else if(vizzini.getSharpness() >= 2 || (!vizzini.weaponless() && fool.onEdge())) poke();
                        else sharpen();
                    }
                }
            }           
        }
    }   //end of main

    private static void poke() {
        System.out.println("P");
    }
    private static void block() {
        System.out.println("B");
    }
    private static void sharpen() {
        System.out.println("S");
    }
}
class Think {
    private char[][] cleverman = new char[6][6];    //tracks what the enemy does in a particular situation 
    private int mySharpness;
    private int enemySharpness;
    public Think(char[] myAction, char[] enemyAction) {
        //init variables
        mySharpness = 0;
        enemySharpness = 0;

        for(int i = 0; i < myAction.length; i++) {
            //remember what enemy did last time
            cleverman[mySharpness][enemySharpness] = enemyAction[i];
            //System.out.println("When I was at ("+mySharpness+") and he was at ("+enemySharpness+") he did ("+enemyAction[i]+")");

            //calculate my sharpness
            if(myAction[i] == 'S') mySharpness++;
            else if(myAction[i] == 'P') mySharpness--;
            if(mySharpness < 0) mySharpness = 0; //ensure multiple pokes don't create a negative sharpness
            //calculate my enemy's sharpness
            if(enemyAction[i] == 'S') enemySharpness++;
            else if(enemyAction[i] == 'P') enemySharpness--;
            if(enemySharpness < 0) enemySharpness = 0; //ensure multiple pokes don't create a negative sharpness
        }   
    }
    public char clearly(int myAction, int enemyAction) {
        if(myAction > 5) myAction = 5;
        if(enemyAction > 5) enemyAction = 5;
        return cleverman[myAction][enemyAction];
    }
}
class Caveman {
    private int sharpness;
    private int disposition;    //Finite State Machine: how inclined the caveman is toward blocking (0) or sharpening (4)
    public Caveman(char[] action) {
        sharpness = 0;
        disposition = 1;        //assume a slightly defensive disposition
        for (int i = 0; i < action.length; i++) {
            if(action[i] == 'S') {
                sharpness++;
                disposition++;
            }
            else if(action[i] == 'P') sharpness--;
            else disposition--;                     //blocking
            if(sharpness < 0) sharpness = 0; //ensure multiple pokes don't create a negative sharpness
            if(disposition > 4) disposition = 4;
            else if(disposition < 0) disposition = 0;
        }
    }
    public int getSharpness() {
        return sharpness;
    }
    public boolean weaponless() {
        return sharpness == 0;
    }
    public boolean hasSword() {
        return sharpness >= 5;
    }
    public boolean onEdge() {
        return sharpness == 4;
    }
    public boolean isDefensive() {
        return disposition == 0;
    }
    public boolean isSharpener() {
        return disposition == 4;
    }
    public int getDisposition() {
        return disposition;
    }
}

3

bash-magnon

Bash-magnons sağlam bir şekilde inşa edildi ve güçlüydü. Vücut genel olarak ağır ve sağlam bir kas yapısı ile sağlamdı. Aln, Neandertallerde olduğu gibi eğimli olmaktan ziyade oldukça düzdü ve sadece hafif tarayıcılarla doluydu. Yüz kısa ve genişdi. Çene belirgindi. Beyin kapasitesi, modern insanlar için ortalamadan daha büyük, yaklaşık 1.600 santimetreküp (98 cu inç) idi. Bununla birlikte, son araştırmalar "Bash-Magnon" denilen fiziksel boyutların, modern insanlardan ayrı bir atama yapılmasına yetecek kadar farklı olmadığını göstermektedir.

Bir beynim var, hatırlıyorum.

Bu kendiliğinden çalıştırılabilir ./bash-magnon.sh

#!/bin/bash

function min () {
 [[ $1 -gt $2 ]] && echo $2 || echo $1
}

function max () {
[[ ${1%% *} -gt ${2%% *} ]] && echo $1 || echo $2
}

declare -A brain
declare -i C S P B me he
he=0
me=0
C=0
S=0; B=0; P=0

left=${1%%,*}
right=${1##*,}
while  : 
do

    [[ "${right:$C:1}" ]] && brain[$he$me]=${right:$C:1}
    case "${left:$C:1}${right:$C:1}" in
    BB) true;;
    BP) ((he--));;
    BS) ((he++));;
    PP) ((he--)); ((me--));;
    PB) ((me--));;
    PS|SP) exit;;
    SB) ((me++));;
    SS) ((me++)); ((he++));;
    "") break;;
    esac
    me=$(max 0 $me)
    me=$(min 9 $me)
    he=$(max 0 $he)
    he=$(min 9 $he)
    ((C++))
done

[[ $me$he =  *[5-9] ]] && ((P+=2))
[[ $me$he =  [5-9]* ]] && ((P+=2))
[[ $me$he =  [1-9]0 ]] && ((P+=2))
[[ $me$he =  00 ]] && ((S+=2))
[[ $me$he =  [1-4]4 ]] && ((P+=2))
[[ $me$he =  0[1-4] ]] && ((S+=1))
[[ $me$he =  0* ]] && ((B+=1))

case "${brain["$he$me"]}" in 
S) ((P+=2));;
B) ((S+=2));;
P) ((B+=2));;
*) ((B++));;
esac

set $(max "$B B" "$(max "$P P" "$S S")" )
echo $2

1+ Belli ki iş için doğru araca sahipsiniz ve mağaracı isimleriniz oldukça eğlenceli :) (Kişisel olarak balıkları daha çok seviyorum)
Sylwester

@Sylwester Teşekkürler, bu ilk + 1'im. İlk sibernetikçinin kendi dengesini hissettiren bir şeyden ilham alan bir homeostatik otomat elde etmeye çalıştım, sonra vazgeçtim ve bir bash betiği yazdım.
Emmanuel,

2

PokeBackBot

Basitçe PokeBot'tan uyarlanmıştır:

puts 'SBPB'[(ARGV.shift || ',').split(',', 2)[0].length % 4]

İle koş ruby pokebackbot.rb.

Bu, bir sonraki en basit stratejiyi kullanır ve saldırmadan önce bir tur için "sabırla" engeller.


3
@PeterTaylor: Rakibimi parmak basmaya dayalı stratejimi değiştirmeme izin verilmediğini okudum. Eğer gönderim yalnızca bir gönderimi geçebiliyorsa, bu diğer gönderilerin puanını gerçekten etkilemeyecek ve kendi gönderimim muhtemelen çok kötü sonuç verecektir. Dahası, eğer sadece bir başvuru varsa ve bir ikinci cevap yazılırsa, bu ikinci cevap ilkini geçme olasılığı yüksektir (çünkü aksi halde neden rahatsız edici) - bu tek başına "başka bir programa özel" olarak nitelendirilebilir mi? SPSBotum (makul görünüyor) ile başlayan herhangi bir botu yenecek , ancak şimdiye kadar PokeBot sadece etraftaydı.
Martin Ender

2

Kılıç ustası

Python 3.4 ile yazılmış (Python 3.x ile çalışır)

Kılıcı olabildiğince hızlı tutmaya çalışır, ancak ona vurma şansı varsa (keskinlik> 0) ve düşman da onu incitebilir (düşman keskinliği> 0).
Keskinlik ve düşmana saldıramazsa sadece engeller.

İle başla:

python3 swordmaster.py MOVES

(olarak kaydettiğinizi varsayalım swordmaster.py)

Hızlı ve çirkin kod:

import sys, random
dg = False
if len(sys.argv) > 1:
    ow,ot = sys.argv[1].split(',')
else:
    ow = ot = ""
def gs(m):
    ow = 0
    ot = 0
    i = 0
    ms = m[0]
    mo = m[1]
    for _ in mo:
        if ms[i] == 'S':
            ow += 1
        elif ms[i] == 'P' and mo[i] in ['P','B']:
            ow -= 1
        if mo[i] == 'S':
            ot += 1
        elif mo[i] == 'P' and ms[i] in ['P','B']:
            ot -= 1
        if dg:
            print("Own: {}, Other: {}".format(ow,ot))
        i += 1
    return [ow, ot]

def sm(sh):
    if (type(sh) != list) and dg:
        raise ValueError('Invalid sh type.')
    ow, ot = sh
    if ow >= 5:
        ret = 'P'
    elif ow >= 0 and ot == 0:
        ret = 'S'
    elif ow > 0 and ot > 0:
        ret = 'P'
    elif ow == 0 and ot > 0:
        ret = 'B'
    else:
        ret = random.choice(['S','B','P']) #Should not happen
    return ret

if __name__ == "__main__":
    print(sm(gs([ow,ot])))

( Hata ayıklama iletilerini etkinleştirmek dgiçin ayarlayın True)


1
İpucu: kendi kendine savaş izin vermeyin - bu ile kilitlenmeye edeceğiz S, P, S, P...
chill0r

Bunun bende de olduğunu gördüm. Tarihi incelemediğiniz veya bir dereceye kadar rastgele bir derecelik kullanmadığınız sürece, bir döngü içinde sıkışmak zorunda kalırsınız.
Pharap

2

FoolMeOnce.py

Her oyuncunun hamlelerini ilk düello için sakla, sonra da aynı hamle ile tekrarla. Düşmanın algoritması rastgele değilse, aynı sonucu tahmin edebilir ve yalnızca kazanacağımızı bildiğimiz zaman grev yapabiliriz.

import os
import sys
import random

def getLastMove(player, turn):
    path = 'players/FoolMeOnce/'+player+str(turn)+'.txt'
    if os.path.isfile(path):
        with open(path, 'r') as f:
            return f.read()
    else:
        return 'nofile'

def sharpness(history):
    sharpness = 0
    for c in history:
        if c is 'S':
            sharpness+=1
        elif c is 'P' and sharpness > 0:
            sharpness-=1
    return sharpness

def takeTurn(choice, history, turn):
    print(choice)
    with open('players/FoolMeOnce/me'+str(turn)+'.txt', 'w') as f:
        f.write(choice)
    #also record their last choice
    choice = history[-1]
    with open('players/FoolMeOnce/them'+str(turn)+'.txt', 'w') as f:
        f.write(choice)

#if its the first turn, always sharpen
if(len(sys.argv) == 1):
    print('S')

else:
    history = sys.argv[1].split(',')
    meSharp = sharpness(history[0])
    themSharp = sharpness(history[1])
    turn = len(history[0])

    #read opponents move and our move for this turn from last duel
    them = getLastMove('them', turn);
    me = getLastMove('me', turn);

    #if this is first duel, fool me once
    if(them is 'nofile' or me is 'nofile'):
        if themSharp is 0 and meSharp >0:
            takeTurn(random.SystemRandom().choice('PS'), history, turn)
        else:
            takeTurn('B', history, turn)

    #if we could have played a winning move, do it. otherwise do what we did last time
    elif(them is 'S' and meSharp > 0):
        takeTurn('P', history, turn)
    else:
        takeTurn(me, history, turn)

Python 3 ile yazılmıştır, bu nedenle büyük olasılıkla python3'ü kullanmanız gerekecektir. FoolMeOnce.py İlk turda, boş bir dize veya sadece virgül alıp almadığımızdan emin değilim, bu yüzden gerekli bazı tweaks olabilir.


Dosya yolunu düzelttim - şu anki çalışma dizini programın değil.
Doorknob

CavemanDuel test cihazı ile oynarken, FoolMeOnce'in daha fazla iş parçacığı kullanırsam daha iyi puanlar aldığını fark ettim (4'e karşı 16 iş parçacığını test ettim). 4 iplik ile ~ 25 puan alır, 16 ile ~ 34 puan alır.
wendelbsilva

Garip, bunun neden olduğu hakkında hiçbir fikrim yok.
tzazy
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.