Конечная битва самураев


37

Обратите внимание: это испытание завершено. Это означает, что зеленая галочка, которая была присуждена C5H8NNaO4 за их запись Наблюдатель, не будет перемещена в новый ответ.

Вы по-прежнему можете отправлять новые записи, но могут быть задержки в новых турнирах, поскольку я больше не проверяю новые записи.

Введение

В этом испытании вы играете в аркадную игру под названием The Ultimate Samurai Showdown Ultimate Edition, специальная версия 2.0 X Alpha Omega Turbo (или просто Ultimate Samurai Showdown для краткости). Ваши оппоненты? Никто иной, как другие участники Programming Puzzles & Code Golf!

Как и следовало ожидать от аркадной игры PPCG, вы не играете в Ultimate Samurai Showdown напрямую, а скорее пишете программу, которая будет играть в эту игру для вас. Эта программа будет бороться с программами, представленными другими пользователями в поединках один на один. Самая опытная программа будет увенчана Ultimate Samurai of PPCG и получит зеленую галочку легенды.

Описание игры

В этом разделе описана механика игры.

Условие Победы

Матч состоит из двух самураев , которые сталкиваются друг против друга. Каждый самурай начинает каждый матч с 20 хитами и 1 честью . Самурай побеждает, если его противник мертв, а он все еще жив. Есть два способа, которыми самурай может умереть:

  1. Если хиты самурая будут снижены до 0, он умрет.
  2. Если самурай принесет свою честь ниже 0, он будет сбит богами за нечестную игру в поединке.

Уничтожение богов имеет более высокий приоритет по сравнению с уменьшением очков жизни до 0, поэтому в ситуации, когда один самурай имеет 0 очков здоровья, а другой - -1 честь, самурай с 0 очками здоровья выиграет. В ситуации, когда оба самурая имеют честь -1, они оба поражены богами, и игра становится ничьей.

Матч состоит из 500 ходов . Если все 500 ходов пройдены и матч не решен (ни один самурай не умер), богам становится скучно, и они сбивают обоих самураев, что приводит к ничьей.

действия

На каждом ходу самурай должен выполнять ровно одно из следующих действий:

W

Самурай должен ждать и не предпринимать никаких действий. Это заставляет его выглядеть круто, но не помогает ему победить своего противника. Это также действие по умолчанию.

B

Самурай должен почтительно поклониться своему противнику. Это радует богов и, таким образом, самурай получит 1 Честь. Честь жизненно важна для успеха вашего самурая, потому что Честь, по сути, является «ресурсом» для этой игры - все движется отдельно Bи Wможет уменьшить Честь. Кроме того, если самурай получает 7 или более Чести, ему предоставляется право использовать Меч Богов . Последствия этого описаны ниже.
Однако, кланяясь своему противнику, вы остаетесь открытым, если ваш противник решает ударить вас своим мечом, поэтому будьте осторожны, когда решите поклониться.

G

Самурай должен войти в оборонительную позицию и защищаться от любых ударов мечом. Этот ход успешно заблокирует все удары мечом, даже те, что были сделаны с помощью Меча Богов .
Тем не менее, боги недовольны чрезмерно оборонительными самураями, поэтому этот ход потребует 1 Чести, если действия самурая в непосредственно предшествующем ходу также охраняли. Иначе Хонор не потребляет.

I

Самурай должен попытаться ударить своего противника быстрым извлечением своего меча из ножен. Если у самурая 7 очков чести или больше, он использует Меч Богов вместо своего обычного меча. Этот ход потребляет 1 Чести.
Быстрая ничья - это быстрый удар, который побьет медленные атаки сверху, однако он проиграет против парирования. Если удар успешен, он нанесет 1 урон или 2 урона Мечом Богов .

P

Самурай должен попытаться парировать любую входящую атаку, а затем начать собственную атаку. Если у самурая 7 очков чести или больше, он использует Меч Богов вместо своего обычного меча. Этот ход потребляет 1 Чести.
Парирование - хороший маневр против быстрых ударов, но оно будет подавлено медленными атаками сверху. Если удар успешен, он нанесет 1 урон или 2 урона Мечом Богов .

O

Самурай должен попытаться нанести удар по противнику с более медленной атакой сверху. Если у самурая 7 Чести или выше, он использует Меч Богов вместо своего обычного меча. Этот ход потребляет 1 честь.
Удар сверху может подавить парирование, но он проиграет от быстрых ударов. Если удар успешен, он нанесет 1 урон или 2 урона Мечом Богов .

Меч богов

Самурай с Честностью 7 или более получает способность использовать Меч Богов . Если его Честь будет ниже 7, способность использовать Меч богов будет отозвана у него. Меч Богов наносит 2 повреждения вместо 1.

Меч Богов не позволяет удар победить мечом удар , что он не будет обычно поражение. Например, парирование Меча Богов все равно проиграет при обычном верхнем ударе, а быстрое ничье Меча Богов не одолеет обычное быстрое ничье. На самом деле, так называемый Меч Богов на самом деле не настолько силен - возможно, это космическая шутка, которую играют боги ...

Таблица взаимодействия

Приведенный ниже фрагмент стека содержит таблицу, в которой явно перечислены все возможные результаты различных комбинаций действий, которые могут выполнять два самурая. Чтобы просмотреть его, нажмите «Показать фрагмент кода», затем нажмите «Запустить фрагмент кода».

Программа связи

Чтобы облегчить проведение турнира, была написана программа контроллера, которая сыграет роль «богов» - она ​​хранит записи о чести и здоровье и, соответственно, поражает самураев. В этом разделе описывается, как ваша программа будет взаимодействовать с программой контроллера.

Описание входа

Программа контроллера будет вызывать вашу программу из командной строки следующим образом:

<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>

где:

  • <command>это команда, необходимая для запуска вашей программы. Например, если ваша программа находится в файле super_sentai.pl, команда, вероятно perl super_sentai.pl.

  • <history>это история ходов, которые вы сделали. Например, это WWBPбудет означать , что вы дважды подождали, один раз поклонились и один раз парировали.

  • <enemy_history>история ходов вашего врага. Например, BBBIэто означает , что ваш враг трижды поклонился и выполнил одну быструю ничью.

  • <your_health> ваше текущее здоровье.

  • <enemy_health> это текущее здоровье врага.
  • <your_honour> ваша нынешняя честь
  • <enemy_honour> это настоящая честь врага.

Для первого хода, historyи enemy_historyбудет пустым, поэтому ваша программа будет вызываться только с последними четырьмя аргументами, подобными этим:

<command> <your_health> <enemy_health> <your_honour> <enemy_honour>

Пожалуйста, будьте готовы к этому!

Проницательные читатели могут заметить, что четыре аргумента, обеспечивающие честь и здоровье обоих самураев, в некоторой степени излишни; Поскольку это идеальная информационная игра, честь и здоровье самурая можно определить, используя только историю.

Эти значения предоставлены для удобства, чтобы вам не приходилось анализировать аргументы истории. Это должно оказаться полезным для реализации простых стратегий, например, не атаковать, когда ваша Честь равна 0.

Описание выхода

Чтобы выбрать действие, ваша программа должна вывести один из W, B, G, I, P, или Oна стандартный вывод, в зависимости от того, какие действия вы хотите сделать. Если ваша программа ничего не выводит в течение 1000 мс, она будет прервана, и ваша программа будет обрабатываться так, как если бы она выводила W.

Если ваша программа выводит более одной буквы, будет рассматриваться только первая буква, поэтому вывод Parryбудет таким же, как и вывод P.

Если вывод первой буквы вашей программы не соответствует ни одному из перечисленных выше параметров, по умолчанию он будет иметь значение W.

Формат представления

Отправить программу в качестве ответа на этот пост. Вы можете подать несколько программ. Если вы отправляете несколько простых программ, я рекомендую отправлять их как один ответ; если вы отправляете несколько сложных программ, я рекомендую отправлять их как отдельные ответы. Как только я успешно добавлю вашу программу / программы в турнир, я сделаю коммит в репозиторий git с вашей записью (ссылка ниже).

Если у меня возникнут проблемы, из-за которых ваша программа не будет добавлена ​​в турнир, я оставлю комментарий к вашей записи с указанием проблемы.

Пожалуйста, включите следующее в ваше представление:

  1. Удобное для чтения имя вашей программы для использования в табло. Здесь разрешены пробелы; Запятые и символы Юникода не являются.
  2. Язык, на котором написана ваша программа. Пожалуйста, не пишите на странных, труднодоступных языках, таких как TinyMUSH.
  3. Краткий обзор вашей программы. Это может быть описание того, как работает программа, или просто небольшой текст о вашей программе (если вы хотите быть полностью скрытным), или, возможно, и то, и другое.
  4. Команда / ы, необходимые для запуска вашей программы. Например, если вы пишете свою заявку на Java example.java, вы должны предоставить инструкции по компиляции, а javac example.javaзатем выполнить инструкции java example.
  5. Исходный код программы.

Чтобы помочь в отправке, я предоставляю шаблон отправки, который можно найти здесь . Шаблон заставляет представления выглядеть лучше. Я настоятельно рекомендую использовать его.

Я также приведу два примера записей. Несмотря на то, что примеры заявок будут участвовать в круговом турнире, их основная цель - уточнить форматы подачи и ввода / вывода для турнира, а не быть серьезными претендентами на звание Ultimate Samurai.

Структура турнира

В этом разделе описывается, как будет проходить турнир между участниками.

Программа управления

Управляющая программа написана на Python 2 и может быть найдена в репозитории Ultimate Samurai Showdown Github . Если вы хотите запустить его самостоятельно, инструкции по его запуску включены в файл README.md по ссылке. Однако только турниры, проводимые на моем компьютере, будут официальными, чтобы избежать различий в оборудовании, влияющих на результаты турниров.

