Caveman Duels (atau: Aku menyodokmu dengan tongkat tajam)

151

Manusia gua gila. Manusia gua lain mengambil tongkat tetapi tongkat itu untukku. Pertarungan manusia gua !


Deskripsi

Manusia gua membutuhkan tongkat tajam untuk menusuk manusia gua lainnya. Manusia gua lainnya juga mencoba menusuk dengan tongkat tajam. Manusia gua dapat menajamkan tongkat, menyodok dengan tongkat, atau memblokir tongkat sempit.

Jika manusia gua menusuk manusia gua lain dengan tongkat tajam, manusia gua lainnya melarikan diri dan aku menang. Tetapi jika manusia gua lain dengan cerdas memblokir ketika saya menusuk, tidak ada yang terjadi kecuali tongkat saya menjadi tumpul dan saya perlu menajamkan lagi.

Manusia gua malas. Juga, manusia gua bodoh. Manusia gua tidak tahu apa yang harus dilakukan, jadi manusia gua perlu program komputer techno yang bagus untuk memberi tahu manusia gua apa yang harus dilakukan.

Memasukkan

Masukan program Anda akan menjadi sejarah peristiwa yang telah terjadi, di mana Skepanjangan dari mempertajam (yaitu manusia gua menajamkan tongkatnya), Psingkatan dari poke, dan Bsingkatan dari block. Input akan berupa riwayat dari kedua sisi (Anda dan lawan), sehingga gerakan Anda dan lawan akan dipisahkan dengan koma ( ,).

Input contoh:

SPB,SBB

Ini berarti bahwa pemain menajamkan tongkatnya, kemudian menusuk, lalu diblokir, dan lawan menajam, kemudian diblokir, lalu diblokir lagi.

Anda tidak akan menerima input pada giliran 1.

Keluaran

Outputnya sangat mirip dengan input (karena manusia gua tidak terlalu pintar). Program Anda harus menampilkan Suntuk mempertajam, Puntuk menyodok, dan Buntuk blok. Hanya karakter pertama dari output yang akan diperhitungkan, dan input lainnya akan diperlakukan sebagai perintah B(blok).

  • S: mempertajam

    Saat diasah, ketajaman tongkat gua naik 1 dan tongkat mendapat 1 tusuk tambahan. Setiap poke mengurangi ketajaman tongkat sebesar 1, dan jika ketajaman tongkat adalah 0, itu terlalu membosankan untuk ditusuk. Ketajaman dimulai dari 0. Jika ketajaman mencapai 5, tongkat itu adalah pedang! (Lihat di bawah.)

    Jika lawan menusuk saat Anda mengasah (dan mereka memiliki ketajaman> 0), lawan menang!

  • P: menyodok

    Saat menusuk, ketajaman tongkat gua turun 1 dan Anda menusuk lawan! Jika lawan Anda mengasah, Anda menang! Jika lawan menusuk, tongkat Anda mengenai tongkat lawan dan keduanya menjadi tumpul (dengan 1 "unit ketajaman"). Jika lawan menghalangi, tidak ada yang terjadi kecuali tongkat Anda menjadi kusam.

    Jika Anda menusuk ketika ketajaman tongkat Anda 5 atau lebih besar, tongkat Anda menjadi pedang dan Anda selalu menang! (Kecuali jika lawanmu juga memiliki pedang dan juga memilih P; dalam hal itu, mereka berdua menjadi kusam, dan dapat kembali menjadi tongkat jika ketajaman mereka jatuh di bawah 5.)

    Anda tidak dapat menyodok dengan ketajaman 0. Jika Anda melakukannya, tidak ada yang akan terjadi.

  • B: blok

    Ketika Anda memblokir, tidak ada yang terjadi ketika lawan Anda menusuk. Jika lawan Anda tidak menusuk, blok tidak melakukan apa pun.

    Memblokir tidak melindungi terhadap pedang, bahkan jika Anda juga memilikinya!

Aturan dan batasan

Aturan tambahan adalah:

  • Program Anda dapat membaca dan menulis file di foldernya sendiri (jangan mencuri!) Jika Anda ingin menyimpan data, tetapi Anda tidak dapat mengakses apa pun di luarnya (dan manusia gua tidak memiliki koneksi internet di hutan belantara).
    • Catatan penting pada file : Jika Anda menyimpan file, ingatlah untuk menyimpannya di direktori players/YourBotsName/somefile.foo! Direktori kerja saat ini untuk program Anda tidak akan menjadi program Anda!
  • Manusia gua adil: Satu program tidak dapat memiliki kode khusus untuk program lain, dan program tidak dapat saling membantu. (Anda mungkin memiliki banyak program, tetapi mereka tidak dapat berinteraksi satu sama lain dengan cara apa pun.)
  • Hakim gua tidak sabar. Jika manusia gua mengambil lebih dari 100 putaran masing-masing untuk menentukan pemenang, hakim menjadi bosan dan kedua manusia gua kalah.

Jika program Anda melanggar aturan atau tidak mengikuti spesifikasi, program tersebut didiskualifikasi, dihapus dari playerlist.txt, dan semua duel restart dari awal. Jika program Anda didiskualifikasi, pemimpin gua (saya!) Akan mengomentari pos program Anda dan menjelaskan alasannya. Jika Anda tidak melanggar aturan apa pun, program Anda akan ditambahkan ke papan peringkat. (Jika program Anda tidak ada di papan peringkat, tidak ada komentar yang jelas di pos Anda, dan Anda memposting program Anda sebelum waktu "Terakhir diperbarui" di bawah, beri tahu pemimpin gua! Mungkin dia lupa.)

