Caveman Duels (หรือ: ฉันแหย่คุณด้วยไม้แหลม)


151

มนุษย์ถ้ำบ้า มนุษย์ถ้ำคนอื่นเอาไม้มา แต่ติดสำหรับฉัน การต่อสู้มนุษย์ถ้ำ!


ลักษณะ

มนุษย์ถ้ำต้องการไม้แหลมคมเพื่อแทงมนุษย์ถ้ำอื่น ๆ มนุษย์ถ้ำคนอื่น ๆ ก็พยายามแทงด้วยไม้แหลม มนุษย์ถ้ำสามารถลับคมไม้แทงด้วยไม้หรือบล็อกไม้โปเก้ได้

ถ้ามนุษย์ถ้ำโผล่มนุษย์ถ้ำคนอื่นด้วยไม้แหลมมนุษย์ถ้ำคนอื่นวิ่งหนีและชัยชนะของฉัน แต่ถ้ามนุษย์ถ้ำคนอื่นปิดกั้นอย่างชาญฉลาดเมื่อฉันโผล่ไม่มีอะไรเกิดขึ้นยกเว้นไม้เท้าของฉันกลายเป็นทื่อและฉันต้องลับคมอีกครั้ง

มนุษย์ถ้ำขี้เกียจ นอกจากนี้มนุษย์ถ้ำยังเป็นใบ้ มนุษย์ถ้ำไม่ทราบว่าจะต้องทำอย่างไรมนุษย์ถ้ำจึงต้องการโปรแกรมคอมพิวเตอร์เทคโนแฟนซีเพื่อบอกมนุษย์ถ้ำว่าต้องทำอย่างไร

อินพุต

ข้อมูลโปรแกรมของคุณจะเป็นประวัติของเหตุการณ์ที่เกิดขึ้นซึ่งSย่อมาจากความคมชัด (เช่นมนุษย์ถ้ำเหลาไม้เท้าของเขา) Pย่อมาจากการกระตุ้นและBย่อมาจากบล็อก อินพุตจะเป็นประวัติของทั้งสองฝ่าย (คุณและฝ่ายตรงข้าม) ดังนั้นการเคลื่อนไหวของคุณและฝ่ายตรงข้ามจะถูกคั่นด้วยเครื่องหมายจุลภาค ( ,)

อินพุตตัวอย่าง:

SPB,SBB

ซึ่งหมายความว่าผู้เล่นลับไม้เท้าของเขา / เธอแล้วแหย่จากนั้นปิดกั้นและฝ่ายตรงข้ามรุนแรงขึ้นจากนั้นปิดกั้นจากนั้นปิดกั้นอีกครั้ง

คุณจะไม่ได้รับการป้อนข้อมูลในเทิร์น 1

เอาท์พุต

เอาต์พุตคล้ายกับอินพุต (เนื่องจากมนุษย์ถ้ำไม่ฉลาดมาก) โปรแกรมของคุณควรส่งออกSเพื่อความคมชัดPสำหรับกระตุ้นและBบล็อก เฉพาะอักขระตัวแรกของเอาต์พุตที่จะถูกนำมาพิจารณาและอินพุตอื่น ๆ จะถือว่าเป็นBคำสั่ง (บล็อก)

  • S: คมชัดขึ้น

    เมื่อเพิ่มความคมชัดความเฉียบแหลมของมนุษย์ถ้ำจะเพิ่มขึ้น 1 และไม้จะเพิ่มขึ้นอีก 1 ครั้ง การกระตุ้นแต่ละครั้งจะลดความคมชัดของแท่งไม้ลง 1 และถ้าความคมชัดของไม้เป็น 0 มันก็น่าเบื่อเกินไปที่จะกระตุ้นด้วย ความคมชัดเริ่มต้นที่ 0 หากความคมชัดถึง 5 ไม้เป็นดาบ! (ดูด้านล่าง)

    หากฝ่ายตรงข้ามโผล่ในขณะที่คุณกำลังลับคม (และพวกเขามีความคมชัด> 0) ฝ่ายตรงข้ามชนะ!

  • P: แหย่

    เมื่อทำการเจาะไม้แหลมของมนุษย์ถ้ำจะลดลง 1 และคุณกระตุ้นฝ่ายตรงข้าม! หากฝ่ายตรงข้ามของคุณลับคมคุณชนะ! หากฝ่ายตรงข้ามโผล่คุณไม้ตีไม้เท้าของฝ่ายตรงข้ามและพวกเขาทั้งสองได้รับทึบ (โดย 1 "หน่วยความคมชัด") หากฝ่ายตรงข้ามกำลังปิดกั้นไม่มีอะไรเกิดขึ้นยกเว้นว่าไม้เท้าของคุณกลายเป็นหมองคล้ำ

    หากคุณโผล่เมื่อความคมชัดของไม้เท้าของคุณเป็น 5 หรือมากกว่าไม้ของคุณกลายเป็นดาบและคุณจะชนะเสมอ ! (เว้นเสียแต่ว่าฝ่ายตรงข้ามของคุณมีดาบและเลือกPด้วย; ในกรณีนี้พวกเขาทั้งคู่จะหมองคล้ำและอาจเปลี่ยนกลับมาใช้ไม้ได้หากความคมชัดต่ำกว่า 5)

    คุณไม่สามารถกระตุ้นด้วยความคมชัดที่ 0 ถ้าคุณทำจะไม่มีอะไรเกิดขึ้น

  • B: บล็อก

    เมื่อคุณบล็อกจะไม่มีอะไรเกิดขึ้นเมื่อฝ่ายตรงข้ามโผล่ หากคู่ต่อสู้ของคุณไม่ได้กระตุ้นการบล็อกก็ไม่ทำอะไรเลย

    การบล็อกไม่ได้ป้องกันดาบแม้ว่าคุณจะมีก็ตาม!

กฎและข้อ จำกัด

กฎเพิ่มเติมคือ:

  • โปรแกรมของคุณสามารถอ่านและเขียนไฟล์ในโฟลเดอร์ของตัวเอง (ไม่ขโมย!) หากคุณต้องการบันทึกข้อมูล แต่คุณไม่สามารถเข้าถึงสิ่งใด ๆ นอกเหนือจากนั้น (และ cavemen ไม่มีการเชื่อมต่ออินเทอร์เน็ตในที่รกร้างว่างเปล่า)
    • หมายเหตุสำคัญเกี่ยวกับไฟล์ : หากคุณบันทึกไฟล์โปรดอย่าลืมบันทึกไว้ในไดเรกทอรีplayers/YourBotsName/somefile.foo! ไดเรกทอรีการทำงานปัจจุบันสำหรับโปรแกรมของคุณจะไม่เป็นโปรแกรมของคุณ!
  • Cavemen มีความยุติธรรม: โปรแกรมหนึ่งไม่สามารถมีรหัสเฉพาะสำหรับโปรแกรมอื่นและโปรแกรมไม่สามารถช่วยเหลือซึ่งกันและกันได้ (คุณอาจมีหลายโปรแกรม แต่ไม่สามารถโต้ตอบกันได้ แต่อย่างใด)
  • ผู้พิพากษามนุษย์ถ้ำไม่อดทน หาก cavemen ใช้เวลามากกว่า 100 รอบในการตัดสินผู้ชนะผู้พิพากษาจะเบื่อและ cavemen ทั้งคู่แพ้