Управляющая программа будет работать на ноутбуке под управлением Arch Linux. Он имеет процессор Intel Core i7 и 8 ГБ оперативной памяти. Я постараюсь, чтобы все записи работали на моем компьютере, но я был бы очень признателен, если бы вы избегали языков, к которым нет свободного доступа (как без денежных затрат).

Система баллов

Система начисления очков - круговой. Каждая программа сыграет восемь матчей против любой другой программы. Победа дает программе 1 очко, проигрыш без очков и ничью 0,5 очка. Программа с наибольшим количеством очков побеждает в игре. Если будет ничья, я буду дуэли двух лучших программ друг с другом, чтобы определить победителя.

Количество раз, когда каждая программа будет воспроизводить другую, может быть уменьшено с 8, если количество участников слишком велико. Я добавлю заметку здесь, если это произойдет.

Я буду запускать циклический перебор много раз, так как новые публикации публикуются, но это будет только самый последний циклический перебор.

Дисквалификация

Ваша программа может быть дисквалифицирована из турнира. Дисквалификация может произойти, если:

  • Ваша программа не компилируется и не запускается;
  • Ваша программа является стратегическим дубликатом другой программы (то есть реализует ту же стратегию, что и другая программа);
  • Ваша программа пытается саботировать другие программы, изменяя код контроллера, код другой программы и т. Д .;
  • Ваша программа пытается использовать ошибку в коде контроллера. Вместо того, чтобы использовать ошибки, вы должны вместо этого открыть проблему в репозитории git, оставить комментарий здесь или пинговать меня в чате.

Прошлые результаты

Подробные результаты всех турниров доступны на вики-странице .

Самый последний турнир был завершен 2015-07-17 07:20. Вот краткое изложение результатов:

The Observer: 209.0
Coward: 203.0
Monk: 173.0
Elephant Warrior: 157.0
Iniqy: 157.0
Agent 38: 144.0
Ninja: 138.0
Meiyo Senshi: 138.0
Kakashi: 136.0
Yoshimitsu: 131.0
Hermurai: 121.0
Warrior Princess: 120.0
Gargoyle: 119.5
The Honourable: 119.0
Hebi: 118.5
Predictor: 116.0
Whack-a-mole: 107.0
The Fool: 106.0
The Prophet: 105.0
Copy-san: 97.0
YAGMCSE: 80.0
The Waiter: 66.0
Swordsman: 43.0
Spork Holder: 32.5
Blessed Samurai: 27.5
Attacker: 27.0
The Terminator: 17.0
Master Yi: 16.0

1
Официант чувствует себя на удивление хорошо. Должно быть, выигрывает у Spork Holder, когда у него кончается честь.
StephenTG

Это аккуратный вызов. Вы явно вложили в это много мыслей и работы, и я думаю, что это определенно принесло свои плоды. Отличная работа. :)
Алекс А.

1
@ C5H8NNaO4 Да, я проверю наличие обновлений для ботов, прежде чем запустить следующий турнир.
Абсент

1
Обратите внимание: мой ноутбук недавно сломался. Таким образом, у меня нет текущего способа запустить турнир в ближайшее время. Будут задерживаться запуск следующего турнира, поскольку я пытаюсь найти компьютер, который смог бы использовать.
абсент

1
@ Леви Да! Производитель отправил мне замену, которая прибыла сегодня. Пока мы говорим, проходит турнир.
абсент

Ответы:


8

Монах (Ява)

Монах ценит честь и хвалит благословения богов. Будучи обученным терпению, он спокойно отправляет свои молитвы на небеса, пока не почувствует благосклонность Бога.

Наслаждаясь своей жизнью, он пытается защитить ее. Когда он теряет здоровье по определенной норме, он защищает себя как можно лучше.

В надежде на поддержку своих богов он случайным образом посылает семяизвержение [1] на небеса, в противном случае он борется как можно лучше.

Если его противник измотан из битвы, он заканчивает его, используя оставшуюся честь, чтобы дать ему быструю и безболезненную смерть.

Compile / Run

javac Monk.java
java Monk

public class Monk {
    public static void main(String[] args){
        char  r = 'B';
        double  s = Math.random ();
        int n = Math.max (args [0].length ()- 8, 1);
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int l = Integer.parseInt (args [3]);
        int m = Integer.parseInt (args [2]);
        double d = 1 + (20 - m) / n;
        double e = 1 + (20 - l) / n;

        if (((p>8&&s<.7)||l<11||m<2)&&p>0) {
                r=(s<(.14)||d>=2||e/d<.618)?'G':"OPI".charAt((int)(Math.random()*3));
        }

        System.out.print (r);
    }
}

Ниндзя (Ява)

Ниндзя быстр и атакует еще быстрее. Он нападает сразу же после дружеского официального приветствия, еще больше сбивая с толку своего врага, кланяясь до и после каждой атаки.

Будучи благословенным, ниндзя продолжает это поведение, ожидая, когда его противник сделает свой первый ход (ы). Используя эту возможность, он выпускает серию взрывов, благословленных Богиней ниндзя, пока он не слишком измотан в битве. Используя свою оставшуюся честь, он прячется под листьями внизу, защищая себя от следующей атаки. Он выпрыгивает и нападает на своего врага сзади, прячась так же быстро.

Если он получает смертельную рану, он делает все возможное, чтобы взять с собой в живых своего противника - конечно, соблюдая минимум чести.

javac Ninja.java
java Ninja

public class Ninja {
    public static void main(String[] args){
        char  r = 'B';
        int n = args [0].length ();
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int m = Integer.parseInt (args [2]);
        int a = n % 3;
        if (p>7) {
           if (m>17) {
                r = "BBI".charAt (a);
           } else if (m>13) {
                r = "BII".charAt (a); 
           } else {
               r  = "GIG".charAt (a);
           }

        } else if (p>0) {
           if (m > 10) {
                    r = "BBI".charAt (a);
           } else {
                r="IGI".charAt (n%2);
           }
        }
        System.out.print (r);
    }
}

Какаши, Подражатель ниндзя (Java)

Какаши копирует движения своих оппонентов, случайным образом выбирая между двумя последними ходами оппонента. Если противник ждет, он кланяется - он также сохраняет свою честь.

javac Kakashi.java
java Kakashi

public class Kakashi {
    public static void main(String[] args){
        char  r;
        String h = args [1];
        if (h=="W" || Integer.parseInt ( args.length > 4?args [4]:"0") < 1){
                 r = 'B';
        } else if (Math.random ()<.1) {
            r = 'I';
        } else {
            r  = h.charAt ((int) (h.length()==1?0: h.length()-Math.random ()*2));
        }

        System.out.print (r);
    }
}


Я бы хотел, чтобы Какаши был благословлен шаринганом ... Я подумал о том, чтобы прочитать cast.txt. Имитируйте каждый раунд своей истории против каждого противника там. Попытайтесь выяснить, против какого противника он сражается, сравнив историю смоделированных врагов с историей реальных врагов. Затем используйте эту информацию, чтобы предсказать следующий ход противника и выбрать лучшую противодействие из заранее определенного списка. Но я чувствую, что это может занять немного времени, так как у меня сейчас очень медленный интернет и нет навыков работы с Java

Наблюдатель, (node.js)

Наблюдатель кланяется, прежде чем попытаться предсказать следующий ход противника из его последних 5 ходов, выбирая лучшего аналога для предсказанного хода.

Редактировать: Спасибо @apsillers за совместное использование шаблона node.js !.

node observer.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var m = {
    m:{},
    l:function (a,b) {
        if (!this.m[a]) {
           this.m [a] = [];
        }
        this.m[a].push (b);
    },
    p:function (a) {
       for (var k=0;k<a.length;k++)
       for (var j=1;j<a.length;j++)
       for (var i=-1+k; i<a.length-j; i++)this.l (a.slice (i,i+j),a[i+j]);
    },
    a:function (a) {
      if (!this.m[a])return;
      return this.m[a][0|Math.random () * this.m[a].length-1]
    }
}
var g={
   B:"IPO",
   G:"B",
   I:"PG",
   O:"IG",
   P:"OG",
   W:"I"
}
var c,i=0;
m.p(enemy.history);
while (!c && i++<enemy.history.length) {
   c=m.a (enemy.history.slice (i));
}
decide.apply  (0,my.honor < 7?["B"]:g[c].split (''))

Редактировать: у меня был большой недостаток в наблюдателе, я на самом деле не знаю, что я думал вчера вечером. Кажется, он только посмотрел на последние два хода врага. Он удивительно хорошо, как это.

Его память теперь запрашивается для самой длинной (конечной) части истории врагов, которую он уже видел. Он содержит массив со всеми ходами, которые следовали за историей ходов. Один выбран случайным образом. Так что, если один ход следует чаще, он также с большей вероятностью будет выбран. Вроде как цепочки марковские.

Наблюдатель, теперь тоже охранник.


[1]: TIL: эякуляция имеет религиозное значение


Ты № 1 и № 3 прямо сейчас! Хорошие боты! :)
Апсиллеры

Поздравляем с победой с The Observer. Зеленая галочка теперь твоя: D
абсент

7

Мейо Сенши (Ява)

Родом из района Хайдзима, мало что известно о Мейо. Обычно они не участвуют в спортивных играх, но отправили туда воина, чтобы оценить своих соперников.

Тем не менее, они достойная группа, так что вы можете быть уверены, что он вскоре сообщит о своем присутствии богам. Как только он увидит достаточно своего противника, чтобы сообщить, он будет использовать полученные благословения, чтобы ударить своего противника.

Чтобы скомпилировать прогон, это стандартный способ Java:

> javac MeiyoSenshi.java
> java MeiyoSenshi
public class MeiyoSenshi {
    public static void main(String[] args){
        System.out.print(
                Integer.valueOf(args[args.length<5?0:2])>12 ||
                Integer.valueOf(args[args.length<5?2:4])<1  ?
                "B":
                "IPO".charAt((int)(Math.random()*3))
        );
    }
}