Dalam posting Anda, harap sertakan:

  • Sebuah nama.
  • Sebuah perintah shell untuk menjalankan program Anda (ex. java MyBot.java, ruby MyBot.rb, python3 MyBot.py, Dll).
    • Catatan: input akan ditambahkan ke ini sebagai argumen baris perintah.
    • Para gua menggunakan Ubuntu 14.04, jadi pastikan kode Anda berfungsi (secara bebas) di atasnya.
  • Nomor versi, jika kode Anda bekerja secara berbeda pada versi berbeda dari bahasa pilihan Anda.
  • Kode Anda (jelas).
  • Cara mengkompilasi kode, jika perlu.

Kode pengontrol / pengujian, contoh bot

Pemimpin gua menulis kode kontrol dalam C ++, dan mempostingnya di repo Github . Anda dapat menjalankan dan menguji program Anda di sana.

Program yang sangat, sangat sederhana (1 baris!) Juga diposting dalam jawaban di bawah ini .

Penilaian dan papan peringkat

Penilaian itu mudah. Manusia gua mana pun yang menang mendapat poin. Manusia gua dengan poin terbanyak setelah 3 duel melawan setiap manusia gua lainnya menjadi pemimpin manusia gua yang baru!

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

(leaderboard ini dihasilkan secara otomatis secara ajaib)

Pemain yang ditandai dengan *lemparan kesalahan atau pengecualian pada beberapa titik; para pemain ini juga memiliki komentar pada posting mereka.

Pemain yang tidak bisa dimasukkan dalam tes untuk alasan apapun (pemain ini akan memiliki komentar pada posting mereka menjelaskan masalah): Monkey, Elephant, FacileFibonacci, StudiousSylwester.

Terakhir diperbarui: 3 Agustus 00:15 (UTC).

Gagang pintu
sumber
Saya terkejut tidak ada yang tampaknya telah berusaha untuk menemukan strategi minimax. Sepertinya hal yang jelas untuk dilakukan.
user2357112
@ user2357112 Saya tidak berpikir minimax adalah peningkatan di sini. Maksud saya, Anda dapat merancang implementasi minimax, tetapi karena logikanya sangat sederhana, perilaku yang persis sama dapat diekspresikan dengan mesin keadaan terbatas. (Yaitu bot tidak akan pernah menajam sampai lawan tumpul karena jika itu terjadi, langkah meminimalkan lawan akan menusuk dan Anda kalah, bot akan selalu memblokir sampai kita memiliki pedang karena gerakan memaksimalkan bot kita akan selalu akan memblokir, dll.)
HuddleWolf
3
Banyak entri tampaknya memungkinkan ketajaman negatif dalam perhitungan mereka. Aturan seperti yang tertulis mengatakan bahwa tidak ada yang terjadi ketika Anda menusuk dengan ketajaman nol. Apakah itu "tidak ada" juga berarti ketajaman Anda tetap nol, bukannya dikurangi?
Sparr
6
Ini perlu ada di sini: dresdencodak.com/comics/2009-09-22-caveman_science_fiction.jpg Mungkin itu akan membuat imajinasi berjalan. :)
Evi1M4chine
2
Apakah ini masih terbuka? Saya melihat orang menambahkan kiriman baru, tetapi saya tidak melihat papan peringkat diperbarui.
ASCIIThenANSI

Jawaban:

35

Darwin - C

Lagi pula, siapa yang butuh strategi? Suruh sekelompok manusia gua saling bertarung dan biarkan seleksi alam melakukan sisanya!


Kami menggunakan model yang sangat sederhana untuk mengeluarkan otak primitif manusia gua: ia tidak memiliki memori dan hanya memperhitungkan ketajaman tongkatnya dan tongkat lawannya. Mereka digunakan sebagai variabel untuk polinomial biner dari beberapa urutan hingga. Setiap tindakan (blok, pertajam, dan aduk) memiliki polinomial terkait yang hasilnya menentukan probabilitas relatif untuk memilih tindakan ini. Cukup banyak yang ada untuk itu --- mulailah dengan beberapa koefisien acak dan optimalkan secara berulang.

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

Mengkompilasi dengan: gcc darwin.c -odarwin -w -O3. Dijalankan dengan: ./darwin <history>.

Bot membaca koefisien dari file bernama programdalam players/Darwindirektori (file yang berbeda dapat ditentukan sebagai argumen baris perintah kedua). Program ini tampaknya berhasil:

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 

Simpan sebagai players/Darwin/program.

Berikut ini adalah program yang menghasilkan programfile yang dapat digunakan oleh bot (tidak harus dikompilasi jika Anda menggunakan programfile di atas):

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

Mengkompilasi dengan: gcc genprog.c -ogenprog -w -O3. Dijalankan dengan: ./genprog [output-filename].


Watson

Apa DNA manusia gua yang menang? Mungkin orang ini punya jawabannya:

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

Jalankan dengan: python Watson.py

Watson adalah produk dari algoritma genetika. Tidak seperti Darwin, datum genetik kali ini adalah program aktual, ditulis dalam bahasa khusus domain kecil (di sini diterjemahkan ke Python).


Simple Sequence Beats Pemain Besar