หากโปรแกรมของคุณผิดกฎหรือไม่ปฏิบัติตามข้อกำหนดโปรแกรมจะถูกตัดสิทธิ์ลบออกจากplayerlist.txtและการดวลทั้งหมดจะเริ่มต้นใหม่ตั้งแต่ต้น หากโปรแกรมของคุณถูกตัดสิทธิ์หัวหน้ามนุษย์ถ้ำ (ฉัน!) จะแสดงความคิดเห็นในโพสต์ของโปรแกรมและอธิบายว่าทำไม หากคุณไม่ได้ละเมิดกฎใด ๆ โปรแกรมของคุณจะถูกเพิ่มไปยังกระดานแต้มนำ (หากโปรแกรมของคุณไม่ได้อยู่ในกระดานผู้นำไม่มีความคิดเห็นอธิบายในโพสต์ของคุณและคุณโพสต์โปรแกรมของคุณก่อนเวลา "อัพเดทล่าสุด" ด้านล่างบอกผู้นำถ้ำ! บางทีเขาอาจลืมมัน)

ในโพสต์ของคุณโปรดรวม:

  • ชื่อ.
  • คำสั่งเปลือกเพื่อเรียกใช้โปรแกรมของคุณ (เช่น. java MyBot.java, ruby MyBot.rb, python3 MyBot.pyฯลฯ )
    • หมายเหตุ: อินพุตจะถูกต่อท้ายสิ่งนี้เป็นอาร์กิวเมนต์บรรทัดคำสั่ง
    • cavemen ใช้ Ubuntu 14.04 ดังนั้นตรวจสอบให้แน่ใจว่าโค้ดของคุณทำงานได้อย่างอิสระ
  • หมายเลขเวอร์ชันหากรหัสของคุณทำงานแตกต่างกันไปตามรุ่นที่คุณเลือก
  • รหัสของคุณ (ชัด)
  • วิธีรวบรวมรหัสหากจำเป็น

รหัส / การทดสอบคอนโทรลเลอร์บอทตัวอย่าง

ผู้นำถ้ำเขียนรหัสควบคุมใน C ++ และโพสต์ไว้บน repo คุณสามารถเรียกใช้และทดสอบโปรแกรมของคุณได้ที่นั่น

มากมากโปรแกรมที่ง่าย (สาย 1) นอกจากนี้ยังโพสต์ในคำตอบดังต่อไปนี้

เกณฑ์การให้คะแนนและลีดเดอร์บอร์ด

การให้คะแนนเป็นเรื่องง่าย มนุษย์ถ้ำคนใดที่ชนะจะได้รับแต้ม มนุษย์ถ้ำที่มีคะแนนมากที่สุดหลังจากการดวล 3 ครั้งต่อมนุษย์ถ้ำทุกคนกลายเป็นผู้นำมนุษย์ถ้ำคนใหม่!

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

(กระดานแต้มนำนี้สร้างขึ้นโดยอัตโนมัติอย่างน่าอัศจรรย์)

ผู้เล่นที่ทำเครื่องหมายด้วย*ข้อผิดพลาดหรือข้อยกเว้นบางชนิดโยนในบางจุด; ผู้เล่นเหล่านี้มีความคิดเห็นในโพสต์

ผู้เล่นที่ไม่สามารถรวมในการทดสอบด้วยเหตุผลใด ๆ (ผู้เล่นเหล่านี้จะมีความคิดเห็นในโพสต์ของพวกเขาอธิบายปัญหา): Monkey, Elephant, ,FacileFibonacciStudiousSylwester

อัพเดทล่าสุด: 3 ส.ค. 00:15 (UTC)


ฉันประหลาดใจที่ดูเหมือนว่าไม่มีใครพยายามที่จะหากลยุทธ์ขั้นต่ำสุดเลย ดูเหมือนว่าสิ่งที่ชัดเจนที่จะทำ
user2357112

@ user2357112 ฉันไม่คิดว่า minimax เป็นการปรับปรุงที่นี่ ฉันหมายความว่าคุณสามารถออกแบบการใช้งานมินิแม็กซ์ได้ แต่เนื่องจากตรรกะนั้นง่ายดังนั้นพฤติกรรมที่แน่นอนเดียวกันสามารถแสดงด้วยเครื่องสถานะ จำกัด (เช่นบอทจะไม่ลับคมจนกว่าฝ่ายตรงข้ามจะน่าเบื่อเพราะถ้าทำได้การเคลื่อนไหวที่ลดลงของฝ่ายตรงข้ามจะเป็นการกระตุ้นและคุณจะสูญเสียบอทจะบล็อกเสมอจนกว่าเราจะมีดาบเพราะการเคลื่อนไหวสูงสุดสำหรับบอทของเราจะ จะบล็อก ฯลฯ )
HuddleWolf

3
หลายรายการดูเหมือนจะอนุญาตให้มีความคมชัดเชิงลบในการคำนวณของพวกเขา กฎตามที่เขียนบอกว่าไม่มีอะไรเกิดขึ้นเมื่อคุณโผล่ด้วยศูนย์ความคมชัด "ไม่มีอะไร" นั่นหมายความว่าความคมชัดของคุณยังคงเป็นศูนย์อยู่แทนที่จะลดลงหรือไม่?
Sparr

6
นี้ความต้องการที่จะอยู่ที่นี่: dresdencodak.com/comics/2009-09-22-caveman_science_fiction.jpg บางทีมันอาจจะได้รับจินตนาการไป :)
Evi1M4chine

2
ยังเปิดอยู่หรือไม่ ฉันเห็นคนเพิ่มการส่งใหม่ แต่ฉันไม่เห็นว่ากระดานผู้นำกำลังได้รับการอัปเดต
ASCIIThenANSI

คำตอบ:


35

ดาร์วิน - ซี

ใครต้องการกลยุทธ์กันล่ะ มีกลุ่มมนุษย์ถ้ำเดินทางต่อกันและปล่อยให้การคัดเลือกโดยธรรมชาติทำส่วนที่เหลือ!


เราใช้แบบจำลองที่ง่ายมากสำหรับสมองดั้งเดิมของมนุษย์ถ้ำ: มันไม่มีความทรงจำและคำนึงถึงความคมชัดของเขาและไม้เท้าของคู่ต่อสู้เท่านั้น สิ่งเหล่านี้ถูกใช้เป็นตัวแปรสำหรับพหุนามไบนารี่ของลำดับ จำกัด บางอัน แต่ละการกระทำ (บล็อกความคมชัดและการกระตุ้น) มีพหุนามที่เกี่ยวข้องซึ่งผลลัพธ์จะกำหนดความน่าจะเป็นสัมพัทธ์ของการเลือกการกระทำนี้ นั่นคือทั้งหมดที่มันมี --- เริ่มต้นด้วยสัมประสิทธิ์แบบสุ่มและเพิ่มประสิทธิภาพซ้ำ ๆ

บอท:

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

รวบรวมกับ: gcc darwin.c -odarwin -w -O3. ./darwin <history>ทำงานด้วย:

บอทอ่านค่าสัมประสิทธิ์จากไฟล์ที่มีชื่อprogramในplayers/Darwinไดเรกทอรี (สามารถระบุไฟล์อื่นเป็นอาร์กิวเมนต์บรรทัดคำสั่งที่สอง) โปรแกรมนี้น่าจะทำได้ดี:

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 

players/Darwin/programบันทึกเป็น