7

Spork Holder (Рубин)

Spork Holder кланяется в первый ход, а затем действует случайным образом. Это один из двух примеров записей.

Команда: ruby spork-holder.rb

if ARGV.length == 4
    print "B"
else
    print ["W", "B", "G", "I", "P", "O"].sample
end

Официант (Баш)

Официант ждет только на каждом шагу. Это один из двух примеров записей.

Команда: echo W

Там не требуется исходный код.


7

Трус (Node.js)

Я трус / Это чудо, что я смею дышать
Сильнейший / Самым нежным летним ветерком

  • Проверки BXBXBX/ BBBшаблонов кланяться (или ударить вас) , когда вы кланяясь.
  • Проверяет GXGXGXшаблоны, чтобы поклониться, когда вы охраняете.
  • Если его случайный бросок храбрости преодолеет порог страха в этом раунде, он попытается попасть.
    • Наличие Меча Богов делает его храбрее.
    • Противник с Мечом Богов делает его более страшным.
    • Оппонент, который ведет не менее 5 единиц здоровья и более, также немного пугает его.
  • В противном случае он по очереди охраняет и кланяется.

Если вы хотите написать представление Node.js , пожалуйста, не стесняйтесь использовать мой стандартный код; все, включая decideфункцию, является полностью общей и бесплатной.


node coward.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var enemyGuards = !!enemy.history.match(/G.G.G.$/);
var enemyBows = !!enemy.history.match(/(B.B.B.$)|(BBB$)/);

// open with a bow
if(!my.history) { decide("B"); }

// enemy will likely bow? Hit them with your super sword! (or bow)
if((!enemy.honor || enemyBows)) {
    if(my.godSword) { decide("P","I","O"); }
    else { decide("B"); }
}

// no point in hitting them if they're going to guard
if(enemyGuards) { decide("B"); }

// calculate bravery level
var braveryLevel = 0.3;
braveryLevel += (my.godSword * 0.2) - (enemy.godSword * 0.2);
braveryLevel -= (enemy.health - my.health > 5) * 0.1;

// if we're feeling brave, hit them
if(Math.random() < braveryLevel && my.honor) { decide("P","I","O"); }

// if we didn't just guard, and we're not feeling brave, cower in fear
if(!my.history.match(/G$/)) {
    decide("G");
}

// if we did just guard, and we're feeling cowardly,
//   if we don't have sword of the gods, bow
//   otherwise, do anything except guard
if(!my.godSword) {
    decide("B");
} else {
    decide("B","P","I","O");
}

1
Это жесткий бот. Потрясающий шаблон; Я использую это прямо сейчас. Спасибо, что поделились :)
C5H8NNaO4

6

Ударить моль (R)

Наносит удар, когда враг может поклониться, иначе охранник.

args <- commandArgs(TRUE)
L <- length(args)
my_health <- as.integer(args[L-3])
enemy_health <- as.integer(args[L-2])
my_honour <- as.integer(args[L-1])
enemy_honour <- as.integer(args[L])
if(L>4){enemy_history <- args[L-4]}else{enemy_history <- ""}
if(my_honour<1){
    out <- "B"
}else if (enemy_honour<=1 | grepl("BB$",enemy_history)){
    out <- sample(c("I","O"),1)
}else{
    out <- "G"
}
cat(out)

Запустить с помощью Rscript Whack-a-mole.R.


1
Хорошая работа, плюс я люблю имя.
Алекс А.

3

Слон Воин (Ява)

Слон Воин из более старого, более естественного времени. Он много видел и все помнит. Он прославляет богов, пока исследует своего противника, а затем, как только он берет их в свое сердце, он разбирает их.

Компилировать: javac ElephantWarrior.java
команда:java ElephantWarrior

import java.util.LinkedList;

//Elephants never forget
class ElephantWarrior
{


  static LinkedList<Choice> analysis = new LinkedList<Choice>();

  public static void main(String[] args){
      if(args.length < 6){ respond("B");}   
      String myhis = args[0];
      String enHis = args[1];
      int health = Integer.parseInt(args[2]);
      int enHealth = Integer.parseInt(args[3]);
      int honour = Integer.parseInt(args[4]);
      int enHonour = Integer.parseInt(args[5]);

        //Bow a few times until I know how he operates
        if(enHis.length() <= 5){
            respond("B");
        }

        //Special cases
        //If I'm at 0 honor, better bow
        else if(honour <= 0){
            respond("B");

        }
        else{
          analyze(enHis);

          //Narrow it down to applicable choices
          char hisLast = enHis.toCharArray()[enHis.toCharArray().length - 1];
          LinkedList<Choice> hisOptions = new LinkedList<Choice>();
          for(Choice c: analysis){
              if(c.pattern.toCharArray()[0] == hisLast){
                  hisOptions.add(c);
              }
          }

           //Default to assuming they bow
          char hisNext = 'B';
          int mostLikely = 0;

          //What will they do next?
          for(Choice c : hisOptions){
              if(c != null && c.probability > mostLikely){
                  //System.out.println("Option = " + c.pattern);
                  //System.out.println("Prob = " + c.probability);
                  mostLikely = c.probability;
                  hisNext = c.pattern.toCharArray()[1]; }
          }

          //Now go through potential case
          switch(hisNext){
              case 'W':
                  respond("I");
                  break;
              case 'B': 
                  respond("O");
                  break;
              case 'G':
                  respond("B");
                  break;
              case 'I':
                  if(enHonour  > 0){
                      respond("P");
                  }
                  else{
                      respond("B");
                  }
                  break;
              case 'P':
                  respond("O");
                  break;
              case 'O':
                  respond("I");
                  break;
              default:
                  respond("G");
          }
        }
    }





      static void analyze(String his){

        //Keep track of his previous moves
        char[] shortString = his.substring(1,his.length() - 1).toCharArray();
        char[] longString = his.toCharArray();
        for( int i = 0; i < shortString.length; i++) {
          String pattern = "" + longString[i] + shortString[i];
          boolean exists = false;
          for(Choice c : analysis){
              if(c.pattern.equals(pattern)){
                  exists = true;
                  c.probability++;
              }
          }
          if(!exists){
              analysis.add(new Choice(pattern, 1));
          }
        }
      }

      private static void respond(String s){
            System.out.println(s);
            System.exit(0);
        }

    }

class Choice{
        String pattern;
        int probability;

       Choice(String p, int i){
            pattern = p;
            probability = i;
       }
}

2
Я не проверял это, но похоже, что он выйдет за пределы на первом повороте, где есть только четыре args.
Geobits

Правильно, не осознавал, что они вообще не будут включены. Я думаю, очевидно, пустая строка не может быть передана, спасибо!
Каин

@katya Это исправлено, кстати, должно быть включено в турнир.
Каин

3

Королева Воинов (Юлия)

Это первый вызов King of the Hill, в котором я участвовал. Посмотрим, как это будет.

Принцесса-Воин отдает приоритет атакам и чести и прибегает к самосохранению, когда это необходимо. Она очень хочет и никогда не ждет. В стремлении остаться проворным, она также не использует атаку сверху.


Сохранить как warrior-princess.jlи запустить из командной строки следующим образом:

julia warrior-princess.jl <arguments>

Если у вас нет Джулии, вы можете скачать ее здесь . Чтобы избежать проблем, рекомендуется последняя стабильная версия (т.е. не версия для разработчиков).


type Samurai
    history::String
    health::Int
    honor::Int
end

A = length(ARGS) < 5 ? ["", "", ARGS] : ARGS

me = Samurai(A[1], int(A[3]), int(A[5]))
opponent = Samurai(A[2], int(A[4]), int(A[6]))


if length(me.history) == 0

    # Always begin the match with an honorable bow
    action = "B"

elseif (!ismatch(r"[OIP]", opponent.history) && me.history[end] != 'G') ||
       (me.health < 2 && me.honor > 0)

    # Guard if the enemy has not yet attacked and I did not previously
    # guard, or if my health is low and my honor is sufficient
    action = "G"

elseif me.honor < 2

    # Bow if I'm low on honor
    action = "B"

elseif opponent.honor >= 7 && opponent.history[end]['B', 'W']

    # Assume the enemy will attack with the Sword of the Gods if they
    # most recently bowed or waited
    action = "I"

else
    action = "P"
end

println(action)

1
Ваша первая запись в KotH и первая запись в Julia KotH, если я не ошибаюсь: поздравляю!
plannapus

@plannapus Спасибо! : D Возможно, я сделаю из этого привычку.
Алекс А.

3

Горгулья (Ява)

Пытается использовать защитный ход без потери чести.

Так как это Java-запись:

> javac Gargoyle.java
> java Gargoyle
public class Gargoyle { 
    public static void main(String args[]) {
        if (args.length < 5 || Integer.valueOf(args[4]) > 0) {
            System.out.println("IPO".charAt((int)(Math.random()*3)));
        } else if (args[0].charAt(args[0].length()-1) != 'G') {
            System.out.println('G');
        } else {
            System.out.println('B');
        }
    }
}

3

Мечник (C / Java)

Мечник кланяется в первый ход и всякий раз, когда ему не хватает чести. Затем он проверяет, не поклонился ли противник, не защищался или не ждал в предыдущем ходу. Если противник этого не сделал, есть большая вероятность, что он сделает одно из них в текущем ходу, и фехтовальщик случайно ударит противника. Если это не так, он защищается, если он не защищал предыдущий ход. Если он имел, он кланяется, чтобы получить честь.

C версия:

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

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    char* attack_moves[]={"I", "P", "O"};
    int random_num = rand() % 3;

    if(argc == 5 || atoi(argv[5]) == 0)
        print_and_exit("B");
    else if(argv[2][strlen(argv[2])-1] != 'B' && argv[2][strlen(argv[2])-1] != 'G' && argv[2][strlen(argv[2])-1] != 'W')
        print_and_exit(attack_moves[random_num]);
    else if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit("G");

     print_and_exit("B");
}