Orang kecil ini sangat mengejutkan (atau, mungkin, tidak terlalu mengejutkan), terutama terhadap para pemimpin:

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

Jalankan dengan: python SSBBP.py

DarwinBot
sumber
Bagaimana saya mengkompilasi dan menjalankan ini? Juga, seperti yang disebutkan dalam pertanyaan, Anda hanya dapat membaca / menulis file di players/Darwindirektori.
Gagang Pintu
@ Doorknob: diperbaiki.
DarwinBot
Saya mendapatkan kesalahan kompilasi ini ketika mengkompilasi kode ini. (Saya di Ubuntu 14.04.)
Gagang Pintu
@ Doorknob: Diperbaiki. Harusnya bekerja sekarang.
DarwinBot
Sekarang saya mengerti undefined reference to `fmax'. --Edit - Sudahlah, aku memang butuh -lm.
Gagang Pintu
50

Manusia gua tak terduga

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!

Manusia gua ini memilih secara acak setiap ronde, tetapi saya sudah menjelaskan kepadanya dengan sangat sederhana bahwa tindakan tertentu terkadang tidak masuk akal. Jangan ragu untuk menyalin kode ini jika Anda ingin mengekspresikan logika yang berbeda.

Ini adalah Ruby, simpan sebagai 'unpredictable.rb' dan jalankan dengan ruby unpredictable.rb

histokrat
sumber
Sebenarnya, aku no 'Block'juga harus memikirkannya jika lawanku memiliki pedang.
njzk2
Tidak ada 'Blok' pertama sebenarnya mencakup: tongkat runcing bukan pedang.
histokrat
2
Mengapa Anda tidak menggunakan unlessuntuk no 'Block'dan no 'Pokelaporan? ( no 'Block' unless he.has_pointy_stick)
wchargin
25

Dokter Gua - Lua

"Aku kalah dari orang asing baru, menjatuhkan mereka untuk mempelajarinya"

Ketika Anda telah melihat banyak pasien sebagai dokter gua, Anda mulai benar-benar memahami jiwa manusia gua (atau jadi saya harap). Permainan dokter gua adalah strategi murni, dia menunggu tusukan yang dia blok dalam upaya melucuti lawannya, tetapi dia tidak akan membiarkan lawan itu mendekat untuk membuat pedang. Dia mencoba memprediksi kapan aman untuk diasah sehingga dia tidak kehilangan kendali.

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

Jalankan dengan: lua CaveDoctor.lua

Perhubungan
sumber
3
Ini hanya kehilangan dua kali di leaderboard saat ini? oO
justhalf
Revisi 5 melempar banyak kesalahan, jadi revisi 4 adalah yang termasuk dalam putaran uji coba saat ini.
Gagang pintu
@ Doorknob Saya pikir saya sudah memperbaiki semuanya, hanya ada satu perubahan pada logika sebenarnya.
Nexus
20

Penjaga Asing

ForeignCaveman tidak tahu apa yang baru saja Anda katakan. Dia hanya ... melakukan banyak hal.

javac ForeignCaveman.java kemudian 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;
        }
   }
}
Kevin L.
sumber
11
Ini mungkin memiliki terlalu banyak upvotes untuk seberapa buruk itu terjadi
Kevin L
19

Wakil Pemimpin

Gagang pintu ♦ adalah pemimpin. Saya ingin menjadi pemimpin! Ikuti program super cerdas untuk menjadi pemimpin!

Kompilasi: javac ViceLeader.javaJalankan: 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;
    }
}
CommonGuy
sumber
Kenapa tidak if (enemySharpness <= 4 || mySharpness >= 5)vs ini ==?
durron597
@ durron597 Karena saya hanya ingin menyodok musuh jika dia dapat membuat pedang pada belokan berikutnya (yang kemungkinan besar akan dia lakukan). VizeLeader tidak sering menyodok, ia melakukannya pada waktu yang tepat .
CommonGuy
Tetapi Anda memiliki pedang dan lawan Anda tidak ...
durron597
@ durron597 Tidak, ini pernyataan ATAU. Itu berarti "menyodok lawan jika saya memiliki pedang ATAU jika dia akan segera memiliki pedang".
CommonGuy
7
Oh kebaikan. Saatnya mendapatkan secangkir kopi lagi :) Atau lensa kontak baru
durron597
15

Mungkin Markov 2.1

Saya pikir itu menggunakan Markov Chains untuk memprediksi apa yang akan dilakukan manusia gua yang lain, tetapi saya hanya melihat sebentar di halaman wikipedia tentang Markov Chains dan memutuskan bahwa terlalu banyak teks.

Ia mencoba untuk tetap hidup selama 30 putaran dan kemudian membangun sebuah meja dengan perubahan keadaan saat ini-berikutnya, dan bereaksi terhadap apa yang menurut manusia lain akan lakukan.

Kode ini berisi banyak pernyataan yang tidak perlu, tetapi performanya cukup baik.

SUNTING

Terdeteksi cacat logika. Sekarang ia benar-benar melakukan sesuatu ketika memiliki pedang.

$ 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)
Lennart_96
sumber
14

CicadaCaveman Berkala

Manusia gua yang agak pintar ini telah mempelajari Bug tertentu dan menyadari tidak ada yang bisa menyesuaikan gaya hidup mereka untuk mengambil keuntungan dari bilangan prima Cicada.

Itu menyembunyikan / memblokir sebagian besar hidup itu, tetapi kadang-kadang menyodok. Yakin itu rentan terhadap Pedang, dan menghabiskan seluruh siklus dengan tongkat yang tidak dicukur, tetapi mengasah tongkatmu saat itu benar-benar tumpul? Itulah tepatnya yang orang lain harapkan darinya ... bukan jangkrik ini

mengkompilasi: mcs program.cs untuk menjalankan mono program.exe

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

  }

}

Sunting: Mengubah ketajaman - kode ... jika saya menyodok saya menang atau tongkat saya menjadi kusam

Edit2: Ditambahkan dalam saran Bobs

Sunting: Diubah menjadi hanya menyodok ketika pada ketajaman 2, jika tongkat itu nol, orang lain mungkin membuat pedang.

Mikey Mouse
sumber
1
Saya menjalankan di Ubuntu; akankah ini dikompilasi di bawah Mono? Jika demikian, bagaimana cara saya mengompilasinya dan bagaimana saya menjalankannya?
Gagang Pintu
Sejujurnya, saya tidak tahu. Aku baru saja akan pergi tidur. Saya bisa menulis ulang ke Jawa besok pagi di tempat kerja. Kode Java harus hampir identik.
Mikey Mouse
5
@ Doorknob mcs program.csakan mengkompilasinya, mono programakan menjalankannya, tetapi Anda harus mengganti foo.Dump();s dengan System.Console.WriteLine(foo);(atau menambahkan metode ekstensi public static void Dump(this string value) { System.Console.WriteLine(value); }).
Bob
@ Bob Terima kasih sobat, saya telah menambahkan metode ekstensi Anda.
Mikey Mouse
Maaf, nama file default aktual yang mcsdihasilkan adalah <filename>.exe, misalnya program.csakan menjadi program.exe. Jadi perintah yang dijalankan adalah mono program.exe. (Saya tidak memiliki akses ke mono pada saat komentar saya sebelumnya.)
Bob
14

Algoritma FancyTechno

Algoritma techno mewah untuk program komputer techno mewah.

Manusia gua terus kalah dalam pertempuran. Manusia gua marah. Jadi manusia gua pergi ke sekolah komputer belajar membuat algoritma.

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"

Program Python 2. Untuk berlari:python fancytechnoalgorithm.py

Vektor
sumber
Ini rusak ketika tidak ada input (yaitu pada belokan pertama). Saya tidak tahu bagaimana Anda ingin mengatasinya, jadi saya harus mengeluarkannya dari pengujian tahap pertama.
Gagang pintu
@Doorknob Untuk input pertama, apakah itu "," atau ""? Saya kira itu yang terakhir dari itu.
Vektor
Untuk input pertama, tidak akan ada argumen (akan dijalankan sebagai python StickSharpener.py).
Gagang pintu
@ Doorknob saya sudah mengeditnya. Lihat apakah itu berfungsi sekarang.
Vektor
Baik terima kasih! Saya akan memasukkan ini dalam putaran uji coba berikutnya.
Gagang Pintu
14

Pengamat

Dia memperhatikan gerakan lawannya, selalu membiarkan mereka menunjukkan tangan mereka sebelum dia menyerang. Dia sangat siap untuk mereka yang lalai bekerja menuju pedang.

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

Nama file: watcher.py

Untuk berlari: python watcher.py

Basilisk

Berusaha menghancurkan mereka yang memandangnya terlalu dekat. Secara konsisten mengalahkan Watcher, tetapi mungkin akan lebih buruk secara keseluruhan.

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

Nama file: basilisk.py

Untuk berlari: python basilisk.py

Nash

Berusaha untuk membuat pilihan lawannya tidak relevan, dengan memilih setiap gerakan dengan probabilitas yang memperhitungkan risiko dan ganjarannya

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

Ini bukan keseimbangan Nash (generator strategi saya memiliki beberapa ketidakstabilan), tetapi sudah dekat.

Demi rasa ingin tahu, berikut adalah perkiraan seberapa mungkin bot ini akan menang di setiap kondisi permainan:

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

Nama file: nash.py

Untuk berlari: python nash.py

Membohong

Terbuka dengan serangan cepat, untuk menguji pertahanan lawannya.

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

Nama file: feint.py

Untuk berlari: python feint.py

LatePokeBot

Adik laki-laki PokeBot. Tidak pernah menunjukkan kelemahan, tetapi mencoba untuk bertarung seperti kakaknya.

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

Nama file: latepokebot.py

Untuk berlari: python latepokebot.py

Brilliand
sumber
Anda melewatkan a :di Basilisk; Saya memperbaikinya untuk Anda
Gagang Pintu
Kiriman ini melemparkan beberapa jenis kesalahan atau pengecualian di beberapa titik; Anda mungkin ingin melihat memperbaikinya sebelum putaran uji coba berikutnya. (the Basilisk one)
Gagang Pintu
@Doorknob Saya memilih urutan awal untuk Basilisk dengan melihat asumsi yang dibuat oleh The Watcher dan Cave Doctor dan menemukan urutan yang akan membuat asumsi-asumsi itu menjadi sangat salah. Apakah itu melanggar aturan "manusia gua yang adil"?
Brilliand
Pergi Nash! Menangkan persis separuh pertandingan Anda melawan semua bot yang cukup pintar untuk menghindari opsi P = 0 Anda!
aschepler
12

PokeBot

Ditulis dalam Ruby.

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

Jalankan dengan ruby pokebot.rb.

Bot ini tidak terlalu pintar; itu tidak tentang apa yang rata-rata manusia gua akan lakukan sendiri.

Gagang pintu
sumber
9

PatientWolf v2.0

Menajamkan jika tumpul, menusuk jika musuh akan memiliki pedang di tikungan berikutnya atau jika musuh tumpul, blok sebaliknya.

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

Jalankan dengan

perl patientwolf.pl

EDIT: terima kasih kepada @sylwester karena telah menunjukkan bug

mematikan
sumber
Karena Anda hanya mendapatkan satu argumen dengan kedua riwayat dipisahkan oleh koma, Anda salah menguraikannya. Misalnya. PatientWolf.pl SB,SPApakah Pkarena berpikir itu memiliki tongkat tajam.
Sylwester
@Sylwester itu tidak benar. Baris pertama memberikan argumen pertama ke $ saya dan argumen kedua ke $ dia
killmous
Program CavemanDuel tidak menggunakan dua argumen, hanya satu. misalnya. perl patientwolf.pl "SB,SP". Anda harus melakukan my($me,$him) = split/,/ $ARGV[0];dan if( @ARGV ) {print "S";exit}.
Sylwester
@Sylwester ok saya melihat apa yang Anda maksud. Itu tidak jelas dari OP atau dari pandangan sekilas saya melemparkan kode controller. Saya akan memperbaikinya segera
killmous
9

Binary Caveman

Pertajam, Stab, Ulangi

Berdasarkan gagasan bahwa pemblokiran adalah untuk banci, manusia gua ini bergantian antara dua opsi yang tersisa.

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

Kompilasi dengan javac BinaryCaveman.java

Jalankan dengan java BinaryCaveman

EDIT: Adventures in String Array ..... args.length () melempar kesalahan. args.length selalu mengembalikan 1. args [0] .length () mengembalikan panjang string pertama dalam array.

EDIT 2: Diperbarui berkat bantuan dari Doorknob, Brilliand, dan Sylwester. Terima kasih kawan

Red_Shadow
sumber
@ MartinBüttner Saya lupa membagi args - 1 dengan 2 untuk hanya mendapatkan jumlah pengiriman sebelumnya oleh satu pemain. Memperbaiki itu. Saya tidak bisa memahami penyerahan Dorknob, ruby ​​bisa dibilang omong kosong bagi saya. Apakah dia selalu mulai dengan mengasah?
Red_Shadow
Ya, dia hanya memeriksa apakah langkah terakhirnya adalah Patau Sdan apakah sebaliknya. Dan jika belum ada sejarah, dia berpura-pura akan menjadi sejarah P,(yang kemudian membuatnya melakukan Slebih dulu).
Martin Ender
Dua pendekatan berbeda yang menghasilkan keluaran yang sama. Apakah itu melanggar aturan?
Red_Shadow
Mungkin tidak, saya hanya akan memberi tahu Anda.
Martin Ender
2
@ Doorknob, saya pikir seharusnya begitu args[0].length(), tidak args.length.
Brilliand
8

CavekidBlocks

Anak gua yang menangis dan ketakutan mungkin terlihat seperti mangsa yang mudah. Jangan biarkan wajahnya yang cantik membodohi Anda karena dia tahu cara memblokir.

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

Jalankan dengan python3 cavekidblocks.py

ChargerMan

Manusia gua ini sangat konservatif. Akan mencoba mengisi senjatanya dan hanya menyerang ketika dibutuhkan.

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)

Jalankan dengan python3 chargerman.py

Penipu

Trickster tidak tahu cara bertarung, jadi dia mencoba membingungkan manusia gua lainnya.

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

Jalankan dengan python3 trickster.py

Sayangnya, setelah acc74 komitmen , Trickster tidak berfungsi seperti yang direncanakan lagi.

wendelbsilva
sumber
4
Program penipu itu jahat
Nexus
@Nexus Aku juga begitu. Sayangnya Trickster tidak berjalan baik di duel.
wendelbsilva
7

Hodor

Hodor tidak terlalu agresif. Dia suka tinggal di perisainya kecuali ada peluang bagus untuk menyerang.

kompilasi dengan: javac Hodor.javadan jalankan dengan:java Hodor

kode:

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

Edit: pembaruan kode minor

Qwix
sumber
Kiriman ini melemparkan beberapa jenis kesalahan atau pengecualian di beberapa titik; Anda mungkin ingin melihat memperbaikinya sebelum putaran uji coba berikutnya.
Gagang pintu
1
Coba dengan SB,BB. Ketika manusia gua lain berperilaku buruk pada giliran pertama Hodor juga berperilaku buruk.
Sylwester
7

Sylwester Spekulatif - Perl5

Sylwester yang spekulatif ingin menyingkirkan para pencari pedang dengan melihat polanya dan menyodok ketika ada peluang lawan akan menajam dan menajamkan saat lawan paling mungkin untuk memblokir. Namun, dia tidak akan melakukan itu jika ada kemungkinan dia akan menebak bahwa dirinya akan menajam pada langkah selanjutnya dan kita bahkan lebih berhati-hati ketika kita memutuskan untuk menajamkan.

Adapun ketika lawan tumpul dia mencoba untuk menjadi agresif tetapi pada akhirnya akan mulai menabung untuk pedang ketika itu tampaknya sia-sia.

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

Untuk berjalan di linux cukup tambahkan ini di playerlist.txt:

perl players/SpeculativeSylwester/SpeculativeSylwester.pl

Fibonacci Facile - Skema R6RS

Selain itu, langkah pertama Facile Fibonacci memblokir ketika belokan adalah angka Fibonacci (mulai dari 0) dan mengisi sisanya dengan PPSS..dan berubah ketika melewati 8 ke urutan tanpa akhir PSSuntuk menang dengan pedang.

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

Untuk menjalankan cukup instal ikarus dengan apt-get install ikarusdan tambahkan ini di playerlist.txt:

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

Studious Sylwester - Perl5

Studious Sylwester menggunakan taktik yang sama dengan Spekulatif Sylwester, tetapi ia juga melihat permainan sebelumnya untuk menentukan di mana ia mungkin mengambil pilihan yang salah.

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

Untuk berjalan di linux cukup tambahkan ini ke playerlist.txt

perl players/StudiousSylwester/StudiousSylwester.pl

Suntingan belajar

Saya tidak dapat mereproduksi masalah yang Anda miliki dengan $0tidak menjadi path lengkap ke skrip perl ketika dijalankan dengan perl. Saya juga telah menarik perubahan Anda dan saya tidak melihat perubahan di CavemanDuels src dan itu sama saya telah menjalankan 20+ kali tanpa masalah yang Anda laporkan. Saya mulai takut Anda mungkin telah membuat skrip sebagai bash script daripada menjalankannya saat dieksekusi atau sebagai argumen untuk perl. Saya perlu lebih banyak info untuk benar-benar tahu pasti. Sebagai ujian saya melakukan ini dan Anda dapat melakukan hal yang sama untuk melihat apakah Anda mendapatkan hasil yang sama:

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
Sylwester
sumber
Skema tampaknya tidak ingin bekerja sama dengan saya di mesin saya, jadi saya tidak dapat menguji Fibonacci. Saya akan terus berusaha membuatnya berfungsi, tetapi alangkah baiknya jika Anda bisa menerjemahkannya ke bahasa lain.
Gagang Pintu
Yang rajin juga tampaknya tidak bekerja, karena $0merupakan bashsaat dipanggil dari baris perintah bash (yang controller tidak). Anda bisa saja melakukan hardcode players/StudiousSylwester/foo.txt.
Gagang Pintu
@ Doorknob saya telah menambahkan cara menginstal ikarusdan saya telah menambahkan pemikiran saya $0untuk Studious.
Sylwester
6

Swordsmith

Butuh tongkat tajam. Jika memiliki tongkat tajam, aduk. Aku tidak merasakan sakit.

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

Simpan sebagai swordsmith.f90dan mengkompilasi dengan gfortran -o swordsmith swordsmith.f90, jalankan seperti yang Anda lakukan eksekusi yang normal: ./swordsmith.

Kyle Kanos
sumber
Ini muncul untuk mencetak spasi (``) sebelum output nyata. Saya tidak tahu cara memperbaikinya, jadi saya harus mengecualikan kiriman ini dari pengujian putaran pertama.
Gagang pintu
Juga, saya telah memperbaiki jalur file Anda; ternyata direktori kerja saat ini ketika dijalankan bukan milik program Anda. Oh, dan jika dengan "contoh baru" maksud Anda "setiap permainan," Saya tidak bisa melakukan itu karena itu akan memerlukan casing khusus program pengontrol; Anda mungkin ingin melakukannya dalam kode Anda sendiri.
Gagang Pintu
@ Doorknob: Saya telah memperbarui kode saya: output adalah karakter tunggal, ini menghapus file yang sudah ada saat dijalankan pertama kali, dan file tersebut ada di direktori pemain.
Kyle Kanos
Baik terima kasih! Pengajuan ini sekarang termasuk dalam leaderboard.
Gagang Pintu
@Doorknob: Keren! Menyebalkan bahwa saya bukan yang pertama. Juga: Saya cukup yakin pengguna Fortran seperti Vampir, jadi saya cukup yakin Anda akan segera mulai membuat kode di Fortran! Muahahahaha!
Kyle Kanos
5

PatientBlacksmith

Bot ini ditulis dalam R, gunakan Rscript PatientBlacksmith.Runtuk memicunya.

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)

Mengukur ketajaman tongkat lawan: memblok saat tajam, luangkan waktu untuk menajamkannya. Saat ketajamannya mencapai 5, aduk sampai ketajaman hilang.

plannapus
sumber
Ini rusak ketika tidak diberi input (yaitu pada belokan pertama); Saya tidak tahu cara memperbaikinya sehingga saya harus mengecualikannya dari putaran 1 pengujian.
Gagang pintu
@ Doorknob dikoreksi.
plannapus
5

Aturan Penjara, Haskell

Petugas wanita berpikir manusia gua dan manusia gua lainnya harus berbicara, berbagi tongkat. Tapi, hei ho, jika harus bertarung, lawanlah aturan penjara. Temukan bos dan serang.

Wakil Pemimpin Alpha Caveman sekarang; bahwa manusia gua harus bertarung. Manusia gua lainnya bertarung nanti. Jika manusia gua saya kalah, jangan khawatir; toh dia terlalu berbulu.

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

Ditulis dalam Haskell (buka pemrograman fungsional!), Jadi simpan sebagai jailrules.hs , lalu kompilasi dengan:

ghc prisonrules.hs

Dan jalankan sebagai:

prisonrules [history]
comperendinous
sumber
4

Saya memanggilnya JavaMan

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

catatan: Saya tidak bermaksud bermain golf kode .. tetapi jika Anda seorang pegolf dan spasi / garis tambahan membuat mata Anda berdarah .. jangan ragu untuk mengubahnya

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;
    }
}
pengguna2813274
sumber
4
Pengajuan tantangan King of the Hill tidak dimaksudkan untuk bermain golf, jadi jangan khawatir. ;)
Martin Ender
Saya telah mengubah namanya menjadi JavaMan, karena "manusia gua" agak terlalu generik untuk berada di papan peringkat. Semoga tidak apa-apa dengan Anda; jika tidak, ubah saja ke sesuatu yang lain.
Gagang Pintu
1
Ini rusak ketika tidak diberi input (yaitu pada belokan pertama); Saya tidak tahu bagaimana Anda ingin mengatasinya, jadi saya harus mengeluarkannya dari pengujian tahap pertama.
Gagang pintu
Diperbaiki, dan perubahan nama tidak masalah bagi saya
user2813274
1
Saya pikir Anda memiliki kesalahan dalam menguraikan negara, baik 'saya' dan 'musuh' mendapatkan langkah yang sama: menyatakan [0]
Roy van Rijn
4

Pikiran yang Mendalam, C

Kode manusia gua. Manusia gua berpikir. Manusia gua lakukan.

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

Saya melakukan pengujian. Lebih banyak pikiran lebih baik.

Zakipu
sumber
1
+1 untuk nama dan komentar manusia gua: P Juga, program yang bagus c:
cat
3

Nigel

Nigel adalah seorang manusia gua tua yang sabar dan defensif yang lebih suka taktis daripada menyerang habis-habisan.

Ini adalah skrip PHP, panggil dengan 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");  
}

?>
ArcticanAudio
sumber
3

Aichmophobic - Lua

Dia akan sesekali menusuk Anda, tetapi hanya sampai beberapa tongkat menjadi terlalu tajam. Ketika ini terjadi, dia akan panik dan meringkuk ke posisi janin.

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)

Jalankan dengan:

lua aichmophobic.lua

William Barbosa
sumber
2
Output Anda harus dalam huruf kapital; Saya sudah memperbaikinya untuk Anda. (Juga, saya salah mengeja nama kiriman ini sekitar seribu kali.: P)
Gagang Pintu
3

Gua Bob

Gua Bob adalah salah satu orang paling pintar di guanya. Dia telah belajar berhitung dengan satu tangan (yang lain sibuk memegang tongkatnya). Dia telah mengetahui Olimpiade Zaman Batu ini dan ingin berpartisipasi.

Strategi utamanya adalah memblokir dan menajamkan tongkatnya sampai ia memiliki tongkat tajam yang bagus atau manusia gua lainnya juga memiliki yang tajam. Dalam hal ini Bob Caves mencoba menusuknya!

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

}

Kompilasi dengan javac BobCaves.javadan jalankanjava BobCaves

Sunting: Bob sekarang diperhitungkan ketika ada blok! (terima kasih kepada Mikey Mouse ). Juga dia akan menajamkan tongkatnya ketika tongkat gua yang lain tumpul.

Sunting 2: Metode penghitungan yang ditingkatkan (sekali lagi terima kasih kepada Mikey).

Sunting 3: Membuat Bob sedikit lebih agresif.

Averroes
sumber
2
Bob lupa menghitung efek Poke: Memblokir ketajaman tongkat sendiri. Tiga "S" dalam tongkat tidak berarti 3 kali tajam. Setiap "P" berarti tongkat yang tidak dicukur. Huh huh huh ... "Pee" manusia gua bercanda ...
Mikey Mouse
@MikeyMouse Bob sependapat. Bob akan mengunjungi dukun untuk meningkatkan tekniknya. Bob bersyukur!
Averroes
1
Dokter penyihir mengajar Bob dengan baik. Tapi dia lupa menyebutkan Poke: Skenario Poke. Tongkat jadi tumpul juga. Bob tidak perlu mempertimbangkan langkah lawan. Jika Bob Poke, tongkat menjadi tumpul. Entah tumpul pada: menyodok lawan, di blok lawan atau di kepala lawan. Jika di Head lawan, Bob menang dan bisa menari di sekitar gua dengan tongkat tumpul.
Mikey Mouse
1
@MikeyMouse Bob tahu bagaimana cara menghitung. Bob perlu belajar membaca. Terima kasih lagi!
Averroes
3

Gruntt

Gruntt defensif. Gruntt menganalisis gerakan manusia gua lainnya untuk mengetahui cara menusuk mereka. Lalu dia menusuk mereka tepat di mata. Gruntt bukan manusia gua yang baik.

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

}

Kompilasi dengan javac Gruntt.javadan jalankanjava Gruntt

Averroes
sumber
Ini melempar ArrayOutOfBoundsExceptionpada belokan pertama, dan terkadang menghasilkan beberapa tindakan pada belokan lainnya.
Gagang Pintu
@Doorknob Ops! Diperbaiki, terima kasih!
Averroes
3

Apakah ini seekor burung? Apakah ini pesawat terbang? Itu adalah RegExMan!

Dia mencoba menganalisis sekuens super-membosankan Anda dengan kekuatan RegEx-purba pribadinya!

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

Ditulis dengan Python 2.7, jalankan bersama python RegExMan.py [history]

Sandi
sumber
3

Sisilia

Tapi ini sangat sederhana! Yang harus saya lakukan adalah ilahi dari apa yang saya ketahui tentang manusia gua lainnya: apakah dia manusia gua yang akan memblokir, menajamkan, atau menusuk? Sekarang, manusia gua yang pandai akan menusuk atau memblokir, karena dia akan tahu bahwa hanya orang bodoh yang akan menajamkan dan mengekspos dirinya untuk menyerang. Saya bukan orang bodoh, jadi saya jelas tidak bisa mengasah. Tapi manusia gua lainnya pasti tahu aku bukan orang bodoh, dan akan mengandalkan itu, jadi aku jelas tidak bisa menyodok atau memblokir!

Jalankan dengan:

javac Sicillian.java
java Sicillian

Kode:

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;
    }
}
amwallis
sumber
3

bash-magnon

Bash-magnon dibangun dengan kuat dan kuat. Tubuh itu umumnya berat dan kokoh dengan otot-otot yang kuat. Keningnya cukup lurus daripada miring seperti di Neanderthal, dan hanya dengan sedikit alis. Wajahnya pendek dan lebar. Dagunya menonjol. Kapasitas otak sekitar 1.600 sentimeter kubik (98 cu in), lebih besar dari rata-rata manusia modern. Namun, penelitian terbaru menunjukkan bahwa dimensi fisik yang disebut "Bash-Magnon" tidak cukup berbeda dari manusia modern untuk menjamin penunjukan yang terpisah.

Saya punya otak, saya ingat.

Ini adalah eksekusi sendiri ./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
Emmanuel
sumber
1+ Anda jelas memiliki alat yang tepat untuk pekerjaan itu dan nama-nama gua Anda cukup menyenangkan :) (Saya pribadi lebih suka ikan)
Sylwester
@Sylwester Terima kasih itu +1 pertama saya. Pertama saya mencoba membuat automata homeostatis yang terinspirasi oleh apa yang dilakukan oleh si cybernetician pertama yang merasakan keseimbangannya sendiri, kemudian saya menyerah dan membuat skrip bash.
Emmanuel
2

PokeBackBot

Cukup diadaptasi dari PokeBot:

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

Jalankan dengan ruby pokebackbot.rb.

Ini menggunakan strategi paling sederhana berikutnya, dan memblokir "dengan sabar" untuk satu putaran sebelum menyerang.

Martin Ender
sumber
3
@PeterTaylor saya membaca bahwa tidak diizinkan untuk mengubah strategi saya berdasarkan sidik jari lawan. Jika kiriman saya hanya dapat mengalahkan satu kiriman lainnya, itu tidak akan benar-benar memengaruhi skor kiriman lainnya, dan kiriman saya sendiri mungkin akan mendapatkan harga yang sangat buruk. Selain itu, jika hanya ada satu pengajuan, dan yang kedua ditulis, yang kedua kemungkinan akan mengalahkan yang pertama (karena kalau tidak, mengapa repot-repot) - apakah itu saja memenuhi syarat sebagai "spesifik untuk program lain"? Bot saya akan mengalahkan semua bot yang dimulai dengan SPS(yang tampaknya masuk akal), tetapi sejauh ini PokeBot adalah satu-satunya di sekitar.
Martin Ender
2

Pendekar pedang

Ditulis dalam Python 3.4 (bekerja dengan Python 3.x)

Berusaha mendapatkan pedang secepat mungkin tetapi menyerang jika memiliki kesempatan untuk memukulnya (ketajaman> 0) dan musuh juga bisa melukainya (ketajaman musuh> 0).
Blok hanya jika tidak memiliki ketajaman dan musuh bisa menyerang.

Dimulai dari:

python3 swordmaster.py MOVES

(diasumsikan Anda menyimpannya sebagai swordmaster.py)

Kode cepat dan jelek:

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

(Setel dgke Trueuntuk mengaktifkan pesan debug)

dinginkan
sumber
1
Petunjuk: Jangan biarkan pertempuran itu sendiri - itu akan deadlock dengan S, P, S, P...
chill0r
Saya menemukan ini terjadi dengan saya juga. Kecuali Anda memeriksa sejarah atau menggunakan tingkat keacakan, Anda pasti akan terjebak dalam suatu siklus.
Pharap
2

FoolMeOnce.py

Simpan gerakan masing-masing pemain untuk duel pertama, lalu ulangi dengan gerakan yang sama persis. Jika algoritme musuh adalah nonrandom, kami dapat memprediksi hasil dan serangan yang sama hanya ketika kami tahu kami akan menang.

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)

Ditulis dengan python 3, jadi kemungkinan besar Anda harus menggunakan python3 FoolMeOnce.py Pada putaran pertama, saya tidak yakin apakah kami mendapatkan string kosong atau hanya koma, sehingga mungkin diperlukan beberapa penyesuaian.

tzazy
sumber
Saya telah memperbaiki jalur file Anda - ternyata direktori kerja saat ini bukan milik program Anda.
Gagang Pintu
Saat bermain dengan tester CavemanDuel, saya perhatikan bahwa FoolMeOnce mendapatkan poin yang jauh lebih baik jika saya menggunakan lebih banyak utas (saya menguji 16 utas melawan 4). Dengan 4 utas, ia mendapat ~ 25 poin, dengan 16 utas ~ 34.
wendelbsilva
Aneh, saya tidak tahu mengapa itu terjadi.
tzazy