ต่อไปนี้เป็นโปรแกรมที่สร้างprogramไฟล์ที่ bot สามารถใช้งานได้ (ไม่ต้องรวบรวมถ้าคุณใช้programไฟล์ด้านบน):

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

รวบรวมกับ: gcc genprog.c -ogenprog -w -O3. ./genprog [output-filename]ทำงานด้วย:


วัตสัน

DNA ของมนุษย์ถ้ำที่ชนะคืออะไร? บางทีไอ้หนุ่มนี้มีคำตอบ:

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

ทำงานด้วย: python Watson.py

วัตสันเป็นผลิตภัณฑ์ของอัลกอริทึมทางพันธุกรรม ซึ่งแตกต่างจากดาร์วินตัวเลขทางพันธุกรรมในครั้งนี้เป็นโปรแกรมจริงเขียนในภาษาเฉพาะโดเมนเล็ก ๆ (ที่นี่แปลเป็นงูหลาม)


Simple Sequence Beats ผู้เล่นตัวใหญ่

ไอ้หนุ่มน้อยคนนี้ทำได้ดีอย่างน่าประหลาดใจ (หรืออาจจะไม่แปลกใจ) โดยเฉพาะกับผู้นำ:

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

ทำงานด้วย: python SSBBP.py


ฉันจะรวบรวมและเรียกใช้สิ่งนี้ได้อย่างไร นอกจากนี้ตามที่กล่าวถึงในคำถามคุณสามารถอ่าน / เขียนไฟล์ในplayers/Darwinไดเรกทอรีได้เท่านั้น
Doorknob

@Doorknob: แก้ไขแล้ว
DarwinBot

ฉันได้รับข้อผิดพลาดในการรวบรวมเมื่อรวบรวมรหัสนี้ (ฉันใช้ Ubuntu 14.04)
Doorknob

@Doorknob: แก้ไขแล้ว ควรทำงานตอนนี้
DarwinBot