Установите GCC (компилятор) и сохраните код в файл с именем команды « Swordsman.c » для компиляции:

gcc Swordsman.c -o Swordsman

Исполняемый файл с именем " Мечник " будет создан. Запустить с помощью

Swordsman

Версия Java:

public class Swordsman {

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        int random_num = (int)(Math.random()*3);

        if(argv.length == 4 || Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else if(argv[2].charAt(argv[2].length()-1) != 'B' && argv[2].charAt(argv[2].length()-1) != 'G' && argv[2].charAt(argv[2].length()-1) != 'W')
            print_and_exit(attack_moves[random_num]);
        else if(argv[1].charAt(argv[1].length()-1) != 'G')
            print_and_exit("G");

         print_and_exit("B");
    }

}

Установите javac (компилятор) и сохраните код в файле с именем « Swordsman.java » для компиляции команды:

javac Swordsman.java

Будет создан файл класса с именем « Swordsman.class ». Запустить с помощью

java Swordsman



Атакующий (Java)

Атакующий не заботится ни о чем, кроме того, что он хочет, чтобы его противник умер. Он случайным образом наносит удар одному из атакующих движений и, если имеет низкую честь, кланяется.

public class Attacker {

    static int position = -1;

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        position = (position + 1) % 3;

        if(argv.length != 5 && Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else 
            print_and_exit(attack_moves[position]);
    }

}

Установите javac (компилятор) и сохраните код в файле с именем команды « Attacker.java » для компиляции:

javac Attacker.java

Будет создан файл класса с именем « Attacker.class ». Запустить с помощью

java Attacker


Предиктор (C / Java)

Предиктор предсказывает движения врагов. В первом повороте он использует случайный ход. Кланяется, если его честь низка, наносит удар, если честь врага низка или поклонился в предыдущем ходу. Если предиктор не охранял предыдущий ход, то охраняет текущий ход. Иначе, делает тот же ход, что и противник в предыдущем ходу, при условии, что это не так'W' в этом случае Predictor не кланяется.

C версия:

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

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    int random = rand() % 5;
    char* moves[] = {"B", "G", "I", "P", "O"};

    if(argc == 5)
        print_and_exit(moves[random]);

    if(atoi(argv[5]) <= 0)
        print_and_exit(moves[0]);
    if(atoi(argv[6]) <= 0)
        print_and_exit(moves[4]);
    if(argv[2][strlen(argv[2])-1] == 'G')
        print_and_exit(moves[4]);
    if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit(moves[1]);

    if(argv[2][strlen(argv[2])-1] != 'W'){
        char buf[2]={0};
        *buf = argv[2][strlen(argv[2])-1];
        print_and_exit(buf);
    }

    print_and_exit(moves[0]);

}

Установите GCC (компилятор) и сохраните код в файл с именем команды « Predictor.c » для компиляции:

gcc Predictor.c -o Predictor

Исполняемый файл с именем « Предиктор » будет создан. Запустить с помощью

Predictor

Версия Java:

public class Predicator{

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }

    public static void main(String[] argv){

        int random = (int)(Math.random() * 5);
        String moves[] = {"B", "G", "I", "P", "O"};

        if(argv.length == 4)
            print_and_exit(moves[random]);
        else if(Integer.valueOf(argv[5]) <= 0)
            print_and_exit(moves[0]);
        else if(Integer.valueOf(argv[6]) <= 0)
            print_and_exit(moves[4]);
        else if(argv[2].charAt((argv[2].length())-1) == 'G')
            print_and_exit(moves[4]);
        else if(argv[1].charAt((argv[1].length())-1) != 'G')
            print_and_exit(moves[1]);
        else if(argv[2].charAt((argv[1].length())-1) != 'W'){
                    print_and_exit(""+argv[2].charAt((argv[2].length())-1));
        }
        else
            print_and_exit(moves[0]);
    }
}

Установите javac (компилятор) и сохраните код в файл с именем команды « Predicator.java » для компиляции:

javac Predicator.java

Будет создан файл класса с именем « Predicator.class ». Запустить с помощью

java Predicator


Не уверен, насколько эффективными будут эти боты, поскольку у меня нет интерпретатора python2 для его проверки.


1
Я не проверял это (Атакующий), но похоже, что он выйдет за пределы на первом ходу, где есть только четыре аргумента.
Geobits

Атакующий, кажется, дает ArrayIndexOutOfBoundsExceptionна первом ходу, заставляя его ждать на первом ходу. Помимо этого он функционирует.
Абсент

@Katya и Geobits, Исправлено. Спасибо, что заметили это.
Спикатрикс,

При запуске предиктора я получаю segmentation fault (core dumped)после 24 раунда
C5H8NNaO4

@ C5H8NNaO4 Исправлена ​​проблема. Обновлен код для всех трех ботов. Теперь должно работать нормально. Спасибо за указание на это! :-D
Spikatrix

2

Мастер Йи (Питон)

Мастер-убийца получает большую поддержку в начале игры, наращивая его до тех пор, пока он не станет непобедимым. Пытается атаковать, когда они меньше всего этого ожидают.

import sys, random

class MasterYi(object):
    def __init__(self):
        self.attack = lambda: random.choice(['I','P','O'])
        self.bow   = "B"
        self.guard = "G"
        self.wait  = "W"
        if len(sys.argv)>6:
            self.hist = sys.argv[1]; self.ohist = sys.argv[2]
            self.hp   = sys.argv[3]; self.ohp   = sys.argv[4]
            self.hon  = sys.argv[5]; self.ohon  = sys.argv[6]
        else:
            self.hist = [];          self.ohist = []
            self.hp   = sys.argv[1]; self.ohp   = sys.argv[2]
            self.hon  = sys.argv[3]; self.ohon  = sys.argv[4]
        self.last  = self.hist  and self.hist[-1]  or "W"
        self.olast = self.ohist and self.ohist[-1] or "W"
        self.oGuarder = len(self.ohist)>4 and self.ohist[-4]==self.ohist[-2]=="G"

    def move(self):
        if self.hon < 1: return self.bow
        if self.olast == "G": return self.attack
        if self.hon > 6:
            if self.oGuarder: return self.bow
            if self.ohon > 6: return self.guard
            if self.ohon < 7: return self.attack
            return self.attack
        if self.ohon > 6: return self.guard
        return self.bow

Yi = MasterYi()
print(Yi.move())

Для запуска: Сохранить как MasterYi.py

python MasterYi.py <args>

2

Копия Сан (С)

Копирует каждый ход своего противника. Уверен, он гарантированно проиграет. Обобщение:gcc copy-san.c

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

int main(int argc, char *argv[]) {
    if (argc == 5) {
        putchar('B');
    } else {
        char *enemy_hist = argv[2];
        size_t len = strlen(enemy_hist);
        putchar(enemy_hist[len - 1]);
    }
    putchar('\n');
    return 0;
}

2

Хеби (Ява)

Хэби следует по Пути Змеи.

Змея не нуждается в благословении богов.

Змея скользит своими ударами; как волны на пляже, то, что приходит, отступает назад, как оно пришло.

Змея никогда не ждет.

У Змеи нет чувства уместности, иначе это было бы написано на Python.

Инструкция по эксплуатации:

> javac hebi.java
> java hebi

Код тела:

public class hebi{

    public static void main(String args[]){

        if( (args.length < 5) || (args[0].length() % 18 == 0) ) System.out.println( "IPO".charAt((int)(Math.random()*3)) );
        else{

            int hist_size = args[0].length();

            if      (hist_size % 3 == 1) System.out.println("G");
            else if (hist_size % 3 == 2) System.out.println("B");
            else{

                if     (hist_size % 18 ==  9) System.out.println(args[0].charAt(hist_size -  3));
                else if(hist_size % 18 == 12) System.out.println(args[0].charAt(hist_size -  9));
                else if(hist_size % 18 == 15) System.out.println(args[0].charAt(hist_size - 15));
                else{

                    char move_head = args[0].charAt( (hist_size / 18) * 18 );
                    char move_mid;
                    if( hist_size % 18 == 3 ){
                        if     ( move_head == 'I' ) move_mid = "PO".charAt((int)(Math.random()*2));
                        else if( move_head == 'O' ) move_mid = "IP".charAt((int)(Math.random()*2));
                        else                        move_mid = "OI".charAt((int)(Math.random()*2));
                        System.out.println(move_mid);
                    }
                    else{
                        move_mid = args[0].charAt( ((hist_size / 18) * 18) + 3 );
                        char move_tail;

                        if( move_head == 'I' ){
                            if( move_mid == 'P' ) move_tail = 'O';
                            else                  move_tail = 'P';
                        }else if( move_head == 'P' ){
                            if( move_mid == 'O' ) move_tail = 'I';
                            else                  move_tail = 'O';
                        }else{
                            if( move_mid == 'I' ) move_tail = 'P';
                            else                  move_tail = 'I';
                        }

                        System.out.println( move_tail );

                    }

                }

            }

        }

    }

}

2

Достопочтенный (Ява)

Достопочтенные ценности чести превыше всего. То есть его честь выше всех остальных. Если враг самурая имеет большую или равную честь, он кланяется. Никто не должен быть более благородным, чем он. В противном случае он делает случайный ход. Он никогда не охраняет дважды подряд - это было бы бесчестно!

Скомпилировать:

> javac TheHonourable.java
> java TheHonourable

Источник:

public class TheHonourable {
    public static void main(String[] args) {
        char move;

        if (args.length < 5) {
            move = 'B';
        } else if (Integer.valueOf(args[5]) >= Integer.valueOf(args[4])){
            move = 'B';
        } else {
            move =  (args[0].endsWith("G")) ?
                    "IPO".charAt((int)(Math.random()*3)) :
                    "GIPO".charAt((int)(Math.random()*4));
        }

        System.out.print(move);
    }
}

