원시인 결투 (또는 : 나는 날카로운 막대기로 당신을 찌를)


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: 블록

    막아도 상대가 찌를 때 아무 일도 일어나지 않습니다. 상대방이 찌르지 않으면 블록은 아무것도하지 않습니다.

    블로킹은 칼이 있어도 칼로부터 보호되지 않습니다!

규칙과 제약

추가 규칙은 다음과 같습니다.

  • 데이터를 저장하려는 경우 프로그램이 자체 폴더 에서 파일을 읽고 쓸 수 있습니다 (도둑질하지 마십시오!). 그러나 외부인은 액세스 할 수 없습니다.
    • 파일에 대한 중요한 참고 사항 : 파일을 저장하는 경우 반드시 디렉토리에 저장하십시오 players/YourBotsName/somefile.foo! 프로그램의 현재 작업 디렉토리는 프로그램의 디렉토리가 아닙니다!
  • 원시인은 공정하다 : 한 프로그램은 다른 프로그램에 특정한 코드를 가질 수 없으며, 프로그램은 서로 도울 수 없습니다. (여러 프로그램이있을 수 있지만 어떤 방식 으로든 상호 작용할 수 없습니다.)
  • 원시인 판사는 참을성이 없습니다. 원시인이 승자를 결정하기 위해 각각 100 번 이상을 돌리면 판사는 지루해지고 두 원시인은 모두집니다.

프로그램이 규칙을 어기거나 사양을 따르지 않으면 프로그램은 자격이 박탈되고에서 제거 playerlist.txt되며 모든 결투가 처음부터 다시 시작됩니다. 귀하의 프로그램이 실격되면, 원시인 지도자 (me!)가 귀하의 프로그램 게시물에 댓글을 달고 그 이유를 설명 할 것입니다. 규칙을 어 기지 않으면 프로그램이 리더 보드에 추가됩니다. (귀하의 프로그램이 리더 보드에없는 경우 게시물에 설명이없고 아래 "최종 업데이트"시간 전에 프로그램을 게시 한 경우 원시인 리더에게 알려주십시오! 어쩌면 그는 잊어 버렸습니다.)

게시물에 다음을 포함하십시오.

  • 이름.
  • 쉘 명령은 프로그램 실행 (예를. java MyBot.java, ruby MyBot.rb, python3 MyBot.py, 등).
    • 참고 : 여기에 입력이 명령 행 인수로 추가됩니다.
    • 원시인은 Ubuntu 14.04를 사용하므로 코드가 자유롭게 작동하는지 확인하십시오.
  • 코드가 선택한 언어의 다른 버전에서 다르게 작동하는 경우 버전 번호입니다.
  • 귀하의 코드 (분명히).
  • 필요한 경우 코드를 컴파일하는 방법

컨트롤러 코드 / 테스트, 예제 봇

원시인 리더는 C ++로 제어 코드를 작성하여 Github 저장소에 게시했습니다 . 거기서 프로그램을 실행하고 테스트 할 수 있습니다.

아주, 아주 간단한 프로그램 (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, FacileFibonacci, StudiousSylwester.

최종 업데이트 : 8 월 3 일 00:15 (UTC).


아직 아무도 minimax 전략을 찾지 못했던 것 같습니다. 명백한 일처럼 보입니다.
user2357112

나는 여기에서 minimax가 개선되지 않았다고 생각합니다. 미니 맥스 구현을 설계 할 수는 있지만 논리가 매우 단순하기 때문에 유한 상태 머신으로 동일한 정확한 동작을 표현할 수 있습니다. (즉, 상대가 둔해질 때까지 봇은 날카롭게하지 않습니다. 왜냐하면 상대의 움 직임이 최소화되면 상대방의 움 직임이 찌그러지고지는 것입니다. 봇의 최대 이동은 항상 차단해야합니다.)
HuddleWolf

3
많은 항목이 계산에서 음의 선명도를 허용하는 것으로 보입니다. 쓰여진 규칙에 따르면 선명도를 0으로 찌를 때 아무 일도 일어나지 않습니다. "아무것도"도 선명도가 감소하지 않고 제로를 유지한다는 의미입니까?
Sparr

6
여기에 있어야 합니다. dresdencodak.com/comics/2009-09-22-caveman_science_fiction.jpg 어쩌면 상상력이 나아질 것입니다. :)
Evi1M4chine