ตอนนี้ฉันได้รับundefined reference to `fmax'แล้ว --Edit-- -lmไม่เป็นไรฉันไม่แน่นอนต้อง
Doorknob

50

มนุษย์ถ้ำที่คาดเดาไม่ได้

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!

มนุษย์ถ้ำนี้เลือกสุ่มในแต่ละรอบ แต่ฉันอธิบายให้เขาฟังอย่างมากว่าการกระทำบางอย่างอาจไม่สมเหตุสมผล อย่าลังเลที่จะคัดลอกรหัสนี้หากคุณต้องการแสดงตรรกะที่แตกต่างกัน

นี่คือทับทิมบันทึกเป็น 'unpredictable.rb' และเรียกใช้ด้วย ruby unpredictable.rb


ที่จริงแล้วสิ่งที่ฉันno 'Block'ควรจะเป็นถ้าคู่ต่อสู้ของฉันมีดาบ
njzk2

อันแรกที่ไม่มี 'บล็อก' ปิดบังจริง: แท่งแหลมไม่ได้เป็นดาบ
ประวัติศาสตร์

2
ทำไมคุณไม่ใช้unlessเพื่อการno 'Block'และno 'Pokeงบ? ( no 'Block' unless he.has_pointy_stick)
wchargin

25

หมอถ้ำ - ลัวะ

"ฉันสูญเสียชาวต่างชาติใหม่ ๆ พาพวกเขาออกไปศึกษาพวกเขา"

เมื่อคุณเห็นผู้ป่วยมากเท่าหมอถ้ำคุณจะเริ่มเข้าใจจิตใจมนุษย์ถ้ำอย่างแท้จริง (หรือฉันหวังอย่างนั้น) เกมของหมอถ้ำเป็นกลยุทธ์ที่บริสุทธิ์เขารอให้โผล่ออกมาซึ่งเขาบล็อกในความพยายามที่จะปลดอาวุธคู่ต่อสู้ของเขา แต่เขาจะไม่ยอมให้คู่ต่อสู้เข้าใกล้เพื่อสร้างดาบ เขาพยายามทำนายเมื่อมันปลอดภัยที่จะลับคมเพื่อที่เขาจะได้ไม่หลุดมือบน

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

ทำงานด้วย: lua CaveDoctor.lua


3
การทำเช่นนี้จะหายไปสองเท่าในกระดานผู้นำปัจจุบัน? oO
justhalf

การแก้ไขครั้งที่ 5 ส่งข้อผิดพลาดจำนวนมากดังนั้นการแก้ไข 4 จึงเป็นสิ่งที่รวมอยู่ในการทดลองรอบปัจจุบัน
Doorknob

@Doorknob ฉันคิดว่าฉันได้แก้ไขทั้งหมดของพวกเขามีการเปลี่ยนแปลงเพียงอย่างเดียวกับตรรกะที่เกิดขึ้นจริงอย่างไรก็ตาม
Nexus

20

ForeignCaveman

ForeignCaveman ไม่รู้ว่าคุณเพิ่งพูดอะไร เขาแค่ ... ทำสิ่งต่างๆ

javac ForeignCaveman.java แล้วก็ java ForeignCaveman

public class ForeignCaveman {

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

11
นี่อาจมี upvotes มากเกินไปสำหรับวิธีการที่ไม่ดี
Kevin L

19

รองหัวหน้า

ลูกบิดประตู♦เป็นผู้นำ ฉันต้องการเป็นผู้นำ! ติดตามโปรแกรมสุดอัจฉริยะเพื่อเป็นผู้นำ!

รวบรวม: Run:javac ViceLeader.javajava 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;
    }
}

ทำไมไม่เป็นแบบนี้if (enemySharpness <= 4 || mySharpness >= 5)VS ==?
durron597

@ durron597 เพราะฉันเพียงแค่ต้องการกระตุ้นศัตรูถ้าเขาสามารถสร้างดาบในเทิร์นถัดไป (ซึ่งเขาน่าจะทำ) VizeLeader ไม่โผล่บ่อยครั้งมันไม่ได้ในเวลาที่เหมาะสม
CommonGuy

แต่คุณมีดาบและคู่ต่อสู้ของคุณไม่ได้ ...
durron597

@ durron597 ไม่มันเป็นคำสั่ง OR มันหมายถึง "กระตุ้นฝ่ายตรงข้ามถ้าฉันมีดาบหรือถ้าเขาจะมีดาบในไม่ช้า"
CommonGuy

7
โอ้พระเจ้า ได้เวลาดื่มกาแฟแล้ว :) หรือคอนแทคเลนส์ใหม่
durron597

15

อาจจะมาร์คอฟ 2.1

ฉันคิดว่ามันใช้มาร์คอฟเชนเพื่อทำนายว่ามนุษย์ถ้ำคนอื่นจะทำอะไร แต่ฉันก็ดูหน้าวิกิพีเดียสั้น ๆ เกี่ยวกับมาร์คอฟเชนและตัดสินใจว่ามันมีข้อความมากเกินไป

มันพยายามที่จะมีชีวิตอยู่ 30 รอบแล้วสร้างตารางที่มีการเปลี่ยนแปลงสถานะปัจจุบัน - ถัดไปและตอบสนองต่อสิ่งที่คิดว่ามนุษย์ถ้ำคนอื่นจะทำ

รหัสมีข้อความที่ไม่จำเป็นจำนวนมาก แต่ทำงานได้ค่อนข้างดี

แก้ไข

ตรวจพบข้อบกพร่องในตรรกะ ตอนนี้มันทำอะไรบางอย่างเมื่อมีดาบ

$ python3 players/MaybeMarkov/MaybeMarkov.py

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

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

all_actions = SHARPEN, POKE, BLOCK
always = 1

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

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

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

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

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


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

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

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

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

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

if turns > 97:
    do(POKE)

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

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

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

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

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

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

counts = itemgetter(1)

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

react_on(prediction)

14

PeriodicalCicadaCaveman

มนุษย์ถ้ำที่ฉลาดคนนี้ได้ศึกษาข้อผิดพลาดบางอย่างและตระหนักว่าไม่มีใครสามารถปรับวิถีชีวิตของพวกเขาเพื่อใช้ประโยชน์จากจั๊กจั่นหมายเลขดี

มันซ่อน / บล็อกส่วนใหญ่ของชีวิต แต่บางครั้งก็โผล่ แน่ใจว่ามันไวต่อดาบและใช้รอบทั้งหมดด้วยไม้ที่ไม่คมชัด แต่เหลาไม้ของคุณเมื่อมันทื่อโดยสิ้นเชิง? นั่นคือสิ่งที่คนอื่นคาดหวังจากมัน ... ไม่ใช่จั๊กจั่นตัวนี้

เพื่อคอมไพล์: mcs program.csเพื่อรัน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"); 

  }

}

แก้ไข: เปลี่ยนความคมชัด - รหัส ... หากฉันกระตุ้นฉันไม่ว่าฉันจะชนะ

แก้ไข 2: เพิ่มในคำแนะนำ Bobs

แก้ไข: เปลี่ยนเป็นเพียงการกระตุ้นเมื่ออยู่ที่ความคมชัดที่ 2 หากไม้แทงเท่ากับศูนย์คนอื่นอาจทำดาบ


1
ฉันทำงานบน Ubuntu; จะคอมไพล์นี้ภายใต้โมโน? ถ้าเป็นเช่นนั้นฉันจะรวบรวมมันได้อย่างไรและฉันจะรันได้อย่างไร?
Doorknob

พูดตามตรงฉันไม่รู้ ฉันกำลังจะนอนแล้วนะ ฉันสามารถเขียนมันใหม่กับ Java ตอนเช้าที่ทำงาน รหัส Java ควรเหมือนกันเกือบ
Mikey Mouse

5
@Doorknob mcs program.csจะรวบรวมมันmono programจะเรียกใช้ แต่คุณจะต้องแทนที่foo.Dump();s ด้วยSystem.Console.WriteLine(foo);(หรือเพิ่มวิธีการขยายpublic static void Dump(this string value) { System.Console.WriteLine(value); })
Bob

@Bob ขอบคุณเพื่อนฉันได้เพิ่มวิธีการขยายของคุณ
Mikey Mouse

ขออภัยชื่อไฟล์เริ่มต้นที่เกิดขึ้นจริงmcsจะสร้างเป็น<filename>.exeเช่นก็จะกลายเป็นprogram.cs ดังนั้นคำสั่งการทำงานจะเป็นprogram.exe mono program.exe(ฉันไม่สามารถเข้าถึงขาวดำได้ในขณะที่ความคิดเห็นก่อนหน้าของฉัน)
Bob

14

FancyTechnoAlgorithm

อัลกอริทึมเทคโนแฟนซีสำหรับโปรแกรมคอมพิวเตอร์แฟนซีเทคโน

มนุษย์ถ้ำสูญเสียการต่อสู้ มนุษย์ถ้ำโกรธ ดังนั้นมนุษย์ถ้ำไปโรงเรียนคอมพิวเตอร์เรียนรู้การสร้างอัลกอริทึม

import random, sys  # Need import some advanced techno code

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

    try:  # Me try use fancy techno algorithm!

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

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

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

โปรแกรม Python 2 วิ่ง:python fancytechnoalgorithm.py


สิ่งนี้จะหยุดเมื่อไม่มีการป้อนข้อมูล (เช่นในเทิร์นแรก) ฉันไม่รู้ว่าคุณต้องการจัดการสิ่งนั้นอย่างไรฉันจะต้องแยกมันออกจากการทดสอบรอบแรก
Doorknob

@Doorknob สำหรับการป้อนข้อมูลแรกมันคือ "," หรือ ""? ฉันเดาว่ามันเป็นอย่างหลัง
Vectorized

สำหรับอินพุตแรกจะไม่มีอาร์กิวเมนต์ (ซึ่งจะถูกเรียกใช้เป็นpython StickSharpener.py)
Doorknob

@Doorknob ฉันได้แก้ไขแล้ว ดูว่ามันใช้งานได้ไหม
Vectorized

เอาล่ะขอบคุณ! ฉันจะรวมสิ่งนี้ไว้ในการทดสอบรอบถัดไป
Doorknob

14

The Watcher

เขาเฝ้าดูการเคลื่อนไหวของคู่ต่อสู้ของเขาปล่อยให้พวกเขาโชว์มือก่อนที่เขาจะโจมตี เขาได้รับการเตรียมพร้อมเป็นพิเศษสำหรับผู้ที่ละเลยงานดาบ

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

ชื่อไฟล์: watcher.py

วิ่ง: python watcher.py

กิ้งก่าขนาดใหญ่

พยายามที่จะทำลายคนที่มองเขาอย่างใกล้ชิดเกินไป ผู้ติดตาม Watcher ชนะอย่างต่อเนื่อง แต่อาจจะแย่ลงโดยรวม

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

ชื่อไฟล์: basilisk.py

วิ่ง: python basilisk.py

แนช

พยายามทำให้ตัวเลือกของคู่ต่อสู้ไม่เกี่ยวข้องโดยเลือกแต่ละการเคลื่อนไหวด้วยความน่าจะเป็นที่อธิบายถึงความเสี่ยงและผลตอบแทน

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

นี่ไม่ใช่สมดุลของ Nash (เครื่องมือสร้างกลยุทธ์ของฉันมีความไม่แน่นอน) แต่มันใกล้เคียง

เพื่อประโยชน์ของความอยากรู้นี่คือการประเมินว่าบอทนี้จะชนะในแต่ละเกมได้อย่างไร:

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

ชื่อไฟล์: nash.py

วิ่ง: python nash.py

หลอก

เปิดการโจมตีอย่างรวดเร็วเพื่อทดสอบการป้องกันของคู่ต่อสู้

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

ชื่อไฟล์: feint.py

วิ่ง: python feint.py

LatePokeBot

น้องชายคนเล็กของ PokeBot ไม่เคยแสดงความอ่อนแอ แต่พยายามต่อสู้เหมือนพี่ใหญ่ของเขา

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

ชื่อไฟล์: latepokebot.py

วิ่ง: python latepokebot.py


คุณหายไป:ในบาซิลิสก์ ฉันแก้ไขแล้วสำหรับคุณ
Doorknob

การส่งนี้ทำให้เกิดข้อผิดพลาดหรือข้อยกเว้นบางประการ คุณอาจต้องการตรวจสอบการแก้ไขก่อนการทดลองรอบถัดไป (หนึ่งใน Basilisk)
Doorknob

@Doorknob ฉันเลือกลำดับเริ่มต้นสำหรับ Basilisk โดยดูที่สมมติฐานที่ทำโดย The Watcher และ Cave Doctor และค้นหาลำดับที่จะทำให้สมมติฐานเหล่านั้นผิดพลาดอย่างรุนแรง นั่นเป็นการละเมิดกฎ "cavemen ยุติธรรม" หรือไม่?
Brilliand

ไปแนช! ชนะการแข่งขันของคุณครึ่งหนึ่งต่อบอตทั้งหมดที่ฉลาดพอที่จะหลีกเลี่ยงตัวเลือก P = 0 ของคุณ!
aschepler

12

PokeBot

เขียนใน Ruby

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

ruby pokebot.rbทำงานด้วย

บอทนี้ไม่ฉลาดมาก มันเกี่ยวกับสิ่งที่มนุษย์ถ้ำธรรมดาจะทำเอง


9

PatientWolf v2.0

ทำให้คมขึ้นหากทื่อหรือแหลมถ้าศัตรูจะมีดาบในเทิร์นถัดไปหรือหากศัตรูทื่อบล็อกในลักษณะอื่น

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

ทำงานด้วย

perl patientwolf.pl

แก้ไข: ขอบคุณ @sylwester สำหรับการชี้จุดบกพร่อง


เนื่องจากคุณได้รับหนึ่งอาร์กิวเมนต์ที่มีประวัติทั้งสองคั่นด้วยเครื่องหมายจุลภาคคุณจึงแยกวิเคราะห์ผิด เช่น. PatientWolf.pl SB,SPทำPเพราะมันคิดว่ามันมีไม้แหลม
Sylwester

@Sylwester ที่ไม่ถูกต้อง บรรทัดแรกกำหนดอาร์กิวเมนต์แรกให้กับ $ me และอาร์กิวเมนต์ที่สองให้แก่เขา $
killmous

โปรแกรม CavemanDuel ไม่ได้ใช้สองข้อโต้แย้งเพียงข้อเดียว เช่น. perl patientwolf.pl "SB,SP". คุณควรจะทำและmy($me,$him) = split/,/ $ARGV[0]; if( @ARGV ) {print "S";exit}
Sylwester

@Sylwester ok ฉันเห็นสิ่งที่คุณได้รับ ไม่ชัดเจนจาก OP หรือจากการเหลือบมองอย่างรวดเร็วที่ฉันโยนไปที่รหัสคอนโทรลเลอร์ ฉันจะแก้ไขปัญหานี้ในไม่ช้า
killmous

9

มนุษย์ถ้ำไบนารี

คมชัด, แทง, ทำซ้ำ

ตามแนวคิดที่ว่าการบล็อกนั้นมีไว้สำหรับน้องสาวมนุษย์ถ้ำคนนี้สลับกันระหว่างตัวเลือกที่เหลือสองตัว

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

รวบรวมกับ javac BinaryCaveman.java

ทำงานด้วย java BinaryCaveman

แก้ไข: การผจญภัยใน String Arrays ..... args.length () ส่งข้อผิดพลาด args.length ส่งคืน 1 เสมอ args [0] .length () ส่งคืนความยาวของสตริงแรกในอาร์เรย์

แก้ไข 2:อัปเดตด้วยความช่วยเหลือจาก Doorknob, Brilliand และ Sylwester ขอบคุณเพื่อน.


@ MartinBüttnerฉันลืมแบ่งเนื้อหา - 1 ต่อ 2 เพื่อรับเฉพาะจำนวนการส่งที่ผ่านมาโดยผู้เล่นคนเดียว แก้ไขที่ ฉันไม่เข้าใจการยอมจำนนของ Dorknob เพราะทับทิมเป็นคำที่พูดพล่อยๆไม่ได้ เขาเริ่มต้นด้วยการลับเสมอหรือไม่?
Red_Shadow

ใช่เขาแค่ตรวจสอบว่าการเคลื่อนไหวครั้งสุดท้ายของเขาเป็นPหรือSไม่และทำตรงกันข้าม และถ้ายังไม่มีประวัติเขาแสร้งทำเป็นประวัติศาสตร์จะเป็นP,(ซึ่งจะทำให้เขาต้องทำSก่อน)
Martin Ender

สองแนวทางที่แตกต่างกันซึ่งส่งผลให้ผลลัพธ์เดียวกัน มันผิดกฎหรือเปล่า?
Red_Shadow

อาจไม่ใช่ฉันแค่อยากให้คุณรู้
Martin Ender

2
@Doorknob ผมคิดว่ามันควรจะเป็นไม่ได้args[0].length() args.length
Brilliand

8

CavekidBlocks

เด็กถ้ำที่กำลังร้องไห้และหวาดกลัวอาจดูเหมือนเหยื่อง่ายๆ อย่าปล่อยให้หน้าสวยของเขาหลอกคุณเพราะเขารู้วิธีปิดกั้น

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

ทำงานด้วย python3 cavekidblocks.py

ChargerMan

มนุษย์ถ้ำนี้อนุรักษ์นิยมมาก จะพยายามชาร์จอาวุธของเขาและโจมตีเมื่อจำเป็นเท่านั้น

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)

ทำงานด้วย python3 chargerman.py

ผู้เล่นกล

คนโกงไม่รู้วิธีการต่อสู้ดังนั้นเขาจึงพยายามทำให้มนุษย์ถ้ำสับสน

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

ทำงานด้วย python3 trickster.py

น่าเสียดายที่หลังจากกระทำผิดพลาดไปแล้วacc74 Trickster ไม่ทำงานตามแผนที่วางไว้อีกต่อไป


4
โปรแกรมเล่นกลนั่นเป็นสิ่งที่ชั่วร้าย
Nexus

@ Nexus ฉันก็เช่นกัน น่าเสียดายที่ Trickster เล่นได้ไม่ดีในการดวล
wendelbsilva

7

Hodor

ฮอร์ไม่ก้าวร้าวมาก เขาชอบที่จะอยู่ในโล่ของเขาจนกว่าจะมีโอกาสที่ดีที่จะตี

คอมไพล์ด้วย: javac Hodor.javaและรันด้วย:java Hodor

รหัส:

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

แก้ไข: อัพเดตรหัสเล็กน้อย


การส่งนี้ทำให้เกิดข้อผิดพลาดหรือข้อยกเว้นบางประการ คุณอาจต้องการตรวจสอบการแก้ไขก่อนการทดลองรอบถัดไป
Doorknob

1
SB,BBลองกับ เมื่อมนุษย์ถ้ำคนอื่นประพฤติตัวไม่ดีในเทิร์นแรก Hodor ก็ทำตัวเหมือนกันเช่นกัน
Sylwester

7

เก็งกำไร Sylwester - Perl5

เก็งกำไร Sylwester ต้องการที่จะกำจัดผู้แสวงหาดาบโดยดูที่รูปแบบและกระตุ้นเมื่อมีโอกาสที่ฝ่ายตรงข้ามจะคมชัดและคมชัดเมื่อฝ่ายตรงข้ามมีแนวโน้มที่จะปิดกั้น อย่างไรก็ตามเขาจะไม่ทำอย่างนั้นหากมีโอกาสที่เขาจะเดาได้ว่าตัวเองจะลับคมในการย้ายครั้งต่อไปและเราจะยิ่งระมัดระวังมากขึ้นเมื่อเราตัดสินใจที่จะลับคม

เมื่อคู่ต่อสู้ทื่อเขาพยายามก้าวร้าว แต่ในที่สุดจะเริ่มเก็บดาบเมื่อดูเหมือนไร้ผล

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ในการรันบน linux เพียงเพิ่มใน playerlist.txt:

perl players/SpeculativeSylwester/SpeculativeSylwester.pl

Facile Fibonacci - R6RS Scheme

นอกจากการย้ายครั้งแรก Facile Fibonacci บล็อกเมื่อเทิร์นเป็นหมายเลขฟีโบนักชี (เริ่มจาก 0) และเติมส่วนที่เหลือด้วยPPSS..และการเปลี่ยนแปลงเมื่อผ่าน 8 ถึงลำดับที่ไม่มีที่สิ้นสุดของPSSการชนะด้วยดาบ

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

หากต้องการเรียกใช้เพียงติดตั้ง ikarus ด้วยapt-get install ikarusและเพิ่มใน playerlist.txt:

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

การศึกษา Sylwester - Perl5

Studious Sylwester ใช้กลยุทธ์เดียวกับเก็งกำไร Sylwester แต่เขาก็ดูเกมก่อนหน้านี้เพื่อพิจารณาว่าเขาอาจจะเลือกผิด

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

  close FH;
  close LOCK;

  return ( $override, $why );
}

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

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

ในการรันบน linux เพียงเพิ่มส่วนนี้ลงใน playerlist.txt

perl players/StudiousSylwester/StudiousSylwester.pl

แก้ไขอย่างขยันขันแข็ง

ฉันไม่สามารถทำซ้ำปัญหาที่คุณมีโดย$0ไม่ได้เป็นเส้นทางแบบเต็มไปยังสคริปต์ Perl เมื่อทำงานด้วย Perl ฉันได้ดึงการเปลี่ยนแปลงของคุณและฉันไม่เห็นการเปลี่ยนแปลงใด ๆ ใน CavemanDuels src และมันก็เหมือนกันฉันได้ใช้งาน 20+ ครั้งโดยไม่มีปัญหาที่คุณกำลังรายงาน ฉันเริ่มกลัวว่าคุณอาจได้สคริปต์มาเป็นสคริปต์ทุบตีแทนที่จะเรียกใช้ในขณะที่ปฏิบัติการหรือเป็นอาร์กิวเมนต์เพื่อ perl ฉันต้องการข้อมูลเพิ่มเติมเพื่อทราบจริงแน่นอน เป็นแบบทดสอบที่ฉันทำและคุณสามารถทำเช่นเดียวกันเพื่อดูว่าคุณได้รับผลลัพธ์เดียวกัน:

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

ดูเหมือนว่าโครงการจะไม่ต้องการให้ความร่วมมือกับฉันในเครื่องของฉันดังนั้นฉันจึงไม่สามารถทดสอบ Fibonacci one ได้ ฉันจะพยายามทำให้มันใช้งานได้ แต่จะดีมากถ้าคุณสามารถแปลเป็นภาษาอื่นได้
Doorknob

ดูเหมือนว่าคนขยันไม่ทำงานเพราะเมื่อ$0ถูกbashเรียกจากบรรทัดคำสั่ง bash (ซึ่งคอนโทรลเลอร์ทำ) แต่คุณสามารถ hardcode players/StudiousSylwester/foo.txtได้
Doorknob

@Doorknob ฉันได้เพิ่มวิธีการติดตั้งikarusและฉันได้เพิ่มความคิดของฉัน$0สำหรับการศึกษา
Sylwester

6

swordsmith

ต้องการไม้แหลม หากมีไม้แหลมให้สะบัด ฉันไม่รู้สึกเจ็บปวด

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

บันทึกเป็นswordsmith.f90และรวบรวมกับดำเนินการตามที่คุณต้องการที่ปฏิบัติการปกติใดgfortran -o swordsmith swordsmith.f90./swordsmith


สิ่งนี้ดูเหมือนจะพิมพ์ช่องว่าง (``) หน้าเอาต์พุตจริง ฉันไม่รู้ว่าจะแก้ไขอย่างไรดังนั้นฉันจะต้องแยกการส่งนี้ออกจากการทดสอบรอบแรก
Doorknob

นอกจากนี้ฉันได้แก้ไขเส้นทางไฟล์ของคุณแล้ว; เปลี่ยนไดเรกทอรีการทำงานปัจจุบันเมื่อเรียกใช้ไม่ใช่โปรแกรมของคุณ โอ้และถ้าโดย "อินสแตนซ์ใหม่" คุณหมายถึง "แต่ละเกม" ฉันทำไม่ได้เพราะนั่นต้องใช้โปรแกรมคอนโทรลเลอร์พิเศษ คุณอาจต้องการทำเช่นนั้นในรหัสของคุณเอง
Doorknob

@Doorknob: ฉันได้อัปเดตรหัสของฉัน: เอาท์พุทเป็นตัวอักษรเดียวมันจะลบไฟล์ที่มีอยู่แล้วในตอนแรกและไฟล์นั้นอยู่ในสารบบผู้เล่น
Kyle Kanos

เอาล่ะขอบคุณ! การส่งนี้รวมอยู่ในกระดานผู้นำแล้ว
Doorknob

@ Doorknob: เจ๋ง! แย่จังว่าฉันไม่ใช่คนแรก นอกจากนี้: ฉันค่อนข้างแน่ใจว่าผู้ใช้ Fortran เป็นเหมือนแวมไพร์ดังนั้นฉันค่อนข้างมั่นใจว่าคุณจะเริ่มเข้ารหัสใน Fortran ในไม่ช้า! Muahahahaha!
Kyle Kanos

5

PatientBlacksmith

บอทนี้เขียนด้วย R ใช้Rscript PatientBlacksmith.Rเพื่อกระตุ้นมัน

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)

วัดความคมชัดของคู่ต่อสู้: บล็อกเมื่อมีคมใช้เวลาในการลับคมเป็นอย่างอื่น เมื่อความคมชัดของตัวเองถึง 5 ให้กระตุ้นจนความคมชัดหายไป


สิ่งนี้จะหยุดเมื่อไม่มีการป้อนข้อมูล (เช่นในเทิร์นแรก) ฉันไม่รู้จะแก้ไขได้อย่างไรฉันจึงต้องแยกมันออกจากการทดสอบรอบที่ 1
Doorknob

@Doorknob แก้ไขแล้ว
plannapus

5

กฎคุก, Haskell

มนุษย์ถ้ำคิดว่ามนุษย์ถ้ำและมนุษย์ถ้ำอื่น ๆ ควรพูดคุยแบ่งปันไม้เท้า แต่เฮ้โฮถ้าต้องต่อสู้สู้กฎคุก ค้นหาบอสและโจมตี

ViceLeader Alpha Caveman ตอนนี้; เพื่อที่มนุษย์ถ้ำจะต้องต่อสู้ cavemen อื่น ๆ ต่อสู้ในภายหลัง ถ้ามนุษย์ถ้ำของฉันแพ้ก็ไม่ต้องกังวล เขามีขนดกเกินไป

import System.Environment


-- Tell caveman next move

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


-- How fancy techno computer program know?

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

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



-- Rest not for caveman - only techno computer

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

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

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


fight = 100


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


basedOn = movesOfEachCaveman . history

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

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


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

times m = length . filter (== m)


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

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


pokiness stick is = foldl countPokiness 0 stick

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


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

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

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

เขียนใน Haskell (ไปใช้การเขียนโปรแกรมใช้งานได้!) ดังนั้นบันทึกเป็นjailrules.hsจากนั้นรวบรวมด้วย:

ghc prisonrules.hs

และเรียกใช้เป็น:

prisonrules [history]

4

ฉันเรียกเขาว่า JavaMan

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

หมายเหตุ: ฉันไม่ได้ตั้งใจที่จะเล่นรหัสกอล์ฟ .. แต่ถ้าคุณเป็นนักกอล์ฟและช่องว่าง / เส้นพิเศษทำให้ดวงตาของคุณมีเลือดออก .. รู้สึกอิสระที่จะเปลี่ยน

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

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

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

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

}

class Player
{
    int sharpLevel;

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

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

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

4
การส่งความท้าทายของ King of the Hill ไม่ได้หมายถึงการตีกอล์ฟดังนั้นไม่ต้องกังวล ;)
Martin Ender

ฉันได้เปลี่ยนชื่อเป็น JavaMan เพราะ "Caveman" นั้นค่อนข้างธรรมดาเกินไปที่จะอยู่ในกระดานผู้นำ หวังว่าไม่เป็นไรกับคุณ ถ้าไม่เพียงแค่เปลี่ยนเป็นอย่างอื่น
Doorknob

1
สิ่งนี้จะหยุดเมื่อไม่มีการป้อนข้อมูล (เช่นในเทิร์นแรก) ฉันไม่รู้ว่าคุณต้องการจัดการกับมันอย่างไรดังนั้นฉันจะต้องแยกมันออกจากการทดสอบรอบแรก
Doorknob

คงที่และการเปลี่ยนชื่อเป็นสิ่งที่ดีกับฉัน
2813274

1
ฉันคิดว่าคุณมีข้อผิดพลาดในการแจงรัฐทั้ง 'ฉัน' และ 'ศัตรู' ได้รับการเคลื่อนไหวที่เหมือนกัน: รัฐ [0]
Roy van Rijn

4

ความคิดลึกล้ำ C

รหัสมนุษย์ถ้ำ มนุษย์ถ้ำคิด มนุษย์ถ้ำทำ

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

ฉันทำการทดสอบ คิดเพิ่มเติมดีกว่า


1
+1 สำหรับชื่อมนุษย์ถ้ำ var และความคิดเห็น: P นอกจากนี้โปรแกรมที่ดี c:
cat

3

ไนเจล

ไนเจลเป็นผู้ป่วยมนุษย์ถ้ำป้องกันตัวเก่าที่ค่อนข้างชอบยุทธวิธีมากกว่าที่จะออกไปโจมตี

มันเป็นสคริปต์ PHP, โทรด้วย php nigel.php

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

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

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

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

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

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

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

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

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

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

?>

3

Aichmophobic - Lua

เขาจะกระตุ้นคุณเป็นครั้งคราว แต่จนกว่าแท่งบางอันจะคมเกินไป เมื่อสิ่งนี้เกิดขึ้นเขาจะตื่นตระหนกและขดตัวในท่าของทารกในครรภ์

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)

รันด้วย:

lua aichmophobic.lua


2
ผลลัพธ์ของคุณจะต้องเป็นตัวพิมพ์ใหญ่ ฉันแก้ไขแล้วสำหรับคุณ (นอกจากนี้ฉันสะกดชื่อการส่งนี้ประมาณพันครั้ง: P)
Doorknob

3

ถ้ำบ๊อบ

Bob Caves เป็นหนึ่งในคนที่ฉลาดที่สุดในถ้ำของเขา เขาเรียนรู้ที่จะนับด้วยมือเดียว (อีกมือหนึ่งถือไม้เท้าไว้) เขารู้จักกีฬาโอลิมปิกยุคหินนี้และต้องการเข้าร่วม

กลยุทธ์หลักของเขาคือบล็อกและลับไม้เท้าของเขาจนกว่าเขาจะมีไม้แหลมคมที่ดีหรือมนุษย์ถ้ำคนอื่นก็มีไม้แหลมคมเช่นกัน ในกรณีนี้บ็อบถ้ำพยายามกระตุ้นเขา!

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

}

รวบรวมjavac BobCaves.javaและเรียกใช้ด้วยjava BobCaves

แก้ไข: ตอนนี้บ๊อบนับเมื่อมีบล็อกใด ๆ ! (ขอบคุณMikey Mouse ) นอกจากนี้เขาจะแหลมไม้ของเขาเมื่อแท่งไม้ถ้ำอื่นไม่คม

แก้ไข 2: วิธีการนับที่ปรับปรุงแล้ว (ขอบคุณ Mikey อีกครั้ง)

แก้ไข 3: ทำให้บ๊อบก้าวร้าวมากขึ้นเล็กน้อย


2
บ๊อบลืมจำนวนผลของ Poke: บล็อกด้วยความคมชัดของไม้ สาม "S" ใน s ไม่ได้หมายความว่าติด 3 ครั้ง "P" ทุกตัวในแท่งแปลว่า Huh huh huh ... "Pee" มนุษย์ถ้ำเรื่องตลก ...
กี้เมาส์

@ MikeyMouse Bob เห็นด้วย บ็อบจะไปหาหมอแม่มดเพื่อพัฒนาเทคนิคของเขา บ๊อบขอบคุณ!
Averroes

1
แม่มดหมอสอนให้บ๊อบเก่ง แต่เขาลืมพูดถึง Poke: สถานการณ์ Poke ติดรับทื่อแล้วเช่นกัน บ๊อบไม่จำเป็นต้องพิจารณาย้ายฝ่ายตรงข้าม หาก Bob Poke ติดได้รับทื่อ ทั้งทื่อเมื่อ: ฝ่ายตรงข้ามโผล่บนบล็อกของฝ่ายตรงข้ามหรือบนหัวของฝ่ายตรงข้าม ถ้าอยู่บนหัวของฝ่ายตรงข้ามบ๊อบชนะและสามารถเต้นไปรอบ ๆ ถ้ำได้ด้วยไม้ทื่อ
Mikey Mouse

1
@ MikeyMouse Bob รู้วิธีนับ บ๊อบต้องเรียนรู้ที่จะอ่าน ขอบคุณอีกครั้ง!
Averroes

3

Gruntt

Gruntt นั้นรับการป้องกัน Gruntt วิเคราะห์มนุษย์ถ้ำคนอื่น ๆ รู้วิธีสะกิดพวกมัน จากนั้นเขาก็โผล่เข้าตา Gruntt ไม่ใช่มนุษย์ถ้ำที่ดี

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

}

รวบรวมjavac Gruntt.javaและเรียกใช้ด้วยjava Gruntt


นี่จะเป็นการโยนArrayOutOfBoundsExceptionในเทิร์นแรกและบางครั้งก็เอาท์พุทหลายการกระทำในเทิร์นอื่น
Doorknob

@ Doorknob Ops! คงที่ขอบคุณ!
เฉลี่ย

3

นี่มันคือนก? มันเป็นเครื่องบินหรือไม่? มันคือ RegExMan!

เขาพยายามวิเคราะห์ลำดับขั้นสุดยอดของคุณด้วยพลังพิเศษยุคแรกของเขา RegEx!

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

def whatAmIDoing(opnHist, meSharp, opnSharp) :

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

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

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

เขียนใน Python 2.7 ทำงานด้วย python RegExMan.py [history]


3

Sicillian

แต่มันง่ายมาก! สิ่งที่ฉันต้องทำก็คือพระเจ้าจากสิ่งที่ฉันรู้จากมนุษย์ถ้ำคนอื่น ๆ : เขาเป็นมนุษย์ถ้ำที่จะปิดกั้นลับหรือแหลมหรือไม่? ตอนนี้มนุษย์ถ้ำที่ฉลาดจะกระตุ้นหรือบล็อกเพราะเขาจะรู้ว่ามีเพียงคนโง่ที่ดีเท่านั้นที่จะลับคมและเปิดเผยตัวเองเพื่อโจมตี ฉันไม่ใช่คนโง่ตัวใหญ่ดังนั้นฉันจึงไม่สามารถลับคมได้อย่างชัดเจน แต่มนุษย์ถ้ำคนอื่น ๆ ต้องรู้ว่าฉันไม่ใช่คนโง่ที่ยอดเยี่ยมและจะเชื่อใจในสิ่งนั้นดังนั้นฉันจึงไม่สามารถกระตุ้นหรือปิดกั้นได้อย่างชัดเจน!

ทำงานด้วย:

javac Sicillian.java
java Sicillian

รหัส:

public class Sicillian {

    public static void main(String[] args) {

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

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

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

            else {          // Inconceivable!

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

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

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

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

3

ทุบตี-Magnon

Bash-magnons นั้นถูกสร้างและแข็งแกร่ง ร่างกายโดยทั่วไปหนักและแข็งด้วยกล้ามเนื้อแข็งแรง หน้าผากนั้นค่อนข้างตรงมากกว่าที่จะลาดเอียงเหมือนในยุคมนุษย์ยุคใหม่และมีขนคิ้วเพียงเล็กน้อยเท่านั้น ใบหน้าสั้นและกว้าง คางนั้นเด่น สมองมีความจุประมาณ 1,600 ลูกบาศก์เซนติเมตร (98 ลูกบาศ์กเมตร) ซึ่งสูงกว่าค่าเฉลี่ยสำหรับมนุษย์สมัยใหม่ อย่างไรก็ตามการวิจัยล่าสุดแสดงให้เห็นว่ามิติทางกายภาพของสิ่งที่เรียกว่า "Bash-Magnon" นั้นไม่แตกต่างจากมนุษย์สมัยใหม่พอที่จะรับประกันการกำหนดแยกต่างหาก

ฉันมีสมองฉันจำได้

นี่คือปฏิบัติการด้วยตนเอง ./bash-magnon.sh

#!/bin/bash

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

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

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

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

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

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

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

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

1+ เห็นได้ชัดว่าคุณมีเครื่องมือที่เหมาะสมสำหรับงานและชื่อ cavemen ของคุณค่อนข้างสนุก :) (โดยส่วนตัวแล้วฉันชอบปลาที่ดีกว่า)
Sylwester

@Sylwester ขอบคุณที่ +1 ครั้งแรกของฉัน ฉันพยายามสร้างออโตมาตาแบบ homeostatic ที่ได้รับแรงบันดาลใจจากสิ่งที่ไซเบอร์เนติกส์คนแรกที่รู้สึกถึงความสมดุลของตัวเองจากนั้นฉันก็เลิกและทำสคริปต์ทุบตี
Emmanuel

2

PokeBackBot

ดัดแปลงมาจาก PokeBot:

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

ทำงานด้วย ruby pokebackbot.rbทำงานด้วย

สิ่งนี้ใช้กลยุทธ์ที่ง่ายที่สุดถัดไปและบล็อก "อดทน" หนึ่งรอบก่อนการโจมตี


3
@ PeterTaylor ฉันอ่านว่าไม่ได้รับอนุญาตให้เปลี่ยนกลยุทธ์ของฉันโดยอาศัยการพิมพ์ลายนิ้วมือของคู่ต่อสู้ หากการส่งของฉันสามารถเอาชนะการส่งอื่นได้เพียงครั้งเดียวนั่นจะไม่ส่งผลกระทบต่อคะแนนการส่งอื่น ๆ และการส่งของฉันเองอาจจะแย่มาก นอกจากนี้หากมีเพียงการส่งเพียงครั้งเดียวและการเขียนครั้งที่สองจะมีการส่งครั้งที่สอง (เพราะเหตุใดรบกวนทำไม) - ที่เพียงอย่างเดียวที่มีคุณสมบัติเป็น "เฉพาะสำหรับโปรแกรมอื่น"? บอทของฉันจะเอาชนะบอทใด ๆ ที่ขึ้นต้นด้วยSPS(ซึ่งดูเหมือนว่าสมเหตุสมผล) แต่จนถึงตอนนี้ PokeBot เป็นเพียงรอบเดียว
Martin Ender

2

จอมกระบี่

เขียนใน Python 3.4 (ใช้ได้กับ Python 3.x)

พยายามรับดาบให้เร็วที่สุดเท่าที่จะเป็นไปได้ แต่โจมตีถ้ามันมีโอกาสที่จะชนเขา (ความคมชัด> 0) และศัตรูก็สามารถทำร้ายได้เช่นกัน (ความคมชัดของศัตรู> 0)
บล็อกเฉพาะในกรณีที่ไม่มีความคมชัดและศัตรูสามารถโจมตีได้

เริ่มกับ:

python3 swordmaster.py MOVES

(สมมติว่าคุณบันทึกเป็นswordmaster.py)

รหัสอย่างรวดเร็วและน่าเกลียด:

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

(ตั้งค่าdgเป็นTrueเปิดใช้งานข้อความแก้ไขข้อบกพร่อง)


1
คำแนะนำ: อย่าปล่อยให้มันต่อสู้กับตัวเอง - มันจะหยุดชะงักด้วยS, P, S, P...
chill0r

ฉันพบว่าสิ่งนี้เกิดขึ้นกับฉันด้วย ถ้าคุณไม่ตรวจสอบประวัติหรือใช้การสุ่มระดับคุณก็จะติดค้างในวงจร
Pharap

2

FoolMeOnce.py

บันทึกการเคลื่อนไหวของผู้เล่นแต่ละคนสำหรับการดวลครั้งแรกจากนั้นเล่นซ้ำด้วยการเคลื่อนไหวที่แน่นอน หากอัลกอริทึมของศัตรูไม่ใช่แบบสุ่มเราสามารถทำนายผลลัพธ์เดียวกันและโจมตีเมื่อเรารู้ว่าเราจะชนะเท่านั้น

import os
import sys
import random

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

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

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

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

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

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

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

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

เขียนใน python 3 ดังนั้นคุณจะต้องใช้python3 FoolMeOnce.py ในรอบแรกฉันไม่แน่ใจว่าเราได้รับสตริงว่างหรือเพียงแค่เครื่องหมายจุลภาคดังนั้นอาจมีการปรับแต่งบางอย่างที่จำเป็น


ฉันได้แก้ไขพา ธ ไฟล์ของคุณแล้ว - เปลี่ยนไดเรกทอรีการทำงานปัจจุบันไม่ใช่โปรแกรมของคุณ
Doorknob

ในขณะที่เล่นกับผู้ทดสอบ CavemanDuel ฉันสังเกตเห็นว่า FoolMeOnce ได้คะแนนดีกว่าถ้าฉันใช้เธรดเพิ่มเติม (ฉันทดสอบ 16 เธรดกับ 4) ด้วย 4 เธรดจะได้รับ ~ 25 คะแนนกับ 16 จะได้รับ ~ 34
wendelbsilva

แปลกฉันไม่รู้ว่าทำไมถึงเป็นเช่นนั้น
tzazy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.