1

Благословенный Самурай (Питон)

Этот самурай пытается сохранить благосклонность богов как можно дольше. Он бросается за священным мечом, затем переключается между Охраной и Атакой одним из ударов, пополняя честь при необходимости. Если похоже, что он или его противник скоро упадут, он бросается на убийство. Он легко упадет противнику, который может отслеживать его паттерн, но его стратегия всегда атаковать с двумя уронами должна быть довольно эффективной.

import sys
import random
class BlessedSamurai(object):
    def __init__(self):
        if len(sys.argv) < 7:
            print("B")
        else:
            self.attack = ['O', 'I', 'P']
            self.hp = sys.argv[3]
            self.ohp = sys.argv[4]
            self.hon = sys.argv[5]
            self.last = sys.argv[1][-1]
            print(self.move())

    def move(self):
        #check if I have low health or should rush the kill
        if (self.hp < 5 or self.ohp < 5) and self.hon > 0:
            return(random.choice(self.attack))
        # charge honour to get SOTG
        elif self.hon < 7:
            return 'B'
        #Alternate guarding and attacking
        else:
            if self.last == 'G':
                return(random.choice(self.attack))
            return 'G'
Sam = BlessedSamurai()

Для запуска:
Сохранить как BlessedSamurai.py

python BlessedSamurai.py <args>

4
Ваша программа должна напечатать свой ход.
mbomb007

3
Я не проверял это, но похоже, что он выйдет за пределы на первом повороте, где есть только четыре аргумента.
Geobits

Я использовал формат, аналогичный тому, что он сделал. @ Stranjyr, посмотри, что я сделал для получения аргументов.
mbomb007

Спасибо вам обоим! Сейчас у меня нет доступа к интерпретатору python, но я думаю, что я исправил проблемы. Почему-то я полностью упустил, что первый набор инструкций не будет иметь истории.
Странджир,

Привет, у вас была небольшая ошибка в вашей программе "глобальное имя 'last' не определено". Так как это небольшая ошибка , я изменил lastна self.lastкоторый , кажется , чтобы решить эту проблему.
Абсент

1

Hermurai (C ++)

Восхищается своим противником и немного параноидален. Хочет знать, может ли он сделать то, что могут другие самураи, потому что он все еще не может поверить, что он самурай. Его нескончаемый сон стал реальностью до того, как он об этом узнал. Что может стоить ему головы ...

#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string enemy_history(argv[2]);

    int ho;
    string honour(argv[5]);
    stringstream(honour) >> ho;

    if(ho > 20){
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }

    char lastMove = enemy_history[enemy_history.length()-1];
    if(lastMove == 'W' || lastMove == 'G')
        lastMove = 'B';
    printf("%c", lastMove);
    return 0;
}

Иниги (C ++)

Удары как можно сильнее. Переходит в режим неудержимой атаки, когда он в опасности.

#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string history(argv[1]);
    string enemy_history(argv[2]);
    string health(argv[3]);
    string enemy_health(argv[4]);
    string honour(argv[5]);
    string enemy_honour(argv[6]);

    int he, enemy_he, ho, enemy_ho;
    stringstream(health) >> he;
    stringstream(enemy_health) >> enemy_he;
    stringstream(honour) >> ho;
    stringstream(enemy_honour) >> enemy_ho;

    if(ho > 6 || ((he < 6 || enemy_he < 6) && ho > 0))
    {
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }


    printf("B");
    return 0;
}

Оба написаны на C ++. Скомпилировать:

g++ iniqy.cpp -o iniqy

Для запуска в Linux: ./iniqy

Для запуска в Windows: iniqy.exe


1

Терминатор (рубин)

Терминатор не обращает внимания на собственное здоровье. Терминатор не имеет понятия о чести. Терминатор отправляется из будущего и просто намерен уничтожить своего противника. Он делает это, наблюдая за движениями своих противников, и ничего больше. Он анализирует ходы и вычисляет соответствующий ответ таким сложным образом, что никакая современная технология не может предсказать действия Терминатора. На самом деле, любому, кто живет в 2015 году, терминатор может показаться несколько случайным ...

responses = {
  ?W => %w(B I),
  ?B => %w(I O),
  ?G => %w(B B),
  ?I => %w(G P),
  ?P => %w(B O),
  ?O => %w(G I)
}

if ARGV.size > 4
  pool = ARGV[1].chars.map{ |c| responses[c] }.flatten
  puts pool.sample
else
  puts %w(O I P B).sample
end

1

Агент 38 [1] (С)

Являясь продуктом обширных генетических манипуляций, Агент 38 обладает телосложением и остротой ума супер [2] -самураев и определенно превосходит всех своих беспомощных [нуждающихся в цитировании] дефектных [нуждающихся в цитировании] конкурентов.


//Agent 38
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#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