2
아직 열려 있습니까? 사람들이 새로운 제출물을 추가하는 것을 보았지만 리더 보드가 업데이트되는 것을 보지 못했습니다.
ASCIIThenANSI

답변:


35

다윈-C

어쨌든 누가 전략이 필요합니까? 한 무리의 원시인이 서로에게 가서 자연 선택이 나머지를 수행하게하십시오!


우리는 원시인의 원시적 인 뇌를 위해 매우 간단한 모델을 사용합니다. 메모리가 없으며 자신과 상대방의 막대기의 선명도 만 고려합니다. 그것들은 유한 한 순서의 이항 다항식에 대한 변수로 사용됩니다. 각 동작 (블록, 선명 화 및 찌르기)에는 관련 다항식이 있으며 결과에 따라이 동작을 선택할 수있는 확률이 결정됩니다. 그것은 임의의 계수로 시작하여 반복적으로 최적화하는 거의 모든 것입니다.

봇 :

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

봇라는 이름의 파일에서 계수를 읽고 programplayers/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봇이 사용할 수있는 파일 을 생성하는 프로그램입니다 ( 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

Watson은 유전자 알고리즘의 산물입니다. 다윈과 달리 이번에는 유전자 데이텀은 작은 도메인 별 언어 (여기서는 파이썬으로 번역)로 작성된 실제 프로그램입니다.


간단한 순서는 큰 선수를 능가합니다

이 작은 녀석은 놀랍게도, 특히 지도자들에 대해 놀랍게도 (또는 아마도 놀랍지 않게) 잘합니다.

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디렉토리의 파일 만 읽고 쓸 수 있습니다 .
손잡이

@ 문 손잡이 : 고정.
DarwinBot

나는 점점 오전 이 컴파일 오류를 이 코드를 컴파일 할 때. (나는 Ubuntu 14.04에 있습니다.)
Doorknob

@Doorknob : 수정되었습니다. 지금 작동해야합니다.
DarwinBot

나는 지금 받고있다 undefined reference to `fmax'. -편집-신경 쓰지 마, 난 정말로 필요했다 -lm.
손잡이

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!

이 원시인은 각 라운드를 무작위로 선택하지만, 특정 행동이 때로는 의미가 없다고 간단하게 설명했습니다. 다른 논리를 표현하려면이 코드를 복사하십시오.

이것은 Ruby입니다. 'unpredictable.rb'로 저장하고 ruby unpredictable.rb


사실, 나는 no 'Block'상대방이 칼을 가지고 있다면해야합니다.
njzk2

첫 번째 no 'Block'은 실제로 그것을 가리 킵니다. 뾰족한 막대기는 칼이 아닙니다.
histocrat

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 나는 그것들을 모두 고쳤다 고 생각한다. 어쨌든 실제 논리에는 단 하나의 변화 만 있었다.
Nexus

20

외국인

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을 가지고 그렇습니다 얼마나 나쁜
케빈 L

19

부사장

Doorknob ♦ 는 리더입니다. 나는 지도자가되고 싶다! 슈퍼 지능형 프로그램에 따라 지도자가 되십시오!

컴파일 : javac ViceLeader.java실행 : java ViceLeader.

public class ViceLeader {

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

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

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

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

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

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

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

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

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

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

왜 이런 일이 아닌 if (enemySharpness <= 4 || mySharpness >= 5)==?
durron597

@ durron597 다음 차례에 칼을 만들 수 있다면 적을 찌르고 싶기 때문입니다. VizeLeader는 자주 찌르지 않고 적시에 수행합니다 .
CommonGuy

그러나 당신은 칼을 가지고 상대는하지 않습니다 ...
durron597

@ durron597 아니요, OR 문입니다. 그것은 "나에게 칼이 있거나 곧 칼을 가지면 상대방을 찌르는 것"을 의미합니다.
CommonGuy

7
오 신 이시여. 커피 한 잔 더 마시기 :) 또는 새로운 콘택트 렌즈
durron597

15

아마 Markov 2.1

다른 원시인이 할 일을 예측하기 위해 Markov Chains를 사용한다고 생각하지만 Markov Chains에 대한 Wikipedia 페이지를 간단히 보았고 너무 많은 텍스트가 있다고 결정했습니다.

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

정기적 인 매미 인

이 똑똑한 동굴 사람은 특정 버그 를 연구했으며 아무도 소수의 Cicada를 이용하기 위해 자신의 라이프 스타일을 조정할 수 없다는 것을 깨달았습니다.

그것은 인생의 대부분을 숨기거나 차단하지만 때로는 찌르기 만합니다. 확실히 칼에 취약하고 날카롭지 않은 막대기로 전체주기를 소비하지만 완전히 무딘 경우 지팡이를 날카롭게합니까? 그게 다른 사람들이 기대하는 것입니다 ...이 매미가 아닙니다.

컴파일하는 방법 : 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"); 

  }

}

편집 : 선명도 변경-코드 ... 내가 찌르거나 내 막대기가 흐려지면

Edit2 : Bobs 제안에 추가됨

편집 : 선명도가 2 일 때 찌르기로 변경되었습니다. 스틱이 0에 도달하면 다른 사람이 칼을 만들 수 있습니다.


1
우분투에서 뛰고 있습니다. 모노로 컴파일됩니까? 그렇다면 어떻게 컴파일하고 어떻게 실행합니까?
손잡이

솔직히 모르겠다. 그냥 침대로 향하려고합니다. 내일 아침 직장에서 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

팬시 테크노 알고리즘

멋진 테크노 컴퓨터 프로그램을위한 멋진 테크노 알고리즘.

원시인은 계속 전투에서 패배합니다. 원시인 화가. 원시인은 컴퓨터 학교에 가서 알고리즘을 배우십시오.

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"

파이썬 2 프로그램. 실행하려면python fancytechnoalgorithm.py


입력이 없으면 (즉, 첫 번째 턴에서) 중단됩니다. 처리 방법을 모르겠 기 때문에 첫 번째 테스트에서 제외해야합니다.
손잡이

@Doorknob 첫 번째 입력의 경우 ","또는 ""입니까? 나는 그것이 후자의 것 같아요.
벡터화

첫 번째 입력의 경우 인수가 없습니다 (로 실행 됨 python StickSharpener.py).
Doorknob

@Doorknob 편집했습니다. 지금 작동하는지 확인하십시오.
벡터화

알았어, 고마워! 다음 시험에서는이 내용을 포함하겠습니다.
손잡이

14

감시자

그는 상대의 움직임을 지켜보고 공격하기 전에 항상 손을 보여줍니다. 그는 칼을 향해 일하는 것을 소홀히하는 사람들을 위해 특별히 준비되어 있습니다.

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

바실리스크

그를 면밀히 바라 보는 사람들을 멸하려한다. 일관되게 감시자를이기는 것이지만 아마도 전반적으로 더 나빠질 것입니다.

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

이것은 내쉬 균형이 아니지만 (전략 생성기는 약간의 불안정성이 있음), 가깝습니다.

호기심을 위해 각 게임 상태에서이 봇이 이길 가능성에 대한 추정치는 다음과 같습니다.

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

이 제출은 어느 시점에서 일종의 오류나 예외를 던졌습니다. 다음 시험 시행 전에이를 수정하는 것이 좋습니다. (바실리스크 하나)
손잡이

@Doorknob 나는 파수꾼과 동굴 의사가 만든 가정을보고 바실리스크의 시작 순서를 선택했으며 이러한 가정이 잘못 될 수있는 순서를 찾았습니다. 이것이 "동굴 공평"규칙을 위반합니까?
Brilliand

내쉬! P = 0 옵션을 피할 수있을만큼 똑똑하게 모든 봇에 대해 정확히 절반의 경기에서 승리하십시오!
aschepler

12

PokeBot

루비로 작성되었습니다.

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에, 두 번째 인수를 $ him에 할당합니다
killmous

CavemanDuel 프로그램은 하나의 인수 만 사용합니다. 예. perl patientwolf.pl "SB,SP". 당신은해야 my($me,$him) = split/,/ $ARGV[0];하고 if( @ARGV ) {print "S";exit}.
Sylwester

@Sylwester ok 네가 얻는 것을 봅니다. 그것은 OP 또는 컨트롤러 코드에 던져진 빠른 눈에서 명확하지 않았습니다. 나는 그것을 곧 고칠 것이다
killmous

9

이진 원시인

선명하게, 찌르기, 반복

이 원시인은 sissies에 대한 차단이라는 아이디어를 바탕으로 나머지 두 가지 옵션을 번갈아 사용합니다.

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

편집 : 문자열 배열의 모험 ..... args.length () 오류가 발생합니다. args.length는 항상 1을 반환합니다. args [0] .length ()는 배열에서 첫 번째 문자열의 길이를 반환합니다.

편집 2 : Doorknob, Brilliand 및 Sylwester의 도움으로 업데이트되었습니다. 고마워


@ MartinBüttner 나는 args를 1에서 2로 나누는 것을 잊어 버렸습니다. 단일 플레이어의 과거 제출 횟수 만 가져옵니다. 고쳤다. Dorknob의 제출 내용을 이해할 수 없습니다. 루비는 실제로 저에게 횡설수설입니다. 그는 항상 선명하게 시작합니까?
Red_Shadow

예, 그는 단지 그의 마지막 움직임인지 P또는 S반대 인지 확인합니다 . 그리고 아직 역사가 없다면, 그는 역사가 가장 한 것으로 가장합니다 P,(그러면 S먼저 그를하게됩니다 ).
Martin Ender

동일한 결과를 도출하는 두 가지 접근 방식. 규칙에 어긋나는가?
Red_Shadow

아마 아니에요, 난 당신에게 알려줄 것입니다.
마틴 엔더

2
@Doorknob 나는 그것이해야한다고 생각 args[0].length()하지 args.length.
Brilliand

8

동굴

울고 겁 먹은 동굴 아이는 쉬운 먹이처럼 보일 수 있습니다. 그가 막는 방법을 알고 있기 때문에 그의 예쁜 얼굴이 당신을 속이게하지 마십시오.

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

충전기 맨

이 원시인은 매우 보수적입니다. 무기를 충전하려고 시도하고 필요할 때만 공격합니다.

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

사기꾼

Trickster는 싸울 방법을 모르므로 다른 원시인을 혼란스럽게하려고합니다.

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

호도르

냄새는 그리 공격적이지 않습니다. 그는 파업 할 좋은 기회가 없다면 방패에 머무르기를 좋아합니다.

로 컴파일하고 다음 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);
    }
}

편집 : 사소한 코드 업데이트


이 제출은 어느 시점에서 일종의 오류나 예외를 던졌습니다. 다음 시험 시행 전에이를 수정하는 것이 좋습니다.
도어 손잡이

1
함께 시도 SB,BB . 첫 번째 차례에 다른 원시인이 잘못 행동 할 때 Hodor도 잘못 행동합니다.
Sylwester

7

투기성 강모-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;
}

리눅스에서 실행하려면 playerlist.txt에 다음을 추가하십시오.

perl players/SpeculativeSylwester/SpeculativeSylwester.pl

Facile Fibonacci-R6RS 체계

턴이 시작될 때 첫 번째 이동 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)))

실행하려면 이카루스를 설치하십시오. apt-get install ikarus 추가 :

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

Studious Sylwester-Perl5

Studious Sylwester는 Speculative 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;
}

리눅스에서 실행하려면 playerlist.txt에 추가하십시오.

perl players/StudiousSylwester/StudiousSylwester.pl

원근법 편집

$0펄로 실행될 때 펄 스크립트의 전체 경로 가 아닌 문제를 재현 할 수 없습니다 . 또한 변경 사항을 가져 왔으며 CavemanDuels src에서 변경 사항이 표시되지 않으며보고 한 문제없이 20 번 이상 실행 한 것과 동일합니다. 실행 중이거나 perl에 대한 인수로 스크립트를 실행하지 않고 bash 스크립트로 소스를 제공했을 수도 있습니다. 실제로 확실히 알기 위해서는 더 많은 정보가 필요합니다. 테스트로 나는 이것을했고 당신은 같은 결과를 얻는 지 확인하기 위해 똑같이 할 수 있습니다.

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

Scheme은 내 컴퓨터에서 나와 협력하고 싶지 않아서 피보나치 테스트를 할 수 없었습니다. 계속 작동 시키려고 노력하지만 다른 언어로 번역 할 수 있다면 좋을 것입니다.
Doorknob

스튜디오 하나도 작동하지 않는 것 같습니다. $0 입니다 bash떠들썩한 파티 명령 행 (컨트롤러가 수행하는)에서 호출 할 때. players/StudiousSylwester/foo.txt그래도 하드 코딩 할 수 있습니다 .
Doorknob

@Doorknob 설치 방법을 추가했으며 Studious ikarus$0대한 생각을 추가했습니다 .
Sylwester

6

도공

날카로운 스틱이 필요합니다. 날카로운 스틱이 있으면 찌르십시오. 나는 고통을 느끼지 않는다.

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 : 코드를 업데이트했습니다. 출력은 단일 문자이며, 처음 실행할 때 이미 존재하는 파일을 삭제하며 파일은 플레이어 디렉토리에 있습니다.
Kyle Kanos

알았어, 고마워! 이 제출물은 이제 리더 보드에 포함됩니다.
손잡이

@Doorknob : 쿨! 내가 처음이 아냐 또한 : Fortran 사용자는 뱀파이어와 비슷하다고 확신하므로 곧 포트란에서 코딩을 시작할 것입니다. Muahahahaha!
Kyle Kanos

5

환자 대장장이

이 봇은 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

원시인은 원시인과 다른 원시인이 이야기하고 막대기를 공유해야한다고 생각합니다. 그러나 이봐, 싸워야한다면, 감옥 규칙에 맞서 싸워 보스와 공격을 찾으십시오.

부통령 알파 원시인; 원시인은 반드시 싸워야합니다. 다른 원시인들은 나중에 싸운다. 내 원시인이 패배하더라도 걱정하지 마십시오. 그는 어쨌든 너무 털이 있습니다.

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 (기능 프로그래밍)로 작성 했으므로 prisonrules.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

"Caveman"은 리더 보드에 들어가기에는 너무 일반적이기 때문에 이름을 JavaMan으로 변경했습니다. 잘만되면 그것은 당신에게 괜찮습니다; 그렇지 않은 경우 다른 것으로 변경하십시오.
손잡이

1
이것은 입력이 없을 때 (즉, 첫 번째 턴에서) 중단됩니다. 처리 방법을 모르겠으므로 첫 번째 테스트에서 제외해야합니다.
손잡이

고정, 그리고 이름 변경 나와 함께
user2813274

1
나는 당신이 국가를 파싱하는 데 실수가 있다고 생각합니다. '나'와 '적'은 같은 움직임을 얻습니다. states [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
원시인 var 이름과 설명에 +1 : P 또한, 좋은 프로그램 c :
cat

3

나이젤

Nigel은 공격에 나가는 것보다 오히려 전술적 인 환자이며 방어적인 오래된 원시인입니다.

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

아이 코포 빅-루아

그는 때때로 당신을 찌를 것입니다. 그러나 일부 막대기가 너무 날카 로워 질 때까지 만요. 이런 일이 발생하면, 그는 당황하고 태아의 위치로 컬됩니다.

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
출력물은 대문자 여야합니다. 나는 당신을 위해 그것을 고쳤습니다. (또한, 나는이 제출의 이름을 천 번 정도
틀렸다

3

밥 동굴

밥 동굴은 동굴에서 가장 영리한 사람 중 하나입니다. 그는 한 손으로 계산하는 법을 배웠습니다 (다른 손은 막대기를 쥐고 있습니다). 그는이 석기 시대 올림픽을 알고 참가하고 싶었습니다.

그의 주요 전략은 차단이 잘되고, 예리한 막대기가 있거나 다른 원시인도 예리한 막대기가 될 때까지 막대기를 갈아줍니다. 이 경우 밥 동굴은 그를 찌르려고합니다!

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

편집 : 이제 블록이있을 때 밥이 계산됩니다! ( 마이키 마우스 덕분에 ). 또한 다른 원시인 지팡이가 무딘 경우 지팡이를 날카롭게 할 것입니다.

편집 2 : 카운트 방법 개선 (Mikey에게 다시 감사드립니다).

편집 3 : 밥을 좀 더 공격적으로 만듭니다.


2
밥은 자신의 스틱 선명도에 대한 Poke : Block의 카운트 효과를 잊습니다. 3 개의 "S"는 평균 스틱이 3 배 선명하지 않습니다. 의 "P"는 날카롭지 않은 스틱을 의미합니다. Huh huh huh ... "오줌"동굴 사람 농담 ...
Mikey Mouse

@MikeyMouse Bob이 동의합니다. 밥은 자신의 기술을 향상시키기 위해 마녀 의사를 방문합니다. 밥 감사합니다!
Averroes

1
마녀 의사가 밥을 잘 가르칩니다. 그러나 그는 Poke : Poke 시나리오를 언급하는 것을 잊었습니다. 스틱도 무뎌집니다. 밥은 상대 이동을 고려할 필요가 없습니다. Bob Poke 인 경우 스틱이 무뎌집니다. 무딘 공격 : 상대 찌르기, 상대 블록 또는 상대 머리. 상대방의 머리에 밥이 이기고 무딘 스틱으로 동굴 주위에서 춤을 출 수 있습니다.
Mikey Mouse

1
@MikeyMouse Bob은 계산 방법을 알고 있습니다. 밥은 읽는 법을 배워야합니다. 다시 감사합니다!
Averroes

3

그 룬트

그룬 트는 방어 적입니다. 그룬 트는 다른 원시인의 움직임을 분석하여 찌르는 방법을 알고 있습니다. 그런 다음 그는 바로 눈을 찌릅니다. 그룬 트는 멋진 원시인이 아닙니다.

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 Ops! 고마워요!
Averroes

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

시칠리아

그러나 너무 간단합니다! 내가해야 할 일은 내가 다른 원시인에 대해 아는 신성입니다. 그는 막거나 날카롭게하거나 찌르는 일종의 원시인입니까? 이제 영리한 원시인이 찌르거나 막을 것입니다. 왜냐하면 그는 위대한 바보만이 날카롭게하고 공격에 노출 될 것임을 알기 때문입니다. 나는 큰 바보가 아니므로 선명하게 할 수 없습니다. 그러나 다른 원시인은 내가 큰 바보가 아니라는 것을 알고 있어야하므로 그것을 찌르거나 막을 수 없습니다!

로 실행 :

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

bash-magnon

Bash-magnon은 견고하고 강력합니다. 몸은 일반적으로 근육이 강하고 무겁습니다. 이마는 네안데르탈 인처럼 경 사진 것보다는 상당히 똑 바르고 약간의 눈썹 만있었습니다. 얼굴은 짧고 넓었습니다. 턱이 두드러졌다. 뇌의 용량은 약 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+ 당신은 분명히 직업에 맞는 도구를 가지고 있으며 당신의 원시인 이름은 꽤 재미 있습니다 :) (나는 개인적으로 물고기를 좋아하지만)
Sylwester

@Sylwester 첫 번째 +1 감사합니다. 나는 첫 번째 사이버네틱스가 자신의 균형을 느끼는 것에 영감을 받아 항상성 오토마타를 만들려고 시도한 다음, bash 스크립트를 포기하고 만들었습니다.
Emmanuel

2

PokeBackBot

PokeBot에서 간단히 적용 :

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

로 실행 ruby pokebackbot.rb.

다음으로 가장 간단한 전략을 사용하고 공격하기 전에 한 라운드 동안 "환자"를 차단합니다.


3
@PeterTaylor 상대방의 지문을 기반으로 내 전략을 바꿀 수 없다는 것을 읽었습니다. 내 제출물이 다른 제출물 하나만 이길 수 있다면 다른 제출물 점수에 영향을 미치지 않으며 내 제출물은 아마도 매우 나쁠 것입니다. 또한 하나의 제출물 만 있고 두 번째 제출물이 작성된 경우 두 번째 제출물이 첫 번째 제출물을 능가 할 가능성이 있습니다 (그렇지 않으면 왜 귀찮게합니까). 내 봇은 SPS(합리적으로 보이는) 것으로 시작하는 모든 봇을 이길 것이지만 지금까지 PokeBot이 유일한 주변이었습니다.
마틴 엔더

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)

파이썬 3으로 작성되었으므로 대부분 python3 FoolMeOnce.py 를 사용해야 할 것입니다 . 첫 번째 라운드에서 빈 문자열이나 쉼표가 있는지 확실하지 않으므로 약간의 조정이 필요할 수 있습니다.


파일 경로를 수정했습니다. 현재 작업 디렉토리가 프로그램이 아닙니다.
손잡이

CavemanDuel 테스터를 가지고 놀면서 더 많은 스레드를 사용하면 FoolMeOnce가 더 나은 점수를 얻는다는 것을 알았습니다 (4에 대해 16 스레드를 테스트했습니다). 4 개의 스레드를 사용하면 ~ 25 포인트가, 16 개는 ~ 34가됩니다.
wendelbsilva

이상하게도 나는 왜 그런지 모른다.
tzazy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.