float program[5][4][4][4][4]={
    {{{{-1.192779,0.693321,-1.472931,-0.054087},{0.958562,0.557915,0.883166,-0.631304},{-0.333221,1.410731,0.496346,0.087134},{0.459846,0.629780,-0.479042,-0.025909}},{{0.547976,1.059051,-0.748062,-0.675350},{-0.607591,-0.152156,-0.400350,-0.685337},{1.686450,0.628706,0.312865,0.324119},{1.652558,0.403733,-0.456481,-0.081492}},{{0.371629,-0.036948,-0.982682,0.065115},{1.360809,0.681294,0.505074,0.782737},{-0.545192,0.954937,-0.727853,0.273542},{-0.575777,1.615253,-0.064885,-0.516893}},{{0.577015,-0.112664,0.456595,-0.007560},{-0.660930,-0.738453,0.668093,1.716388},{1.972322,0.108558,0.535114,-0.337916},{0.640208,-0.019680,-0.769389,0.873087}}},{{{-0.021140,-0.095956,-0.098309,-0.280295},{-0.926284,1.724028,0.278855,0.678060},{0.153006,-1.860947,-0.577699,-1.931683},{-0.187152,0.529719,-1.164157,0.125499}},{{0.582208,-0.835029,-0.329857,0.088176},{-0.030797,0.389396,0.584636,-0.025866},{-0.736538,1.624658,0.690493,0.387515},{0.973253,-0.530825,1.934379,-0.872921}},{{0.812884,0.138399,-1.452478,-1.504340},{-0.119595,0.986078,-0.993806,1.102894},{0.848321,-0.268764,0.876110,0.782469},{0.948619,-0.557342,0.749764,-0.712915}},{{-1.195538,0.783784,-1.973428,-0.873207},{0.085426,-0.241360,-0.534561,-0.372105},{0.029696,-0.906821,0.932227,-0.834607},{0.764903,-0.276117,-1.346102,-0.093012}}},{{{0.168113,0.855724,1.817381,-0.547482},{0.468312,0.923739,-0.723461,0.798782},{-0.875978,-0.942505,-0.684104,-0.046389},{0.893797,-0.071382,0.283264,0.811233}},{{0.391760,0.309392,-0.045396,-0.977564},{0.085694,0.257926,-0.775461,0.060361},{0.486737,-0.175236,0.806258,-0.196521},{0.691731,-0.070052,0.636548,0.464838}},{{0.532747,-1.436236,-0.900262,-0.697533},{0.566295,0.650852,0.871414,-0.566183},{-0.075736,-0.886402,0.245348,-0.438080},{-0.811976,0.022233,-0.685647,0.323351}},{{-1.864578,1.141054,1.636157,-0.455965},{0.592333,0.890900,-0.259255,0.702826},{0.404528,0.905776,0.917764,0.051214},{0.761990,0.766907,-0.595618,-0.558207}}},{{{0.209262,-1.126957,-0.517694,-0.875215},{0.264791,0.338225,0.551586,0.505277},{0.183185,0.782227,0.888956,0.687343},{0.271838,0.125254,1.071891,-0.849511}},{{0.261293,-0.445399,0.170976,-0.401571},{0.801811,0.045041,-0.990778,-0.013705},{-0.343000,-0.913162,0.840992,0.551525},{-0.526818,-0.231089,0.085968,0.861459}},{{0.540677,-0.844281,-0.888770,0.438555},{0.802355,-0.825937,0.472974,-0.719263},{-0.648519,1.281454,0.470129,-0.538160},{-0.851015,0.985721,-0.993719,0.558735}},{{1.164560,-0.302101,0.953803,0.277318},{0.886169,0.623929,1.274299,-0.559466},{-0.948670,0.807814,-1.586962,-0.502652},{-0.069760,1.387864,-0.423140,0.285045}}}},
    {{{{0.747424,-0.044005,0.402212,-0.027484},{0.785297,0.169685,0.734339,-0.984272},{-0.656865,-1.397558,0.935961,-0.490159},{-0.099856,-0.293917,0.129296,-0.920536}},{{0.546529,-0.488280,-0.516120,-1.112775},{0.155881,-0.103160,0.187689,0.485805},{0.918357,0.829929,0.619437,0.877277},{0.389621,0.360045,0.434281,0.456462}},{{-0.803458,-0.525248,-0.467349,0.714159},{-0.648302,-0.005998,-0.812863,0.205664},{0.591453,0.653762,-0.227193,-0.946375},{0.080461,0.311794,0.802115,-1.115836}},{{-0.495051,-0.869153,-0.179932,0.925227},{-1.950445,1.908723,-0.378323,-0.472620},{-0.688403,-1.470251,1.991375,-1.698926},{-0.955808,-0.260230,0.319449,-1.368107}}},{{{-0.029073,-0.622921,-1.095426,-0.764465},{-0.362713,-0.123863,0.234856,-0.772613},{0.697097,0.103340,0.831709,0.529785},{0.103735,-0.526333,-0.084778,0.696831}},{{-0.670775,0.289993,-0.082204,-1.489529},{0.336070,0.322759,0.613241,0.743160},{0.298744,-1.193191,0.848769,-0.736213},{0.472611,-0.830342,0.437290,-0.467557}},{{-0.529196,-0.245683,0.809606,-0.956047},{-1.725613,0.187572,0.528054,-0.996271},{-0.330207,0.206237,0.218373,0.187079},{0.243388,0.625787,-0.388859,0.439888}},{{-0.802928,-0.811282,0.788538,0.948829},{0.966371,1.316717,0.004928,0.832735},{-0.226313,0.364653,0.724902,-0.579910},{-0.544782,-0.143865,0.069256,-0.020610}}},{{{-0.393249,0.671239,-0.481891,0.861149},{-0.662027,-0.693554,-0.564079,-0.477654},{0.070920,-0.052125,-0.059709,0.473953},{-0.280146,-0.418355,0.703337,0.981932}},{{-0.676855,0.102765,-0.832902,-0.590961},{1.717802,0.516057,-0.625379,-0.743204},{-0.170791,-0.813844,-0.269250,0.707447},{0.057623,0.472053,-0.211435,0.147894}},{{-0.298217,0.577550,1.845773,0.876933},{0.617987,0.502801,0.951405,0.122180},{0.924724,-0.166798,0.632685,-0.466165},{-0.834315,-0.864180,-0.274019,0.568493}},{{0.669850,-0.961671,0.790462,0.738113},{-0.534215,-0.556158,0.653896,0.031419},{0.065819,0.220394,0.153365,-0.373006},{0.886610,-0.742343,1.282099,0.198137}}},{{{0.092579,-0.026559,-1.121547,0.143613},{-0.289030,0.265226,-0.350741,-0.897469},{-0.918046,0.038521,-1.515900,0.488701},{-0.759326,-1.782885,-1.787784,0.249131}},{{-0.849816,-0.857074,-0.843467,-0.153686},{0.998653,0.356216,0.926775,0.300663},{-0.749890,-0.003425,-0.607109,0.317334},{-0.561644,0.446478,-0.898901,0.711265}},{{0.232020,-0.445016,0.618918,0.162098},{0.381030,-0.036170,0.084177,0.766972},{0.493139,0.189652,-0.511946,-0.273525},{0.863772,-0.586968,0.829531,-0.075552}},{{0.191787,-0.627198,0.975013,-0.448483},{-0.197885,0.151927,-0.558646,-1.308541},{-0.582967,1.207841,0.746132,0.245631},{0.314827,-0.702463,-0.301494,0.787569}}}},
    {{{{0.670028,-1.825749,-0.739187,0.482428},{0.175521,-0.020120,-0.154805,0.187004},{0.971728,-0.160181,-0.164031,-0.868147},{-0.954732,-0.175713,0.791116,0.294173}},{{-0.958337,-0.843157,-0.472882,0.273517},{-0.999058,0.824762,-0.223130,-0.150628},{0.393747,-0.301297,0.095572,-0.798950},{-0.119787,0.746673,0.955094,0.259353}},{{0.951590,0.225539,0.503282,0.668746},{-0.384898,-0.979592,-0.005485,-0.191883},{-0.692369,-0.642401,-0.825598,0.171933},{-0.321919,-0.498635,0.449704,0.780842}},{{-0.387902,0.522435,0.565608,0.166193},{-0.799671,-0.295871,-0.702573,-0.151006},{0.040550,-0.468503,0.651076,0.636352},{-0.839299,-0.090651,0.428761,0.187043}}},{{{-0.369823,0.377011,0.422936,0.284752},{-0.181514,-0.701449,0.748768,0.540533},{0.734381,0.149410,-0.867043,-0.397142},{-0.770904,-0.581897,-1.578306,-0.402638}},{{0.859015,-0.540358,0.202715,-0.975354},{-0.773629,-0.382342,-0.022498,-0.129286},{-0.901210,-0.641866,1.219216,0.731525},{0.740457,0.858546,-0.408661,-0.364897}},{{-0.830865,-1.370657,-1.226303,-0.392147},{-0.810554,-0.975232,-0.717845,-0.825379},{-0.150096,-0.664533,0.347084,0.243443},{-0.447383,0.842164,1.491342,0.380295}},{{-0.383958,0.811219,0.160459,0.841601},{1.631515,0.371637,0.110000,0.467783},{-0.689356,-0.004289,-0.081057,-0.317243},{0.092451,-0.181268,-0.575747,-0.580061}}},{{{0.908549,-0.013975,-0.880165,-0.938937},{-0.225713,0.449478,0.372569,-0.229889},{0.255711,-0.264752,0.307982,0.260505},{0.314966,-0.540905,0.743032,-0.078475}},{{-0.307472,-1.268296,0.020383,1.798401},{-0.150954,0.909716,-0.407903,0.379046},{0.621853,-0.003629,-0.582697,0.614618},{-0.122843,-0.627133,-0.217968,0.608322}},{{0.071923,0.807315,0.538905,-0.630660},{0.495641,0.240202,-0.920822,-0.258533},{-1.760363,-0.448525,-0.351553,-0.551666},{0.152720,0.900531,0.061966,-0.544377}},{{0.648923,0.450945,-1.530020,1.570190},{0.536210,0.078454,0.577168,0.464872},{-0.888258,-0.950748,0.781474,0.958593},{0.463631,0.319614,-0.248374,-0.413144}}},{{{0.293463,0.236284,1.721511,0.107408},{-0.790508,-0.072027,-0.559467,-0.955839},{-0.777662,-0.169876,0.896220,0.776105},{0.003944,-0.745496,-0.236446,-0.824604}},{{-1.770746,-0.051266,-0.174258,0.003074},{-0.339553,-0.868807,-0.032754,-0.494847},{-0.896712,0.957339,-0.003444,-1.582125},{-0.699883,0.626691,0.799635,-0.542343}},{{-0.635123,-0.755960,0.576373,-0.899530},{-0.393745,0.718900,0.312400,0.511415},{-0.647565,0.368431,0.214726,0.892693},{-0.511960,-0.513262,0.885908,-0.536478}},{{-0.590074,0.623328,0.268674,-0.401391},{0.308868,-0.869862,0.233132,0.243337},{-0.242908,-0.557192,-0.728454,0.867029},{0.156435,-0.805308,-0.815392,-1.437798}}}},
    {{{{0.613484,1.454566,-0.363858,0.634053},{0.535096,-0.641079,-0.607553,0.852559},{0.959100,-0.398621,0.375819,0.385756},{-0.601982,0.494128,0.809699,0.608804}},{{-1.390871,-0.943062,1.556671,0.966501},{-0.013242,0.152716,-0.089592,0.230793},{0.933785,0.119358,0.057387,0.502033},{-0.332925,0.537509,-0.081436,-0.701995}},{{-0.435117,0.996885,0.646630,-0.092342},{0.004343,-0.737514,-0.716187,-0.946819},{0.814258,-0.766971,-0.488162,-0.531619},{-0.923069,0.683915,-0.023809,-1.242992}},{{-0.909155,-0.166488,-0.159273,-0.908121},{-0.783871,-0.522598,0.691845,-0.164065},{1.255966,0.051373,-0.566025,0.820081},{0.186583,0.266032,-0.793747,-0.510092}}},{{{0.890639,0.970042,-0.507885,-0.029557},{-0.771142,-0.875802,0.400070,-1.264247},{-0.881146,0.570950,-0.051624,0.347612},{0.312110,-0.374885,0.600112,0.388460}},{{-0.417107,-0.309284,-0.128477,0.689671},{-0.695866,1.254585,-0.381883,-0.313415},{0.433565,0.919626,0.159180,-0.657310},{-1.396139,0.346053,0.108768,0.061238}},{{-0.776695,0.084491,0.045357,0.312823},{-0.379268,1.217006,-0.014838,-1.032272},{-1.251344,-0.366283,-0.124786,0.729754},{0.979936,0.669519,-0.900018,-0.596954}},{{-0.998834,0.593942,0.375639,-0.627459},{0.297281,0.400240,0.839707,0.960262},{-0.872143,0.574040,-0.559580,-1.965570},{-0.559218,-0.778780,-0.955526,-0.253380}}},{{{-1.919625,-1.911049,0.025035,0.754917},{-0.110993,0.535933,-0.572788,-0.856476},{-0.810836,-0.496261,1.128368,1.758826},{-0.564368,-1.849772,-0.251560,0.635528}},{{0.768196,-0.934122,0.207228,0.884610},{-0.356145,0.265792,-0.835582,0.377675},{-0.410745,0.613212,0.245560,-0.873826},{1.725191,-0.263344,-0.077167,-0.976379}},{{-0.736299,-0.109476,0.044512,-0.004005},{0.692230,0.316670,0.267247,-1.076821},{-0.903184,0.189762,-0.674111,0.219113},{0.639162,1.347521,0.428823,-0.765664}},{{-0.509165,0.458806,-0.851011,0.455027},{-0.218564,-0.063492,0.889320,-0.762062},{0.145950,0.985037,-0.489372,-0.879851},{0.352346,-0.127275,0.896496,-0.596037}}},{{{0.402678,1.479855,0.089187,0.967153},{-0.431225,0.402980,0.883584,-0.900324},{0.262233,-0.647278,0.637005,0.142678},{-0.003253,-0.671924,0.969458,-0.316752}},{{0.345185,-0.477503,-0.326822,-0.106251},{0.239521,1.617125,0.632651,0.969976},{-1.015183,-0.676629,0.955842,0.134925},{-0.319063,-0.493157,-0.488088,0.713008}},{{-0.468621,1.301292,-1.826501,1.138666},{0.170247,-0.661171,0.895204,-0.400700},{-0.077645,-0.978179,-0.245724,0.245282},{-0.258300,0.287261,-0.006274,0.549716}},{{-0.932247,-0.274950,0.920451,0.016237},{0.888865,-0.845248,1.661716,-0.108960},{0.712357,0.586609,-0.867356,0.355058},{-0.540912,0.892622,0.302627,0.247194}}}},
    {{{{0.817578,0.719047,0.438903,0.637398},{0.750466,-0.911799,-0.609606,0.358541},{-1.782979,-0.851717,-0.802122,0.735913},{0.490604,-0.417822,-0.332074,0.836756}},{{-0.650232,-0.442026,0.874916,0.705671},{0.217602,-0.755841,0.573944,0.279365},{-0.713729,0.358880,-0.308992,0.778297},{0.832099,-0.916695,-0.887834,1.041483}},{{1.019467,1.099488,-0.130674,-0.241995},{0.792572,0.756977,0.518186,0.070411},{-0.815779,-0.790757,-1.027439,-0.163698},{0.721461,-0.403364,0.656609,-0.367364}},{{-0.279333,-0.742041,0.515832,-0.408114},{0.834577,0.736056,0.900594,0.276357},{0.726000,0.464991,-0.569281,0.098139},{-0.582324,0.875666,-0.681556,-0.903009}}},{{{1.300969,-0.798351,0.107230,1.611284},{0.239211,0.418231,-0.795764,-0.398818},{-0.939666,1.768175,-0.297023,-0.064087},{-0.239119,-0.365132,0.864138,0.595560}},{{1.898313,-0.343816,1.066256,0.876655},{-0.053636,0.544756,-0.937927,0.189233},{0.445371,-0.656790,-0.675091,0.753163},{-0.293330,-0.002717,0.341173,0.095493}},{{0.951658,0.513912,-0.678347,-0.981140},{-0.020791,0.571138,-0.890648,0.881789},{-1.783345,0.909598,-0.393155,0.240630},{-0.057908,-0.237435,-0.124993,-0.754091}},{{-0.014153,0.127172,0.097134,0.538952},{0.167943,0.786395,0.946153,-0.762513},{-0.562758,0.675657,-0.226395,0.979761},{0.850214,0.818309,0.397074,-0.372059}}},{{{0.803316,-0.659538,-1.987864,-0.186366},{-0.259213,0.315848,-0.427898,0.326521},{-0.168181,-0.620898,0.562309,0.722064},{-1.949690,0.307720,-0.147760,0.603492}},{{0.898339,0.986228,0.724530,0.105193},{0.066046,0.037689,-0.553543,0.597864},{0.296553,0.165199,0.500125,-0.395978},{0.790120,-1.873361,0.354841,-0.187812}},{{-0.559746,0.357012,0.373903,-0.113564},{-0.671918,-0.919720,0.258328,-0.283453},{0.008365,0.597272,0.355827,0.391287},{0.355297,-0.631888,0.221383,1.448221}},{{0.259199,-0.491776,0.721151,0.391427},{0.494000,0.652814,-0.153306,-0.615687},{0.142167,-0.601161,0.281702,0.563390},{0.904019,1.284241,0.901663,0.244620}}},{{{-0.664638,-0.564596,0.839897,0.153358},{-0.506883,0.822337,-0.974957,-0.098112},{-0.962870,-0.274566,0.418039,-0.020525},{-0.965969,0.954587,-0.250493,-0.031592}},{{-0.966475,0.455338,0.868491,0.723032},{-0.002141,0.021922,-0.131429,-0.601106},{-1.240003,1.483318,1.612920,-0.653210},{-0.505979,0.005588,-0.087506,-0.705789}},{{-0.203137,0.765652,-0.132974,-0.900534},{0.731132,0.133467,-1.086363,0.600763},{1.795911,-0.411613,-1.990494,0.405937},{0.729332,-0.119175,-0.979213,0.362346}},{{-0.049014,0.228577,-1.728796,-0.898348},{-0.540969,1.245881,-0.820859,0.285859},{0.430751,-0.373652,0.034535,0.434466},{0.365354,0.243261,0.910114,1.497873}}}}
};
float eval_polynomial(float variables[4],int program_index,int variable_index,int indices[4]){
    if(variable_index==4)return program[program_index][indices[0]][indices[1]][indices[2]][indices[3]];
    float result=0,base=1;
    for(int power=0;power<4;++power){
        indices[variable_index]=power;
        result+=base*eval_polynomial(variables,program_index,variable_index+1,indices);
        base*=variables[variable_index];
    }
    return result;
}
int main(int argc,char *argv[]){
    srand(tick_count());
    rand();
    float variables[4],probability[5],total=0;
    int i,indices[4],temp;
    for(i=0;i<4;++i){
        sscanf(argv[i-4+argc],"%d",&temp);
        variables[i]=temp;
    }
    temp=variables[1];
    variables[1]=variables[2];
    variables[2]=temp;
    if(variables[1]==0){ //bow if our honour is 0
        putchar('B');
        return 0;
    }

    variables[0]/=20;variables[2]/=20;
    variables[1]=1/(variables[1]+1);variables[3]=1/(variables[3]+1);
    for(i=0;i<5;++i){
        probability[i]=eval_polynomial(variables,i,0,indices);
        if(probability[i]<0)probability[i]=0;
        total+=probability[i];
        probability[i]=total;
    }
    total*=(float)rand()/RAND_MAX;
    for(i=0;i<5;++i)if(total<probability[i]){
        putchar("BGIPO"[i]);
        return 0;
    }
    putchar('B');
    return 0;
}

[1] Абсолютно неуместное число [2] Гарантировано, что оно верно в 1% случаев


YAGMCSE

Методы Монте-Карло, кажется, демонстрируют достойную игру, так что вот еще один универсальный вход в симуляцию Монте-Карло!

В отличие от большинства других записей в этом конкурсе, эта запись использует большое количество симуляций случайных игр и, следовательно, требует использования флага -O3 для оптимальной производительности.

Скомпилируйте программу с помощью команды: gcc monte.c -o monte -O3 -std = c99

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

#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

const int turn_limit=500;
enum Move{
    WAIT,BOW,GUARD,QUICK,PARRY,OVERHEAD
};
struct Player{
    int health,honour;
    enum Move lastMove;
};
typedef struct Player Player;
//<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>
//<command> <your_health> <enemy_health> <your_honour> <enemy_honour>
int damage_table[6][6][2]={
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is waiting
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is bowing
    {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, //P1 is guarding
    {{0,1},{0,1},{0,0},{0,0},{1,0},{0,1}}, //P1 is using quick draw
    {{0,1},{0,1},{0,0},{0,1},{0,0},{1,0}}, //P1 is parrying
    {{0,1},{0,1},{0,0},{1,0},{0,1},{0,0}} //P1 is using overhead attack
};
enum Move decode_move(char x){
    switch(x){
        case 'W': return WAIT; break;
        case 'B': return BOW; break;
        case 'G': return GUARD; break;
        case 'I': return QUICK; break;
        case 'P': return PARRY; break;
        case 'O': return OVERHEAD; break;
    }
    return WAIT;
}
struct SimulationStat{
    enum Move first_me_move;
    int win,draw,lose,compound;
};
int stat_compare(const void*a,const void*b){
    return ((struct SimulationStat*)b)->compound-((struct SimulationStat*)a)->compound;
}
struct SimulationStat monte_carlo(int num_iters,enum Move first_me_move,Player original_me,Player original_opponent){
    struct SimulationStat simulation_result={first_me_move,0,0,0};

    for(int iter=0;iter<num_iters;++iter){
    Player me=original_me,opponent=original_opponent;
        int turn,game_result;
        for(turn=0;turn<turn_limit;++turn){
            enum Move me_move,opponent_move=rand()%(OVERHEAD-BOW+1)+BOW;
            if(turn==0)me_move=first_me_move;
            else me_move=rand()%(OVERHEAD-BOW+1)+BOW;

            //update honour for guarding
            if(me.lastMove==GUARD&&me_move==GUARD)--me.honour;
            if(opponent.lastMove==GUARD&&opponent_move==GUARD)--opponent.honour;

            int me_attacking=me_move==QUICK||me_move==PARRY||me_move==OVERHEAD,opponent_attacking=opponent_move==QUICK||opponent_move==PARRY||opponent_move==OVERHEAD;

            //update health of players
            me.health-=damage_table[me_move][opponent_move][0]*(1+(opponent.honour>=7));
            opponent.health-=damage_table[me_move][opponent_move][1]*(1+(me.honour>=7));

            //update honour for attacking (Sword of the Gods is revoked after the player attacks with an original honour value of 7)
            if(me_attacking)--me.honour;
            if(opponent_attacking)--opponent.honour;

            //printf("%d %d\n",me.health,me.honour);
            //printf("%d %d\n",opponent.health,opponent.honour);

            //check if any of the terminating conditions are met
            //c. both players fall off the graces of the gods (me.honour<0&&opponent.honour<0)
            if(me.honour<0&&opponent.honour<0){
                game_result=0; //draw
                break;
            }
            //a. player 1 falls off the graces of the gods (me.honour<0)
            else if(me.honour<0){
                game_result=-1; //loss
                break;
            }
            //b. player 2 falls off the graces of the gods (opponent.honour<0)
            else if(opponent.honour<0){
                game_result=1; //win
                break;
            }
            //d. both players are dead (me.health<0&&opponent.health<0)
            else if(me.health<0&&opponent.health<0){
                game_result=0; //draw
                break;
            }
            //e. player 1 is dead (me.health<0)
            else if(me.health<0){
                game_result=-1; //loss
                break;
            }
            //f. player 2 is dead (opponent.health<0)
            else if(opponent.health<0){
                game_result=1; //win
                break;
            }
        }
        //both players get struck down by the guards for being boring
        if(turn==turn_limit)game_result=0; //draw

        if(game_result==1)++simulation_result.win;
        else if(game_result==0)++simulation_result.draw;
        else ++simulation_result.lose;
    }
    return simulation_result;
}
int main(int argc,char*argv[]){
    //const int num_iters=200000,num_shortlist_iters=1000000;
    const int num_iters=20000,num_shortlist_iters=55000;

    srand(tick_count());
    Player me,opponent;
    if(argc==5){
        sscanf(argv[1],"%d",&me.health);
        sscanf(argv[2],"%d",&opponent.health);
        sscanf(argv[3],"%d",&me.honour);
        sscanf(argv[4],"%d",&opponent.honour);
        me.lastMove=WAIT;
        opponent.lastMove=WAIT;
    }else{
        sscanf(argv[3],"%d",&me.health);
        sscanf(argv[4],"%d",&opponent.health);
        sscanf(argv[5],"%d",&me.honour);
        sscanf(argv[6],"%d",&opponent.honour);
        me.lastMove=decode_move(argv[1][strlen(argv[1])-1]);
        opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]);
    }

    struct SimulationStat results[6];
    results[0].first_me_move=WAIT;
    results[0].win=0;
    results[0].draw=0;
    results[0].lose=num_iters;
    results[0].compound=-num_iters*2-1000; //waiting is worse than any other action

    for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){
        results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent);
        struct SimulationStat *cur=&results[first_me_move];
        cur->compound=cur->win*4+cur->draw*1-cur->lose*2;
    }
    qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare);

    for(int i=0;i<OVERHEAD-BOW+1;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound);
    }

    for(int i=0;i<2;++i){
        results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent);
        struct SimulationStat *cur=&results[i];
        cur->compound=cur->win*2+cur->draw*1;
    }
    qsort(results,2,sizeof(*results),stat_compare); 

    for(int i=0;i<2;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound);
    }
    putchar("WBGIPO"[results[0].first_me_move]);
    return 0;
}

1
Кажется, он только склоняется по какой-то причине. Возможно, вы захотите взглянуть
C5H8NNaO4

@ C5H8NNaO4 Спасибо, что сообщили мне об этой серьезной ошибке. Моя редакция должна исправить ошибку.
Картофель

YAGMCSE, кажется, делает только GBWWWWW...илиBWWWW
C5H8NNaO4

@ C5H8NNaO4 Это странно. Я не могу воспроизвести результаты, которые вы упомянули. Противник YAGMCSE постоянно кланялся / охранял / ждал?
Картофель

Да, он кланялся первые 7 раундов. Вот Pastebin
C5H8NNaO4

1

После моей неудачной попытки войти в Target Dummy, я представляю вам моего следующего бота ...

ScroogeBot - Python 2

Этот бот склонится, если у него будет одна честь. В противном случае он подбросит монету.

Если он приземлится на головы, он выполнит случайную атаку. Если он приземлится на хвосты, он будет либо кланяться, либо охранять.

Команда: python scroogebot.py

import random, sys
# If he has more than one honor...
if int(sys.argv[5]) > 1:
    #Flip a coin.
    coin = random.choice(['heads','tails'])
    #If the coin lands on heads...
    if coin == 'heads':
        #Attack!
        print random.choice(['I','O','P'])
    #If the coin lands on tails...
    else:
        #Don't attack!
        print random.choice(['G','B'])
#If he has 1 honor...
else:
    #Bow!
    print "B"

Уу, новая запись! Просто быстрое прояснение ситуации - может пройти некоторое время, прежде чем я смогу настроить новый турнир, так как вчера я переоборудовал свою операционную систему. Я должен закончить новый турнир с вашими результатами к концу недели.
абсент

0

Ёсимицу (JS)

Попытки не получить охрану, проверив последние два хода, получат храбрость с большей честью. на основе шаблона сделаны апсиллеры

var attacks = ['I','P','O'];
var pasive = ['B','W'];
var argv = process.argv;
var playerHistory = argv.length>6?argv[2].split(''):[];
var enemyHistory = argv.length>6?argv[3].split(''):[];
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:playerHistory };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;

enemy.lastMove = enemyHistory.pop();
enemy.secondToLast = enemyHistory.pop();

enemy.didAttack = !!attacks.indexOf(enemy.lastMove);

my.lastMove = playerHistory.pop();

function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

chooseAnAttack = function(){ decide.apply(this,attacks); };

if( ( pasive.indexOf( enemy.lastMove ) && my.honor < 15 ) || (my.honor < 7 && enemy.health > 10) || my.honor === 1 ){
    if( Math.random * 15 < my.honor ){
        chooseAnAttack();
    } else {
        decide('B');
    }
} else if( enemy.honor < 2 ){
    chooseAnAttack();
} else if( enemy.didAttack ){

    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }

} else if( enemy.lastMove = 'G' ) {
    chooseAnAttack();
} else if( enemy.lastMove === 'W' ){
    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }
}

0

Дурак (С)

Дурак предлагает довольно ошибочную стратегию, никогда не повторяя один и тот же ход дважды, если только его не принуждают из-за отсутствия чести. Его движения в значительной степени основаны на случайности, что затрудняет прогнозирование его действий. Его благосостояние - последнее, что у него на уме, так как его мысли сосредоточены только на кровопролитии и окончательной победе

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

const char commands[] =
{
    'W', 'B', 'G', 'I', 'P', 'O'
};

char select_candidate(const char c[])
{
    unsigned i = 0;
    int n_candidates = 0;
    char candidates[sizeof(commands)];

    for (; i < sizeof(commands); i++)
        if (c[i])
            candidates[n_candidates++] = c[i];

    /* There are no candidates for actions, so the fool blindly attacks his opponent, hoping for the best */
    return n_candidates == 0 ? 'I' : candidates[rand() % n_candidates];
}

int main(int argc, char *argv[])
{
    unsigned i = 0;
    int honour;
    char candidates[sizeof(commands)];
    char last_action;

    srand(time(NULL));

    memcpy(candidates, commands, sizeof(commands));

    /* It's the first round, the fool selects a random action except for waiting */
    if (argc != 7)
    {
        candidates[0] = 0;
        putchar(select_candidate(candidates));
        return 0;
    }

    last_action = argv[1][strlen(argv[1]) - 1];
    honour = atoi(argv[5]);

    if (honour == 0)
    {
        /* The fool realises he will meet his doom if he performs any of the following moves */
        /* and removes them from his list of possible actions */
        candidates[3] = 0;
        candidates[4] = 0;
        candidates[5] = 0;

        /* Only omit the blocking action if the last action was blocking */
        if (last_action == 'G')
            candidates[2] = 0;
    } else if (honour >= 7) {

        /* If the fool has the opportunity to abuse power, he will */
        candidates[0] = 0;
        candidates[1] = 0;
    }

    /* However unintellegent, the fool decides never to repeat the same move twice */
    for (; i < sizeof(commands); i++)
    {
        if (candidates[i] == last_action)
        candidates[i] = 0;
    }

    /* The fool randomly selects a possible action and hopes for the best */
    putchar(select_candidate(candidates));

    return 0;
}


Пророк (С)

Пророк использует знание предыдущих двух ходов своего противника, чтобы предсказать его следующий ход и обеспечивает быструю и смертельную контратаку. Также он занимается астрологией и прочим.

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

int main(int argc, char* argv[])
{
    char* hist;
    char* enemy_hist;
    int hist_len;
    int enemy_hist_len;
    int health;
    int enemy_health;
    int honour;
    int enemy_honour;

    if (argc != 7)
    {
        /* Always start with guarding */
        putchar('G');
        return 0;
    }

    srand(time(NULL));

    /* Grab the command-line values */
    hist         = argv[1];
    enemy_hist   = argv[2];
    health       = atoi(argv[3]);
    enemy_health = atoi(argv[4]);
    honour       = atoi(argv[5]);
    enemy_honour = atoi(argv[6]);

    hist_len = strlen(hist);
    enemy_hist_len = strlen(enemy_hist);

    /* Looks like the enemy is starving for honour. */
    /* This means that they have to bow, so attack them,  */
    /* But only if we have the honour to do so. */
    if (enemy_honour == 0 && honour > 0)
    {
        putchar('O');
        return 0;
    } else if (honour == 0) {
        /* We have to bow */
        putchar('B');
        return 0;
    } else if (honour <= 3) {
        /* We have low honour, attack if the enemy has no honour, otherwise bow to restore some of our honour */
        putchar(enemy_honour == 0 ? ((rand() % 2) ? 'I' : 'O') : 'B');
        return 0;
    }

    switch (enemy_hist[enemy_hist_len - 1])
    {
        /* The enemy has previously performed a passive action, so they will likely attack this round */
        case 'W':
        case 'B':
        case 'G':
            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G'); /* Protect ourselves, using `guard` if we did not use it last turn */
            return 0;

        default:
            if (enemy_hist_len >= 2)
            {
                switch (enemy_hist[enemy_hist_len - 2])
                {
                    case 'I':
                    case 'P':
                    case 'O':
                        /* The enemy has attacked for the last 2 turns, they will likely rest now */
                        putchar((rand() % 2) ? 'I' : 'O');
                        return 0;

                    default:
                        /* Low health, block an incoming attack */
                        if (health <= 5)
                        {
                            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G');
                            return 0;
                        } else {
                            /* Choose randomly to bow or attack */
                            int decision = rand() % 3;
                            putchar(decision == 2 ? 'B' : decision == 1 ? 'I' : 'O');
                            return 0;
                        }
                }
            } else {
                /* Attack! */
                putchar((rand() % 2) ? 'I' : 'O');
                return 0;
            }
    }

    /* If somehow we get to this point, parry */
    putchar('P');
    return 0;
}


компиляция

Обе программы написаны на C и могут быть скомпилированы с gcc:

gcc fool.c -o fool
gcc prophet.c -o prophet


Бег

* Никс

./fool <args>
./prophet <args>

Windows

fool.exe <args>
prophet.exe <args>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.