КОТ: Всесвітня пандемія


82

Остаточні результати тут!

Вступ

У 2042 році світ перенаселений. Глобалізація, переповненість, новий спосіб життя та глобальна відсутність гігієни спричинили поширення нової пандемії. У ті важкі часи державним керівникам доводилося керувати ситуацією. Ви не можете дозволити вашому населенню знищити, але, можливо, ви могли б отримати користь, відпустивши своїх сусідів на смерть ...

Глосарій

Здорові : Люди не інфіковані
Заражені : Люди , які можуть померти від пандемія
Мертвого : не брати до уваги тіла, ніякого особливого ефекту (тільки забили)
Зараження Оцінити : Кількість здорового , хто стане Infected кожного повороту
Зараження Оцінити : Відсоток Infected , який буде конвертувати Healthy в Infected кожен поворот
летальність Частота : Відсоток Infected , які вмирають кожен хід
міграції Швидкість : Відсоток як здоровий і Infected , що емігрують / іммігрувати кожен поворот
Local: Зачіпає лише ваш штат
Глобальний : впливає на кожен штат

Принцип

Кожен з гравців керуватиме одним містечком, починаючи з 100 людей . На жаль, серед них одна заражена .

Гра покрокова. Поворот складається з семи фаз , остання - інтерактивна (прохання ботів про команду). Порядок гравців рандомізований на кожному кроці. Наступна фаза починається, коли попередній етап виконується в кожному місті (Поворот 1: Гравець 1, Гравець 2, Гравець 3 ...; Поворот 2: Гравець 3, Гравець 2, Гравець 1 ...):

1. Mutation                                 - AUTOMATED
2. Reproduction                             - AUTOMATED
3. Migration                                - AUTOMATED
4. Infection                                - AUTOMATED
5. Contagion                                - AUTOMATED
6. Extinction                               - AUTOMATED
7. Players Turn                             - INTERACTIVE

Контролер надає вам введення через аргументи команд, і ваша програма повинна виводити через stdout.

Синтаксис

Вхідні дані

Щоразу, коли ваша програма викликається, вона отримуватиме аргументи у такому форматі:

Round;YourPlayerId;PlayerId_Healthy_Infected_Dead_InfectionRate_ContagionRate_LethalityRate_MigrationRate;PlayerId_Healthy_Infected_Dead_InfectionRate_ContagionRate_LethalityRate_MigrationRate;...

Круглі є 1-індексованими.

Приклад введення

6;2;1_106_23_9_2_4_13_5;0_20_53_62_16_20_35_5;2_20_53_62_16_20_35_5

Тут ви бачите, що це 6-й раунд, і ви граєте 2. У вас 20 здорових, 53 заражених, 62 загиблі, 16% рівень зараження, 20% рівень зараження, 35% летальності та 5% міграції.

Вихідні дані

Ви повинні вивести три символи (ні пробілу, ні роздільника), кожен з яких відповідає одній дії, яку ви зробите в цьому рубежі. Порядок символів визначає порядок дій. Ви можете виводити одні й ті самі дії кілька разів.

N: Do N ичто
M: Research M icrobiology [Ефекти: Зниження місцевої інфекції Оцінити на 4%]
E: Дослідження E pidemiology [Ефекти: Знизити місцеву заразу Оцінити на 8%]
I: Дослідженнях I mmunology [Ефекти: Знизити місцеве летальність Оцінити на 4%]
V: дослідження V accination [ефекти: Зниження місцевої інфекції Оцінити один, зменшити місцеві зарази Оцінити на 4%, знизити місцеву летальність Оцінити на 2%]
C: Дайте C Юр [ефекти: Перетворення 10 місцеві Заражений до здорового ]
Q: Q uarantine [Ефекти: Видалити 30 місцеві Заражені ]
O: Про пере Межі [Ефекти: збільшення місцевої швидкості міграції на 10%]
B: Закрити B замовлень [Ефекти: Зниження місцевої швидкості міграції на 10%]
T: Bio T errorism [Ефекти: Преобразованіе- глобальний Healthy до Infected ]
W: W eaponization [ефекти: збільшення глобальної інфекції Оцінити на 1, збільшення глобальної летальність Rate на 2%]
D: D issemination [ефекти: збільшення глобальної інфекції Оцінитина 1, збільшити глобальний рівень зараження на 2%]
P: P acification [Ефекти: Зменшити глобальний рівень зараження на 1, зменшити глобальний рівень зараження на 1%, зменшити глобальний рівень летальності на 1%]

Ігровий процес

Усі фази

Недійсна команда =
Відсоток нічого не додається, як цілі числа, тобто 10% - 4% = 6%. Коли відсоток застосовується у формулі, результат формується у формі.

Фаза 1: Мутація

Пандемія стає все більш сильною. Кожен поворот він випадковим чином отримує один з цих атрибутів (ця мутація впливає на всіх гравців відразу):

  • Збільшити глобальний рівень зараження на 2
  • Збільшити глобальний рівень зараження на 5%
  • Збільшити глобальний рівень летальності на 5%

Фаза 2: Розмноження

Кожні п’ять турів (5, 10, 15…) народжуватимуться нові громадяни. Кожна пара здорових зробить один здоровий (23 здорових генерують 11 нових здорових ). Кожна пара заражених зробить одного зараженого .

Фаза 3: Міграція

З кожним кроком відсоток здорових та інфікованих залишатиме штати, залежно від рівня міграції (10 здорових залишать стан зі 100 здоровим та 10% міграційним рівнем ). Потім мігранти будуть розподілені між кожною державою, ще раз залежно від рівня міграції . (Ставки кожної держави зважуються, а мігранти потім усі розподіляються відповідно).

Фаза 4: Інфекція

Здорові кожної держави перетворюються на інфікованих , відповідно до рівня інфікування .

Фаза 5: Зараження

Здорові кожної держави перетворюються на інфіковані , відповідно до рівня зараження . Кількість обчислюється шляхом множення заражених на швидкість зараження .

6 фаза: вимирання

Заражені перетворюються на мертвих , відповідно до коефіцієнта летальності . Кількість обчислюється шляхом множення зараженого на коефіцієнт летальності .

Фаза 7: Гравці чергують

Кожен гравець отримує вхід і повинен виводити три дії, які виконуються в порядку їх виведення.

Правила

  • Ботів не слід писати, щоб бити або підтримувати конкретних інших ботів.
  • Запис у файли дозволяється. Будь ласка, напишіть на "tvojeubmissionname.txt", папка буде видалена перед початком гри. Інші зовнішні ресурси заборонені.
  • На ваше подання є одна секунда для відповіді (на місто)
  • Укажіть команди для складання та запуску подань.

Перемога

Переможець - найздоровіший після 50 турів. Якщо гравець останній живий (більше 0 здорових чи заражених ), гра припиняється і він виграє. Якщо декілька гравців мають однакову кількість здорових , виграє той , у кого найбільше заражених , а той, у якого менше мертвих .

Контролер

Ви можете знайти контролер на GitHub . Він також містить три вибірки, написані на Java.
Щоб запустити його, перегляньте проект та відкрийте його у вашій Java IDE. Точка входу в mainметод класу Game. Потрібна Java 8.

Щоб додати ботів, спочатку вам потрібна або компільована версія для Java (файли .class), або джерела для інтерпретованих мов. Розмістіть їх у кореневій папці проекту. Потім створіть новий playersпакет Java в пакеті (ви можете взяти приклад для вже наявних ботів). Цей клас повинен реалізовувати Playerдля зміни способу String getCmd(). Рядок, що повернувся - це команда оболонки для запуску ваших ботів. Наприклад , ви можете зробити бот роботу Ruby , з допомогою цієї команди: return "C:\Ruby\bin\ruby.exe MyBot.rb";. Нарешті, додайте бота в playersмасив у верхній частині Gameкласу.

Остаточні результати (04.03.2016 08:22 GMT)

Глобальний (100 репутації):

Результати 100 ігор: http://pasted.co/942200ff

1. EvilBot (24, 249, 436)
2. Triage (23, 538, 486)
3. WICKED (23, 537, 489)
4. Israel (23, 40, 240)
5. InfectedTown (22, 736, 482)
6. ZombieState (22, 229, 369)
7. Mooch (22, 87, 206)
8. InfectedHaven (21, 723, 483)
9. Crossroads (16, 9, 136)
10. TheKeeper (3, 4, 138)
11. Terrorist (0, 595, 496)
12. InfectionBot (0, 511, 430)
13. FamilyValues (0, 6, 291)
14. UndecidedBot (0, 0, 20)
15. XenoBot (0, 0, 26)
16. Researcher (0, 0, 33)
17. Strategist (0, 0, 42)
18. TheCure (0, 0, 55)
19. Socialist (0, 0, 67)
20. TrumpBot (0, 0, 77)
21. CullBot (0, 0, 81)
22. BackStabber (0, 0, 87)
23. BlunderBot (0, 0, 104)
24. RemoveInfected (0, 0, 111)
25. PFC (0, 0, 117)
26. BioterroristBot (0, 0, 118)
27. PassiveBot (0, 0, 118)
28. Smaug (0, 0, 118)
29. WeaponOfMassDissemination (0, 0, 119)
30. AllOrNothing (0, 0, 121)
31. Obamacare (0, 0, 122)
32. DisseminationBot (0, 0, 123)
33. CureThenQuarantine (0, 0, 125)
34. Madagascar (0, 0, 129)
35. OpenAndClose (0, 0, 129)
36. ThePacifist (0, 0, 130)
37. MedicBot (0, 0, 131)
38. Medic (0, 0, 133)
39. Salt (0, 0, 134)
40. Piecemeal (0, 0, 136)
41. Graymalkin (0, 0, 137)
42. PureBot (0, 0, 140)
43. MadScienceBot (0, 0, 144)
44. BipolarBot (0, 0, 149)
45. RedCross (0, 0, 151)

Без судинного дня (200 репутації):

Результати 100 ігор: http://pasted.co/220b575b

1. FamilyValues (5708, 14, 2)
2. BlunderBot (5614, 12, 3)
3. Graymalkin (5597, 17, 4)
4. PureBot (5550, 12, 5)
5. Crossroads (5543, 11, 4)
6. Salt (5488, 24, 7)
7. CureThenQuarantine (5453, 13, 7)
8. Piecemeal (5358, 121, 23)
9. TrumpBot (5355, 12, 5)
10. CullBot (5288, 12, 9)
11. AllOrNothing (5284, 13, 10)
12. Madagascar (5060, 180, 35)
13. TheKeeper (4934, 165, 44)
14. WICKED (4714, 25, 5)
15. Strategist (2266, 25, 5)
16. BackStabber (2180, 1327, 596)
17. RemoveInfected (2021, 33, 27)
18. OpenAndClose (1945, 667, 394)
19. Triage (1773, 401, 80)
20. TheCure (1465, 46, 26)
21. Obamacare (1263, 525, 247)
22. Mooch (1103, 546, 269)
23. Israel (1102, 580, 292)
24. RedCross (1086, 1700, 727)
25. ThePacifist (1069, 636, 580)
26. Researcher (1035, 113, 37)
27. UndecidedBot (825, 219, 93)
28. PassiveBot (510, 990, 567)
29. MedicBot (411, 1474, 667)
30. Medic (392, 1690, 619)
31. Socialist (139, 63, 90)
32. XenoBot (0, 82, 170)

Дякую всім за участь. Я сподіваюся, що ви так само добре розробляли і кодували своїх ботів, як і я, що я керував цією грою.


9
Чи можемо ми отримати команду E xecute, яка вбиває X кількості заражених (перетворюючи їх прямо на мертвих)? Напевно, не життєздатний метод перемоги, але дія, яка здається законною. Якщо тільки це не робить карантин (незрозуміло).
Draco18s

3
Швидка примітка граматики: "Здоровий" означає "психічно стійкий"; слово, яке ви (напевно) шукаєте тут, - «здоровий». (Чи правильно я здогадуюсь, що ваша перша мова - іспанська, де "sano" означає "здоровий", або щось тісно пов'язане?)
Мейсон Уілер

5
@MasonWheeler причіпки термінології Примітка: Ваша записка була термінологія або словниковий запас примітка як не було граматики не бере;)
Jan

3
@Thrax Наразі обробка поворотів (рандомізована на старті, з того самого порядку після цього) дає гравцям, які приходять пізніше в черзі, величезну перевагу, що робить кінцевий результат дивовижним варіантом. Можливо, якщо ви або 1) рандомізували порядок чергування кожного раунду, або 2) змусили кожного переглядати однаковий стан під час своєї черги і застосувати зміни до всіх одночасно в кінці раунду, тоді результати можуть бути більш збалансованими та базуватися на них докладніше про якість подання. Я перевірив перший варіант, і результати набагато послідовніші.
Mwr247

7
@Thrax Зараз існує надмірна кількість ботів, які існують просто для того, щоб "знищити світ". Незважаючи на те, що це може бути цікавим викликом, це бот, який насправді намагається змагатись, вже не може ефективно протистояти йому, і ми залишаємося з тим, що боти запрограмовані на "Cure X 3" в кінці як переможці. Я хотів би запропонувати змінити правила, де для того, щоб вважатись за КОТХ, боти повинні бути принаймні здатними закінчуватись позитивними "розумами" в матчі 1 на 1 проти PassiveBot? Завдання є веселішим, коли стратегії насправді мають ефект.
Mwr247

Відповіді:


12

Сімейні цінності, вузол (ES6)

// Process input
var data = process.argv[2].split(';');
var round = data.shift()*1;
var id = data.shift()*1;
var playerCount = data.length;
var local = data.find(function(v) {
  return !v.indexOf(id+'_')}
).split('_');
local = {
  sane: local[1]*1,
  infected: local[2]*1,
  dead: local[3]*1,
  infectionRate: local[4]*1,
  contagionRate: local[5]*1,
  lethalityRate: local[6]*1,
  migrationRate: local[7]*1
};

// Determine response
var response = [];
for(var i=0;i<3;i++) {
  var model = {
    M: local.infectionRate,
    E: local.contagionRate * (local.sane > 0 ? 1 : 0.5),
    I: local.lethalityRate * (round > 45 ? 0 : local.sane > 0 ? 1 : 2),
    V: (local.infectionRate/4 + local.contagionRate/2 + local.lethalityRate/2) * (round > 45 ? 0 : 1),
    C: local.infected / Math.max(local.infectionRate, 1) * (round > 48 ? round : local.infectionRate + local.contagionRate/100 * local.infected < (3 - i) * 10 ? 1 : 0),
    B: local.migrationRate * 10
  };
  var max = 'M';
  for(k in model) {
    if (model[k] > model[max] ) {
      max = k;
    } else if(model[k] == model[max]) {
      max = [max, k][Math.random()*2|0];
    }
  }
  response.push(max);

  // Refactor priorities
  if(max == 'M') {
    local.infectionRate -= 4;
  } else if(max == 'E') {
    local.contagionRate -= 8;
  } else if(max == 'I') {
    local.lethalityRate -= 4;
  } else if(max == 'V') {
    local.infectionRate -= 1;
    local.contagionRate -= 4;
    local.lethalityRate -= 2;
  } else if(max == 'C') {
    local.infected -= 10;
  } else if(max == 'B') {
    local.migrationRate -= 10;
  }
}

// Respond with actions
process.stdout.write(response.join(''));

Сімейні цінності зосереджуються на самозбереженні та захисті, і лише виконує дії з цією метою. Він використовує систему крапкових значень для визначення найкращого курсу дій, а потім коригує власні значення статусу, щоб краще визначити наступний пріоритет. У разі вирівнювання, він випадковим чином вибирає з числа кращих варіантів.

РЕДАКТУВАННЯ: Здається, поки що все добре:

    ********** FINISH **********
    1. FamilyValues (1143, 0, 188)
    2. Triage (582, 0, 158)
    3. Researcher (281, 0, 142)
    4. Madagascar (149, 0, 162)
    5. Mooch (148, 0, 331)
    6. MedicBot (142, 0, 161)
    7. Medic (66, 65, 211)
    8. XenoBot (0, 0, 22)
    9. WMDbot (0, 0, 218)
    10. PassiveBot (0, 0, 221)
    11. BioterroristBot (0, 0, 221)
    12. MadScienceBot (0, 0, 221)
    13. DisseminationBot (0, 0, 221)
    14. TheCure (0, 0, 222)

Пасіфіст, Вузл

// Process input
var data = process.argv[2].split(';');
var round = data.shift()*1;

// Respond with actions
process.stdout.write(round == 1 ? 'OOO' : 'PPP');

З великою концентрацією уваги на вбивствах та смерті, Пасіфіст вважає, що міцне глобальне здоров'я означає міцне місцеве здоров'я. Як такі, вони, як правило, зосереджуються лише на зменшенні глобальних захворювань, залишаючи кордони частково відкритими, щоб добро поширилося навколо.


Нічого собі, я не очікував, що TheCure буде останньою
половина

@justhalf З цим безліччю гравців всі вони в кінці рухаються багато на дошках: просто пробігли одного, де TheCure опинився на третьому місці. І FamilyValues, і Triage майже завжди в перших двох, і FV отримує №1 більшу частину часу.
Mwr247

Гм, сама задача детермінована, правда? Так це пов’язано з тим, що деякі гравці вкладають випадковість у свій алгоритм?
justhalf

@justhalf Найбільшим фактором на сьогоднішній день, здається, є порядок чергувань, який рандомізований (але однаковий для кожного раунду в грі). Якщо ви будете першими, це означає, що ви не маєте шансу реагувати на дії кожного під час поточного розвороту, тоді як, коли ви пройдетеся останнім, ви зможете найкраще налаштуватись на те, що зробили з вами інші гравці.
Mwr247

1
@justhalf Я щойно перевірив модифікований контролер, який рандомізує порядок повороту для кожного раунду, і зараз результати набагато послідовніші.
Mwr247

27

TrumpBot

private void sleep(String[] args) {

    round = Integer.parseInt(args[0]);
    thisTownID = Integer.parseInt(args[1]);

    states = new ArrayList<>();
    //states.add(new State(args[thisTownID+2]));

    otherStates = new ArrayList<>();


    for (int i = 2; i < args.length; i++){
        states.add(new State(args[i]));
    }

    for (State state : states){
        if (state.ownerId == thisTownID) {
            thisState = state;
        } else {
            otherStates.add(state);
        }
    }

    StringBuilder cmd = new StringBuilder();

    for (int j =0;j<3;j++){
        if (thisState.infected > 7) {
          if (thisState.infected > 25){
            cmd.append("Q");
            thisState.infected -= 30;
          }
          else {
            cmd.append("C");
            thisState.infected -= 10;
          }
        }
        else if (thisState.migrationRate > 2) {
          cmd.append("B");
          thisState.migrationRate -= 10;
        }
        else if (thisState.infectionRate > 4) {
          cmd.append("M");
          thisState.infectionRate  -= 4;
        }
        else if (thisState.contagionRate > 10 || thisState.lethalityRate > 6 || thisState.infectionRate > 0) {
          cmd.append("V");
          thisState.contagionRate  -= 4;
          thisState.lethalityRate  -= 2;
          thisState.infectionRate  -= 1;
        }

        else if (thisState.infected % 10 <= 6){
          cmd.append("T");
          thisState.infected +=4;
        }
        else cmd.append("V");
    }
    System.out.print(cmd.reverse());
}

Робить Америку чудовою, вилікувавши всіх заражених, якщо їх немає лише 2; меншини будуть ігноровані.

Якщо менше інфекцій, це ліки дешевше.

Не потребує іммігрантів - вони лише приносять інфекцію.

Якщо нічого не залишається робити, бомбардуйте інших гравців.

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

Редагувати: виправлено помилку, яка виліковувала б спам, оскільки кількість заражених після вилікування не знижувалася.

Трубопис

Дякую Дж. Аткіну за надання:

Make turn 4000000
As long as, turn larger than 1000000;:
If, refugee count > 2000000;: say "C"!
Else if, infectionRate > 200000;: say "M"!
Else if, immigration rate > 9000000;: say "B"!
Else: say "T"!
Make turn old turn - 1000000!
America is Great. 

14

AllOrNothing, R

args <- strsplit(commandArgs(TRUE),";")[[1]]
round <- as.integer(args[1])
me <- as.integer(args[2])
stats <- do.call(rbind,strsplit(args[-(1:2)],"_"))
stats <- as.data.frame(apply(stats,2,as.integer))
colnames(stats) <- c("id","Sane","Infected","Dead","InfRate","ContRate","LethRate","MigRate")
out <- ""
statme <- stats[stats$id==me,]
while(nchar(out)<3){
    if(round==1 & !nchar(out)){
        out <- paste0(out, "B")
    }else if(round%%5==4 & statme$Infected > 20){
        statme$Infected <- statme$Infected - 30
        out <- paste0(out, "Q")
    }else if(statme$Sane*statme$InfRate/100 >= 1){
        o <- ifelse(statme$Sane*statme$InfRate/100 < statme$Infected*statme$ContRate/100, "C", "M")
        if(o=="C") statme$Infected <- statme$Infected - 10
        if(o=="M") statme$InfRate <- statme$InfRate - 4
        out <- paste0(out, o)
    }else if(statme$Infected > 0){
        statme$Infected <- statme$Infected - 10
        out <- paste0(out, "C")
    }else if(median(stats$LethRate)<20){ 
        out <- paste0(out, "W")
    }else{
        out <- paste0(out, "E")     
    }
}
cat(substr(out,1,3))

Викликано користувачем Rscript AllOrNothing.R.

З одного боку, ідея полягає в тому, щоб обмежити максимальний ризик зараження (знизивши рівень зараження, вилікувавши інфікованих та запобігаючи імміграції інфікованих), а з іншого - збільшити летальність захворювання, щоб люди, які все-таки потрапили інфіковані, гинуть перед зараженням інших.

Редагувати: стратегія трохи налаштувала.


Добре, здається, це робить надзвичайно добре проти 21 інших держав!
Thrax

@Thrax Дійсно, хоча час від часу, під час деяких пробіжок, він все-таки виходить дуже вражаючим :) Але найчастіше це досягає успіху, як у вашому тестовому запуску.
планнапус

ось цілком дивовижний бот, гарна робота
Eumel

Це дуже схоже на стан, про який я збирався написати, коли знайшов час, якщо не тотожний. Моє існує тільки в моїй голові, хоча ("якщо 20 інфікованих, карантинуйте їх, якщо 10, вилікуйте їх тощо"), це гарна робота.
Draco18s

13

Медик

Медик завжди ... хвилювався , так би мовити, людьми без ліків. Він любить займатися медициною, тому це все, що він робить. Йому також подобаються пітони, тому він написав свій код у Python. Це все має сенс, якщо ви подумаєте про це. Ні, це насправді не так. Насправді, це ніби ...

from random import *
commands = ""
while len(commands) < 3:
    chance = random()
    if chance < .5: commands += "V"
    elif chance < .66: commands += "I"
    elif chance < .84: commands += "E"
    else: commands += "M"

print(commands)

Я тут, щоб допомогти.

Я тут, щоб допомогти.


4
Пітони, як у стрижні Асклепія? Або як у штаті Гермеса? Це може мати певний сенс ...
Не те, що Чарльз

3
Або! Обидва! Чому ні? Це все має сенс!
Conor O'Brien

7
++ 1; для TF2: D
кіт

11

Ліки

Це здається занадто спрощеним, але це також здається досить хорошим методом, щоб зменшити рівень зараженості / смертності. На кожному кроці виводиться MCQ:

  • Знизити рівень зараження
  • Вилікуйте інфікованих
  • Карантин деяких із заражених, що залишилися

Це воно!

public class TheCure{
    public static void main(String[]a){
        System.out.println("MCQ");
    }
}

Можливо, я міг би покращити це, вивівши більше M(або B), якщо в мене зараз немає зараження замість вилікування та карантину, але я хотів би побачити, наскільки добре це робиться спочатку. На жаль, одним із побічних ефектів опублікування першого є те, що важко оцінити ефективність:


9

ЗЛОЖЕНИЙ, Котлін

Пам’ятайте, WICKED - це добре.

package wicked

import java.util.*

fun clamp(value : Double, floor : Double, ceil : Double = Double.POSITIVE_INFINITY) = Math.max(Math.min(value, ceil), floor)
fun clamp(value : Int, floor : Int, ceil : Int = Integer.MAX_VALUE) = Math.max(Math.min(value, ceil), floor)

data class Player(
        val id            : Int,
        var healthy          : Int,
        var infected      : Int,
        var dead          : Int,
        var infectionRate : Int,
        var contagionRate : Double,
        var lethalityRate : Double,
        var migrationRate : Double)

class Game(val players : List<Player>) {

    fun doAction(playerId: Int, a: Char) {
        val player = players.first { it.id == playerId }
        with(player) {
            when (a) {
                'N' -> {}
                'M' -> infectionRate = clamp(infectionRate - 4, 0)
                'E' -> contagionRate = clamp(contagionRate - .08, 0.0, 1.0)
                'I' -> lethalityRate = clamp(lethalityRate - .04, 0.0, 1.0)
                'V' -> {
                    infectionRate = clamp(infectionRate - 1, 0)
                    contagionRate = clamp(contagionRate - .04, 0.0, 1.0)
                    lethalityRate = clamp(lethalityRate - .02, 0.0, 1.0)
                }
                'C' -> {
                    val cured = Math.min(infected, 10)
                    infected -= cured
                    healthy += cured
                }
                'Q' -> infected = clamp(infected - 30, 0)
                'O' -> migrationRate = clamp(migrationRate + .1, 0.0, 1.0)
                'B' -> migrationRate = clamp(migrationRate - .1, 0.0, 1.0)
                'T' -> {
                    players.forEach {
                        val infected = Math.min(it.healthy, 4)
                        it.healthy -= infected
                        it.infected += infected
                    }
                }
                'W' -> {
                    players.forEach {
                        it.infectionRate++
                        it.lethalityRate = clamp(it.lethalityRate + .02, 0.0, 1.0)
                    }
                }
                'D' -> {
                    players.forEach {
                        it.infectionRate++
                        it.contagionRate = clamp(it.contagionRate + .02, 0.0, 1.0)
                    }
                }
                'P' -> {
                    players.forEach {
                        it.infectionRate = clamp(it.infectionRate - 1, 0)
                        it.contagionRate = clamp(it.contagionRate - .01, 0.0, 1.0)
                        it.lethalityRate = clamp(it.lethalityRate - .01, 0.0, 1.0)
                    }
                }
                else -> throw IllegalArgumentException("Invalid action: $a")
            }
        }
    }

    fun copy() = Game(players.map { it.copy() })

    fun migration() {
        var migratingHealthy = 0
        var migratingInfected = 0
        var totalMigratingWeight = 0.0

        players.forEach {
            migratingHealthy += (it.healthy * it.migrationRate).toInt()
            migratingInfected += (it.infected * it.migrationRate).toInt()
            totalMigratingWeight += it.migrationRate

            it.healthy = (it.healthy * (1 - it.migrationRate)).toInt()
            it.infected *= (it.healthy * (1 - it.migrationRate)).toInt()
        }

        players.forEach {
            it.healthy += (migratingHealthy * it.migrationRate / totalMigratingWeight).toInt()
            it.infected += (migratingInfected * it.migrationRate / totalMigratingWeight).toInt()
        }
    }

    fun infection() {
        players.forEach {
            val infected = it.infectionRate //Allow negative healthy.
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun contagion() {
        players.forEach {
            val infected = (it.infected * it.contagionRate).toInt()
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun extinction() {
        players.forEach {
            val killed = (it.infected * it.lethalityRate).toInt()
            it.infected -= killed
            it.dead += killed
        }
    }

    operator fun get(playerId : Int) = players.first { it.id == playerId }

    fun calculateBenefit(action : Char, myId: Int) : Int {

        val copy1 = copy()
        copy1.doAction(myId, action)

        copy1.migration()
        copy1.infection()
        copy1.contagion()
        copy1.extinction()

        return copy1[myId].healthy
    }

}

fun main(args : Array<String>) {
    @Suppress("NAME_SHADOWING")
    val args = args[0].split(';')

    val round = args[0].toInt()
    val myId = args[1].toInt()

    val players : MutableList<Player> = ArrayList()

    for ( i in 2..args.size-1) {
        val data = args[i].split('_')
        players.add(Player(data[0].toInt(), data[1].toInt(), data[2].toInt(), data[3].toInt(), data[4].toInt(), data[5].toDouble() / 100, data[6].toDouble() / 100, data[7].toDouble() / 100))
    }

    val currentGame = Game(players)

    if (round == 50) {
        println("CCC")  //Extra 30 at end of game.
        return
    }

    for (i in 1..3) {
        val action = determineBestAction(currentGame, myId)
        currentGame.doAction(myId, action)
        print(action)
    }
}

fun determineBestAction(game : Game, myId : Int) : Char {

    if (game[myId].lethalityRate > .02) {        //Save the executives!!!
        return 'I'
    } else if (game[myId].lethalityRate > 0) {
        return 'V'
    }

    val bestAction = "NMEIVQCOBP".maxBy { game.calculateBenefit(it, myId) }!!

    return bestAction

}

Компілювати з: kotlinc WICKED.kt
Запустити з:kotlin wicked.WICKEDKt

ПФК, Котлін

Спроби звільнити хворобу у всіх.

package pfc

import java.util.*

fun clamp(value : Double, floor : Double, ceil : Double = Double.POSITIVE_INFINITY) = Math.max(Math.min(value, ceil), floor)
fun clamp(value : Int, floor : Int, ceil : Int = Integer.MAX_VALUE) = Math.max(Math.min(value, ceil), floor)

data class Player(
        val id            : Int,
        var healthy          : Int,
        var infected      : Int,
        var dead          : Int,
        var infectionRate : Int,
        var contagionRate : Double,
        var lethalityRate : Double,
        var migrationRate : Double)

class Game(val players : List<Player>) {

    fun doAction(playerId: Int, a: Char) {
        val player = players.first { it.id == playerId }
        with(player) {
            when (a) {
                'N' -> {}
                'M' -> infectionRate = clamp(infectionRate - 4, 0)
                'E' -> contagionRate = clamp(contagionRate - .08, 0.0, 1.0)
                'I' -> lethalityRate = clamp(lethalityRate - .04, 0.0, 1.0)
                'V' -> {
                    infectionRate = clamp(infectionRate - 1, 0)
                    contagionRate = clamp(contagionRate - .04, 0.0, 1.0)
                    lethalityRate = clamp(lethalityRate - .02, 0.0, 1.0)
                }
                'C' -> {
                    val cured = Math.min(infected, 10)
                    infected -= cured
                    healthy += cured
                }
                'Q' -> infected = clamp(infected - 30, 0)
                'O' -> migrationRate = clamp(migrationRate + .1, 0.0, 1.0)
                'B' -> migrationRate = clamp(migrationRate - .1, 0.0, 1.0)
                'T' -> {
                    players.forEach {
                        val infected = Math.min(it.healthy, 4)
                        it.healthy -= infected
                        it.infected += infected
                    }
                }
                'W' -> {
                    players.forEach {
                        it.infectionRate++
                        it.lethalityRate = clamp(it.lethalityRate + .02, 0.0, 1.0)
                    }
                }
                'D' -> {
                    players.forEach {
                        it.infectionRate++
                        it.contagionRate = clamp(it.contagionRate + .02, 0.0, 1.0)
                    }
                }
                'P' -> {
                    players.forEach {
                        it.infectionRate = clamp(it.infectionRate - 1, 0)
                        it.contagionRate = clamp(it.contagionRate - .01, 0.0, 1.0)
                        it.lethalityRate = clamp(it.lethalityRate - .01, 0.0, 1.0)
                    }
                }
                else -> throw IllegalArgumentException("Invalid action: $a")
            }
        }
    }

    fun copy() = Game(players.map { it.copy() })

    fun migration() {
        var migratingHealthy = 0
        var migratingInfected = 0
        var totalMigratingWeight = 0.0

        players.forEach {
            migratingHealthy += (it.healthy * it.migrationRate).toInt()
            migratingInfected += (it.infected * it.migrationRate).toInt()
            totalMigratingWeight += it.migrationRate

            it.healthy = (it.healthy * (1 - it.migrationRate)).toInt()
            it.infected *= (it.healthy * (1 - it.migrationRate)).toInt()
        }

        players.forEach {
            it.healthy += (migratingHealthy * it.migrationRate / totalMigratingWeight).toInt()
            it.infected += (migratingInfected * it.migrationRate / totalMigratingWeight).toInt()
        }
    }

    fun infection() {
        players.forEach {
            val infected = Math.min(it.healthy, it.infectionRate)
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun contagion() {
        players.forEach {
            val infected = Math.min(it.healthy, (it.infected * it.contagionRate).toInt())
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun extinction() {
        players.forEach {
            val killed = (it.infected * it.lethalityRate).toInt()
            it.infected -= killed
            it.dead += killed
        }
    }

    operator fun get(playerId : Int) = players.first { it.id == playerId }

    fun calculateBenefit(action : Char, myId: Int) : Int {

        val copy1 = copy()
        copy1.doAction(myId, action)

        copy1.migration()
        copy1.infection()
        copy1.contagion()
        copy1.extinction()

        return copy1.players.sumBy { it.infected }
    }

}

fun main(args : Array<String>) {
    @Suppress("NAME_SHADOWING")
    val args = args[0].split(';')

    @Suppress("UNUSED_VARIABLE")
    val round = args[0].toInt()
    val myId = args[1].toInt()

    val players : MutableList<Player> = ArrayList()

    for ( i in 2..args.size-1) {
        val data = args[i].split('_')
        players.add(Player(data[0].toInt(), data[1].toInt(), data[2].toInt(), data[3].toInt(), data[4].toInt(), data[5].toDouble() / 100, data[6].toDouble() / 100, data[7].toDouble() / 100))
    }

    val currentGame = Game(players)

    for (i in 1..3) {
        val action = determineBestAction(currentGame, myId)
        currentGame.doAction(myId, action)
        print(action)
    }
}

fun determineBestAction(game : Game, myId : Int) : Char {

    val bestAction = "NMEIVCQOBTWDP".maxBy { game.calculateBenefit(it, myId) }!!

    return bestAction

}

Компілювати з: kotlinc PFC.kt
Запустити з:kotlin pfc.PFCKt

Терорист, Котлін

Намагається зробити всіх людей мертвими.

package terrorist

import java.util.*

fun clamp(value : Double, floor : Double, ceil : Double = Double.POSITIVE_INFINITY) = Math.max(Math.min(value, ceil), floor)
fun clamp(value : Int, floor : Int, ceil : Int = Integer.MAX_VALUE) = Math.max(Math.min(value, ceil), floor)

data class Player(
        val id            : Int,
        var healthy          : Int,
        var infected      : Int,
        var dead          : Int,
        var infectionRate : Int,
        var contagionRate : Double,
        var lethalityRate : Double,
        var migrationRate : Double)

class Game(val players : List<Player>) {

    fun doAction(playerId: Int, a: Char) {
        val player = players.first { it.id == playerId }
        with(player) {
            when (a) {
                'N' -> {}
                'M' -> infectionRate = clamp(infectionRate - 4, 0)
                'E' -> contagionRate = clamp(contagionRate - .08, 0.0, 1.0)
                'I' -> lethalityRate = clamp(lethalityRate - .04, 0.0, 1.0)
                'V' -> {
                    infectionRate = clamp(infectionRate - 1, 0)
                    contagionRate = clamp(contagionRate - .04, 0.0, 1.0)
                    lethalityRate = clamp(lethalityRate - .02, 0.0, 1.0)
                }
                'C' -> {
                    val cured = Math.min(infected, 10)
                    infected -= cured
                    healthy += cured
                }
                'Q' -> infected = clamp(infected - 30, 0)
                'O' -> migrationRate = clamp(migrationRate + .1, 0.0, 1.0)
                'B' -> migrationRate = clamp(migrationRate - .1, 0.0, 1.0)
                'T' -> {
                    players.forEach {
                        val infected = Math.min(it.healthy, 4)
                        it.healthy -= infected
                        it.infected += infected
                    }
                }
                'W' -> {
                    players.forEach {
                        it.infectionRate++
                        it.lethalityRate = clamp(it.lethalityRate + .02, 0.0, 1.0)
                    }
                }
                'D' -> {
                    players.forEach {
                        it.infectionRate++
                        it.contagionRate = clamp(it.contagionRate + .02, 0.0, 1.0)
                    }
                }
                'P' -> {
                    players.forEach {
                        it.infectionRate = clamp(it.infectionRate - 1, 0)
                        it.contagionRate = clamp(it.contagionRate - .01, 0.0, 1.0)
                        it.lethalityRate = clamp(it.lethalityRate - .01, 0.0, 1.0)
                    }
                }
                else -> throw IllegalArgumentException("Invalid action: $a")
            }
        }
    }

    fun copy() = Game(players.map { it.copy() })

    fun migration() {
        var migratingHealthy = 0
        var migratingInfected = 0
        var totalMigratingWeight = 0.0

        players.forEach {
            migratingHealthy += (it.healthy * it.migrationRate).toInt()
            migratingInfected += (it.infected * it.migrationRate).toInt()
            totalMigratingWeight += it.migrationRate

            it.healthy = (it.healthy * (1 - it.migrationRate)).toInt()
            it.infected *= (it.healthy * (1 - it.migrationRate)).toInt()
        }

        players.forEach {
            it.healthy += (migratingHealthy * it.migrationRate / totalMigratingWeight).toInt()
            it.infected += (migratingInfected * it.migrationRate / totalMigratingWeight).toInt()
        }
    }

    fun infection() {
        players.forEach {
            val infected = Math.min(it.healthy, it.infectionRate)
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun contagion() {
        players.forEach {
            val infected = Math.min(it.healthy, (it.infected * it.contagionRate).toInt())
            it.healthy -= infected
            it.infected += infected
        }
    }

    fun extinction() {
        players.forEach {
            val killed = (it.infected * it.lethalityRate).toInt()
            it.infected -= killed
            it.dead += killed
        }
    }

    operator fun get(playerId : Int) = players.first { it.id == playerId }

    fun calculateBenefit(action : Char, myId: Int) : Int {

        val copy1 = copy()
        copy1.doAction(myId, action)

        copy1.migration()
        copy1.infection()
        copy1.contagion()
        copy1.extinction()

        return copy1.players.sumBy { it.dead }
    }

}

fun main(args : Array<String>) {
    @Suppress("NAME_SHADOWING")
    val args = args[0].split(';')

    @Suppress("UNUSED_VARIABLE")
    val round = args[0].toInt()
    val myId = args[1].toInt()

    val players : MutableList<Player> = ArrayList()

    for ( i in 2..args.size-1) {
        val data = args[i].split('_')
        players.add(Player(data[0].toInt(), data[1].toInt(), data[2].toInt(), data[3].toInt(), data[4].toInt(), data[5].toDouble() / 100, data[6].toDouble() / 100, data[7].toDouble() / 100))
    }

    if (round == 50) {
        println("TTT")  //Let's mess up the scoreboard :D
        return
    }

    val currentGame = Game(players)
    for (i in 1..3) {
        val action = determineBestAction(currentGame, myId)
        currentGame.doAction(myId, action)
        print(action)
    }
}

fun determineBestAction(game : Game, myId : Int) : Char {

    if (game[myId].lethalityRate > .02) {          //We don't want to hurt ourselves.
        return 'I'
    } else if (game[myId].lethalityRate > 0) {
        return 'V'
    }

    val bestAction = "NMEIVCQOBTWDP".maxBy { game.calculateBenefit(it, myId) }!!

    return bestAction

}

Компілювати з: kotlinc Terrorist.kt
Запустити з:kotlin terrorist.TerroristKt


Компіляція дає мені "злу" папку з класами Game, Player та WICKEDkt. Запуск, як ви описали, повертає: "помилка: не вдалося знайти або завантажити основний клас злий. WICKEDKt"
Mwr247

Це дивно, він працює на моєму комп’ютері просто чудово. Ви впевнені, що файл класу WICKEDkt насправді не названий WICKEDKt? Також переконайтесь, що ваш робочий каталог не знаходиться в папці злого.
TheNumberOne

Це WICKEDKt. Я друкував у коментарі.
Mwr247

@ Mwr247 Ви залишили створену нечестиву папку всередині папки подань? Ви перемістили згенеровані файли з папки злих?
TheNumberOne

WICKED - це добре ... чорт ти і твої посилання на речі, які я щойно прочитав.
ArtOfCode

9

Мадагаскар, Ява

Так, їдемо по маршруту Мадагаскар. Перший тур, ми BBBповинні закрити свої кордони. В іншому випадку він дає ліки і орієнтується на місцеві вакцини.

public class Madagascar{
    public static void main(String[]args){
        Boolean bool = false;
        bool = args[0].startsWith("1;");

        if(bool) {
            System.out.println("BBB");
        }
        else {
            System.out.println("CVV");
        }
    }
}

Edit1 - I more-Madagascar'd
Edit2 - Дякую @Geobits за startsWithнагадування


якщо Geobits має рацію щодо швидкості міграції, починаючи з 5 і не зводиться до нуля, B не роблять абсолютно нічого.
Кінтопія

Наразі це не виглядає так, як якщо б це було складено. if (b == true)(що має бути if (b)винятком стилю) призведе до помилки, оскільки змінна насправді викликається bool.
Пітер Тейлор

не хотів би, якщо перевірка проти туру == 1 працює набагато краще, ніж створювати файл?
Евмель

1
@TimmyD На щастя, раунд перший, тому не сильно розбирається. Просто перевірте, чи починається вхід1;
Geobits

@Geobits Дякуємо за startsWith()нагадування. МНОГО простіше, ніж розділяти на себе ;і намагатися відвоювати і ... Сказав, що я був іржавий з Java.
AdmBorkBork

7

Сіль, Котлін

Цей бот виживає, поки всі неприємні гравці не загинуть. Після цього вона виліковує своє населення і переселяє місто здоровими людьми.

Цей бот має 5 кроків:

  1. Закрийте кордони.
  2. Дозвольте інфікованому померти, але не надто швидко (важко визначити, як швидко занадто швидко йдеться).
  3. Запобігайте інфікуванню зараження здорових.
  4. Вилікуйте заражених (сіллю: P).
  5. Відтворити.

Ось:

package salt

import java.io.File
import java.util.*

data class Player(
        val id            : Int,
        var healthy       : Int,
        var infected      : Int,
        var dead          : Int,
        var infectionRate : Int,
        var contagionRate : Int,
        var lethalityRate : Int,
        var migrationRate : Int)

fun main(args : Array<String>) {
    @Suppress("NAME_SHADOWING")
    val args = args[0].split(';')

    val round = args[0].toInt()
    val myId = args[1].toInt()

    val players : MutableList<Player> = ArrayList()

    for ( i in 2..args.size-1) {
        val data = args[i].split('_')
        players.add(Player(data[0].toInt(), data[1].toInt(), data[2].toInt(), data[3].toInt(), data[4].toInt(), data[5].toInt(), data[6].toInt(), data[7].toInt()))
    }

    if (round == 50) {
        println("CCC")  //Extra 30 at end of game.
        return
    }

    var actionsLeft = 3

    val me = players.first { it.id == myId }
    val dataFile = File("Salt.txt")
    val lastRoundInfected : Int
    var roundsInHole : Int
    if (round == 1) {
        lastRoundInfected = 1
        roundsInHole = 0
    } else {
        val lines = dataFile.readLines()
        lastRoundInfected = lines[0].toInt()
        roundsInHole = lines[1].toInt()
    }

    val wantedInfected = lastRoundInfected * Math.pow(1/1.5, 1.0/5) * (if (round % 5 == 0 && round != 0) 1.5 else 1.0)

    while (me.migrationRate > 0) {
        print('B')          //Close borders
        me.migrationRate = Math.max(0, me.migrationRate - 10)
        actionsLeft--
    }

    if (me.infected <= wantedInfected) {   //Our infected are dieing too quickly
        roundsInHole++
    } else {
        roundsInHole = Math.max(0, roundsInHole - 1)
    }

    if (me.lethalityRate > 0) {
        var lethalityRateDelta = roundsInHole * 2
        while (lethalityRateDelta > 0 && me.lethalityRate > 0 && actionsLeft > 0) {
            if (lethalityRateDelta == 2 || me.lethalityRate <= 2) {
                lethalityRateDelta -= 2
                print('V')  //Research vaccines
                me.infectionRate = Math.max(0, me.infectionRate - 1)
                me.contagionRate = Math.max(0, me.contagionRate - 4)
                me.lethalityRate = Math.max(0, me.lethalityRate - 2)
                actionsLeft--
            } else {
                lethalityRateDelta -= 4
                print('I')
                me.lethalityRate = Math.max(0, me.lethalityRate - 4)
                actionsLeft--
            }
        }
    }

    dataFile.writeText("${me.infected}\n$roundsInHole")

    while (actionsLeft > 0) {
        if (me.infectionRate + me.contagionRate * me.infected / 100 <= 0) {
            break
        }
        val mWeight = Math.min(me.infectionRate, 4)
        val eWeight = Math.min(me.contagionRate, 8) * me.infected / 100
        val vWeight = Math.min(me.contagionRate, 4) * me.infected / 100 + Math.min(me.infectionRate, 1)
        if (mWeight > eWeight && mWeight > vWeight) {
            print('M')      //Research microbiology
            me.infectionRate = Math.max(0, me.infectionRate - 4)
        } else if (eWeight > vWeight){
            print('E')      //Research epidemiology
            me.contagionRate = Math.max(0, me.contagionRate - 8)
        } else {
            print('V')      //Research vaccines
            me.infectionRate = Math.max(0, me.infectionRate - 1)
            me.contagionRate = Math.max(0, me.contagionRate - 4)
            me.lethalityRate = Math.max(0, me.lethalityRate - 2)
        }
        actionsLeft--
    }

    while (actionsLeft > 0) {
        if (me.infected <= 0) {
            break
        }
        print('C')          //Cure
        val cured = Math.min(me.infected, 10)
        me.infected -= cured
        me.healthy += cured
        actionsLeft--
    }

    while (actionsLeft > 0) {
        print('N')          //Do nothing
        actionsLeft--
    }

    return
}

Компілювати з: kotlinc Salt.kt
Запустити з:kotlin salt.SaltKt

EDIT: Більш висока ймовірність вижити до тих пір, поки більшість ботів "кінця світу" не загинуть.

Приклад результатів:

1. Salt (247, 12, 280)
2. InfectedTown (30, 2016, 843)
3. ZombieState (30, 1030, 609)
4. WICKED (30, 413, 222)
5. Triage (18, 965, 706)
6. Mooch (18, 657, 597)
7. MadScienceBot (18, 305, 647)
8. TheKeeper (13, 0, 158)
9. FamilyValues (10, 110, 373)
10. Madagascar (2, 0, 271)
11. Terrorist (0, 1358, 651)
12. InfectionBot (0, 1217, 830)
13. Medic (0, 27, 340)
14. MedicBot (0, 1, 200)
15. UndecidedBot (0, 0, 33)
16. Researcher (0, 0, 63)
17. TheCure (0, 0, 71)
18. TrumpBot (0, 0, 88)
19. WeaponOfMassDissemination (0, 0, 137)
20. Strategist (0, 0, 142)
21. PassiveBot (0, 0, 149)
22. DisseminationBot (0, 0, 152)
23. PassiveBot (0, 0, 155)
24. Crossroads (0, 0, 164)
25. InfectedHaven (0, 0, 170)
26. Socialist (0, 0, 172)
27. BioterroristBot (0, 0, 175)
28. XenoBot (0, 0, 184)
29. ThePacifist (0, 0, 199)
30. CullBot (0, 0, 294)
31. AllOrNothing (0, 0, 327)

Дуже приємна стратегія. Мені подобається, що ти використовуєш летальність «добре»!
Фракс

Гарна робота, яка поклала край ботам "кінця світу"! Однак Сіль може звалитися, якби було ще кілька таких ботів, я не впевнений. Можливість вижити, що вже дуже вражає, милий чоловік!
busukxuan

@busukxuan Як це є наразі, декільком ботам доведеться максимально збільшити рівень летальності, перш ніж вони зможуть це вбити, вбиваючи себе в процесі.
TheNumberOne

7

PureBot (Haskell)

PureBot ненавидить одне: побічні ефекти!
Він спробує впоратися з усіма побічними ефектами, і якщо все піде добре, це зменшить кількість побічних ефектів, що виробляються зовнішнім світом.
Він також ігнорує всі побічні ефекти у своїх розрахунках.
Це змушує значно грати проти пасивних ворогів (які не змінюють глобальних показників).

Якщо infected, infection, contagion, lethalityі migrationвсі рівні нулю, то це допоможе іншим роботам з P(для Pureкоманди).

module Main where
import Control.Monad (void)
import Data.List (find)
import System.Environment (getArgs)
import System.Exit (exitFailure)
import Text.Parsec

-- | The world
data World = World
    { worldRound  :: Int    -- ^ The current round
    , worldTownID :: Int    -- ^ The current town ID
    , worldTowns  :: [Town] -- ^ List of all towns in the world
    }
    deriving (Show)

-- | A town in the world
data Town = Town
    { townID            :: Int -- ^ The town ID
    , townDeath         :: Int -- ^ The number of death people in the town
    , townHealthy       :: Int -- ^ The number of healthy people in the town
    , townInfected      :: Int -- ^ The number of infected people in the town
    , townInfectionRate :: Int -- ^ The infaction rate of the town
    , townContagionRate :: Int -- ^ The contagion rate of the town
    , townLethalityRate :: Int -- ^ The lethality rate of the town
    , townMigrationRate :: Int -- ^ The migration rate of the town
    }
    deriving (Show)

-- | Parse a Int
parseInt :: Parsec String () Int
parseInt = do
    sign <- option '+' $ oneOf "+-"
    numb <- read <$> many1 digit
    return $ if sign == '+'
        then numb
        else negate numb

-- | Parse a town
parseTown :: Parsec String () Town
parseTown = do
    nID <- parseInt
    void $ char '_'
    nHealthy <- parseInt
    void $ char '_'
    nInfected <- parseInt
    void $ char '_'
    nDeath <- parseInt
    void $ char '_'
    nInfectionRate <- parseInt
    void $ char '_'
    nContagionRate <- parseInt
    void $ char '_'
    nLethalityRate <- parseInt
    void $ char '_'
    nMigrationRate <- parseInt
    return Town
        { townID            = nID
        , townDeath         = nDeath
        , townHealthy       = nHealthy
        , townInfected      = nInfected
        , townInfectionRate = nInfectionRate
        , townContagionRate = nContagionRate
        , townLethalityRate = nLethalityRate
        , townMigrationRate = nMigrationRate }

-- | Parse a world
parseWorld :: Parsec String () World
parseWorld = do
    nRound <- parseInt
    void $ char ';'
    nTownID <- parseInt
    void $ char ';'
    towns <- parseTown `sepBy` char ';'
    let nTowns = length towns
    if nTowns < nTownID
        then let nExpected   = (nTownID - nTowns) in
            fail $ "expected at least " ++ show nExpected ++ " more town(s)"
        else return World
            { worldRound  = nRound
            , worldTownID = nTownID
            , worldTowns  = towns }

-- | Update a town
updateTown :: World -> Town -> String
updateTown world town = take 3 $ lastRound
                   ++ prepareForReproduction
                   ++ decreaseInfected
                   ++ decreaseMigration
                   ++ decreaseInfection
                   ++ decreaseContagion
                   ++ decreaseLethality
                   ++ decreaseWorldWide
  where
    -- | The current round number
    nRound         = worldRound world
    -- | The current number of infected
    nInfected      = townInfected town
    -- | The current lethality rate
    nLethalityRate = townLethalityRate town
    -- | The current migration rate
    nMigrationRate = townMigrationRate town
    -- | The current infection rate
    nInfectionRate = townInfectionRate town
    -- | The current contagion rate
    nContagionRate = townContagionRate town
    -- | What to do on the last round
    lastRound
        | nRound == 50 = "CCC"
        | otherwise    = ""
    -- | What to do in order to prepare for reproduction
    prepareForReproduction
        | (nRound+1) `mod` 5 == 0 = decreaseInfected
        | otherwise               = ""
    -- | What to do in order to decrease infected
    decreaseInfected
        | nInfected > 25 = "CCC"
        | nInfected > 15 = "CC"
        | nInfected > 5  = "C"
        | otherwise      = ""
    -- | What to do in order to decrease lethality
    decreaseLethality
        | nLethalityRate > 4 = "I"
        | otherwise          = ""
    -- | What to do in order to decrease migration
    decreaseMigration
        | nMigrationRate > 0 = "B"
        | otherwise          = ""
    -- | What to do in order to decrease infection
    decreaseInfection
        | nInfectionRate > 0 = "M"
        | otherwise          = ""
    -- | What to do in order to decrease contagion
    decreaseContagion
        | nContagionRate > 4 = "E"
        | otherwise          = ""
    -- | What to do if everything else has been taken care of
    decreaseWorldWide = "PPP"

-- | Update a world
updateWorld :: World -> Maybe String
updateWorld world = updateTown world <$> town
  where
    town          = find ((==worldTownID world) . townID) (worldTowns world)

-- | Main program entry point
main :: IO ()
main = do
    cmds <- concat <$> getArgs
    case parse parseWorld "stdin" cmds of
        Left err    -> print err >> exitFailure
        Right world -> case updateWorld world of
            Just cmd -> putStrLn cmd
            Nothing  -> putStrLn "Failed to update world!" >> exitFailure

працювати з: runhaskell PureBot.hs


Нічого собі, яка технічна чистота! Мені подобається, як ви інтерпретуєте команду P.
busukxuan

Щойно я встановив Haskell 7.10.3, і коли я намагаюся запустити ваш бот, він чекає нескінченно. Я намагався з цим: runhaskell.exe PureBot.hs 1;0;0_97_3_0_2_5_15_5;1_97_3_0_2_5_15_5. Чи потрібно щось ще зробити перед тим, як запустити його?
Фракс

@Thrax О, вибач. Я думав, ти передав команди через stdin ... Якщо цього не відбудеться, я зміню програму.
YoYoYonnY

Команди передаються як аргументи. Я буду робити наступний запуск після того, як ви оновили свого бота.
Thrax

@Thrax У такому випадку це має працювати зараз.
YoYoYonnY

7

Заражене місто, Ява

Заражене місто не хвилює, чи заражаються люди до тих пір, поки вони не вмирають. Тому це максимально знизить рівень локальної летальності.

Коли рівень летальності вже дуже низький, він використовує свої інші дії для підвищення глобальної смертності, перш ніж зменшити власну.

Оскільки він намагається бути найбільшим містом навколо, баланс імміграції може бути лише негативним, тому його першою дією є закриття кордонів.

Під час останньої черги рівень летальності не впливає, і рейтинг проводиться за кількістю здорових людей у ​​місті, тому він виліковує 30 осіб та сподівається, що цього буде достатньо.

import java.util.ArrayList;
import java.util.List;

public class InfectedTown {

    int playerID;
    State thisState;

    public static void main(String[] args){
        new InfectedTown().sleep(args[0].split(";"));
    }

    private void sleep(String[] args) {
        // Parse arguments
        int round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        for (int i = 2; i < args.length; i++){
            thisState = new State(args[i]);
            if(thisState.isMine()){
                break;
            }
        }

        // Special actions on turn 1 and 50.
        String action="";
        if(round == 1){
            action = "B";
        } else if(round == 50){
            action="CCC";
        } 

        while(action.length()<3){
            if(thisState.lethalityRate<=2 && action.length()<2){
                // We still have at least one action: lets increase the 
                // lethality rate for everyone, we will decrease it with our 
                // remaining actions.
                action+="W";
                thisState.lethalityRate+=2;
            } else if (thisState.lethalityRate>=4 
                    ||(thisState.lethalityRate>0 && action.length()==2)) {
                // Don't let people die!
                action+="I";
                thisState.lethalityRate-=4;
            } else {
                // Nothing better to do, lets distract other towns by  
                // increasing some useless values
                action+="D";
            }
        }

       System.out.println(action);
    }

    private class State {
        public int ownerId;
        public int lethalityRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            lethalityRate = Integer.parseInt(args[6]);
        }

        public boolean isMine(){
            return ownerId == playerID;
        }
    }
}

5

CullBot, Python 3

Це майже стандартний бот для самозахисту, який закриває межі та намагається знизити рівень зараження в місті. Це відбувається шляхом відсічення векторів тварин (оскільки заражені люди не впливають на швидкість зараження, це повинно мати щось спільне з векторами, що не належать до людини; в основному це "Дослідницька мікробіологія"). Іноді він також «знищує» заражених людей ... Знаєте, AI теж помиляється ...

# Parsing code
from sys import argv

args = argv[1].split(";")

n = int(args[0])
pid = int(args[1])
dic = ["pid","healthy","infected","dead","infection","contagion","lethality","migration"]
players = []
for p in args[2:]:
    players += [{dic[i]:int(p.split("_")[i]) for i in range(len(p.split("_")))}]
    if int(p.split("_")[0]) == pid:
        me = players[-1]

# Bot code

actions = ""
nextInfected = me["infected"]*me["contagion"]/100 + me["infection"] + me["infected"] - me["infected"]*me["lethality"]/100
if n%5 == 4:
    nextInfected *= 1.5

if n == 1:
    actions += "BM"
    if nextInfected*1.3 > 10:
        actions += "C"
    elif me["infection"] > 6:
        actions += "M"
    elif me["infection"] > 4:
        actions += "V"
    else:
        actions += "E"
    print(actions)
    exit()
elif n == 50:
    print("CCC")
    exit()


if nextInfected*1.2 > 30:
    if me["infected"] >= 23:
        actions += "Q"
        me["infected"] -= 30
    else:
        actions += "C"
        me["infected"] -= 10
elif me["infection"] > 0:
    actions += "M"
    me["infection"] -= 4
elif me["contagion"] >= 6:
    actions += "E"
    me["contagion"] -= 8
elif me["infected"] > 0:
    actions += "C"
    me["infected"] -= 10
else:
    actions += "E"
    me["contagion"] -= 8

if me["infection"] >= 3:
    actions += "M"
    me["infection"] -= 4
elif me["infected"] >= 7 :
    actions += "C"
    me["infected"] -= 10
elif me["infection"] > 0 and me["contagion"] >= 3:
    actions += "V"
    me["infection"] -= 1
    me["contagion"] -= 4
elif me["contagion"] >= 6:
    actions += "E"
    me["contagion"] -= 8
elif me["infection"] > 0:
    actions += "M"
    me["infection"] -= 4
elif me["infected"] > 0:
    actions += "C"
    me["infected"] -= 10
else:
    actions += "E"
    me["contagion"] -= 8

if me["infection"] >= 3:
    actions += "M"
    me["infection"] -= 4
elif me["infected"] >= 7 :
    actions += "C"
    me["infected"] -= 10
elif me["infection"] > 0 and me["contagion"] >= 3:
    actions += "V"
    me["infection"] -= 1
    me["contagion"] -= 4
elif me["contagion"] >= 6:
    actions += "E"
    me["contagion"] -= 8
elif me["infection"] > 0:
    actions += "M"
    me["infection"] -= 4
elif me["infected"] > 0:
    actions += "C"
    me["infected"] -= 10
else:
    actions += "E"
    me["contagion"] -= 8

if actions[-2:] == "VV":
    actions = actions[0] + "ME"
print(actions)

1
Я не хлопець Python, тому я можу робити це неправильно, але запуск цього в Python 3.4 дає мені "NameError: ім'я" словник "не визначено" у рядку 9.
Mwr247

@ Mwr247 Дякую, виявляється, я зовсім не придумав, коли писав код розбору ... Проблем було набагато більше.
busukxuan

Тепер він дає об’єкт "TypeError: 'list' не можна інтерпретувати як ціле число" в рядку 11
Mwr247

Зараз це працює =)
Mwr247

@ Mwr247 Лол! Я думав, що це виправив, але не скопіював і не вставив новий код, тому, мабуть, пропустив цей. Я тестував, зараз він повинен працювати нормально. Якщо я якось неправильно зрозумів правила вводу / виводу.
busukxuan

5

EvilBot, Java

EvilBot не переймається лікуванням людей. До тих пір, поки вони залишаться живими (свого роду). Намагається захворіти решту світу.

У моєму локальному тестуванні BlunderBot робив набагато краще, поки я також не представив EvilBot. Здається, трохи потрясає речі.

import java.util.ArrayList;
import java.util.List;

public class EvilBot {

int round;
int phase;
int playerID;
int thisTownID;

List<State> states;
List<State> otherStates;

State thisState;
String action = "";
int cc=0; // command count

public static void main(String[] args){
    new EvilBot().sleep(args[0].split(";"));
}

private void action(String newAction) {
    action += newAction;
    cc+= newAction.length();
    if (cc>=3) {
        System.out.println(action.substring(0, 3));
        System.exit(0);;
    }
}
private void sleep(String[] args) {

    round = Integer.parseInt(args[0]);
    thisTownID = Integer.parseInt(args[1]);

    states = new ArrayList<>();
    otherStates = new ArrayList<>();

    for (int i = 2; i < args.length; i++){
        states.add(new State(args[i]));
    }

    for (State state : states){
        if (state.isMine()) {
            thisState = state;
        } else {
            otherStates.add(state);
        }
    }

    // Round specific commands
    if (round == 1 )                                { action("B");   }
    if (round == 50)                                { action("CCC"); }

    for (int i=0;i<3;i++){
        if (thisState.getLethalityRate() >= 4)  { action("I"); thisState.lethalityRate -= 4;}
    }

    // Nothing else to do, cause trouble.
    action("DWT");
}


private class State {

    private final int ownerId;
    private int healthy;
    private int infected;
    private int dead;
    private int infectionRate;
    private int contagionRate;
    private int lethalityRate;
    private int migrationRate;

    public State(String string) {
        String[] args = string.split("_");
        ownerId = Integer.parseInt(args[0]);
        healthy = Integer.parseInt(args[1]);
        infected = Integer.parseInt(args[2]);
        dead = Integer.parseInt(args[3]);
        infectionRate = Integer.parseInt(args[4]);
        contagionRate = Integer.parseInt(args[5]);
        lethalityRate = Integer.parseInt(args[6]);
        migrationRate = Integer.parseInt(args[7]);
    }

    public int getOwnerId() {
        return ownerId;
    }

    public int getHealthy() {
        return healthy;
    }

    public int getInfected() {
        return infected;
    }

    public int getDead() {
        return dead;
    }

    public int getInfectionRate() {
        return infectionRate;
    }

    public int getContagionRate() {
        return contagionRate;
    }

    public int getLethalityRate() {
        return lethalityRate;
    }

    public int getMigrationRate() {
        return migrationRate;
    }

    public boolean isMine(){
        return getOwnerId() == thisTownID;
    }

}

}

5

Зброя масового поширення

public class WMDbot{
    public static void main(String[]a){
        System.out.println("WMD");
    }
}

Бот WMD - це ривок: утримує низький рівень власної інфекції та підвищує рівень усіх інших.

Бот, сконструйований виключно для абревіатури, ймовірно, не є сильним суперником, але зробить змагальне поле трохи більше ... цікавим. Код запозичив у TheCure і просто змінив рядок дій.


Технічно ви також змінили назву класу; P
Капітан Людина

@DenhamCoote: Будь ласка, не обходьте масові мовні теги. Якщо ви збираєтеся редагувати публікацію, переконайтеся, що це щось більш значне (граматика, форматування тощо). Дякую.
Zach Gates

Ой? У мене колись це було як єдине редагування одного з моїх дописів - я лише слідкував за чужими наслідками ...
Denham Coote

@DenhamCoote Це одне з тих "легких дешевих редагувань", які нічого не додають, але які насправді не заборонені. Якщо ви зробите купу з них, ви отримаєте спам.
Draco18s

Не впевнений, що ви маєте на увазі під «дешевим» - Це додає мені читабельності ... Для цього виклику можна прочитати набагато більше коду, ніж звичайний виклик у гольф, і тому я вважав, що виділення синтаксису буде вітатися. Це не так, як я роблю це за очки, я просто випадково отримав задоволення від цього виклику.
Denham Coote

5

Graymalkin, Java

Основна увага Graymalkin - зниження рівня зараженості до 0 та збільшення здорової популяції. Він не вірить у карантини ... окрім зовнішнього світу, звичайно.

Мій перший пост - прийом критики. :)

import java.util.ArrayList;
import java.util.List;

public class Graymalkin {

    int round;
    int phase;
    int playerID;
    int thisTownID;

    List<State> states;
    List<State> otherStates;

    State thisState;

    public static void main(String[] args) {
        new Graymalkin().sleep(args[0].split(";"));
    }

    private void sleep(String[] args) {

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        states = new ArrayList<>();
        otherStates = new ArrayList<>();

        for (int i = 2; i < args.length; i++) {
            states.add(new State(args[i]));
        }

        for (State state : states) {
            if (state.isMine()) {
                thisState = state;
            } else {
                otherStates.add(state);
            }
        }

        if (round == 50) {
            System.out.println("CCC");
            return;
        }

        String out = "";

        if (round == 1) {
            out += "B";
        }

        if (thisState.infectionRate < 10 && thisState.infected >= 10) {
            out += "C";
            thisState.infected -= 10;
        }

        while (thisState.infectionRate >= 4) {
            out += "M";
            thisState.infectionRate -= 4;
        }

        while (thisState.infectionRate > 0) {
            out += "V";
            thisState.infectionRate -= 1;
        }

        while (out.length() < 3) {
            if (thisState.infected > 0) {
                out += "C";
                thisState.infected -= 10;
            } else if (thisState.contagionRate > 0) {
                out += "E";
                thisState.contagionRate -= 8;
            } else if (thisState.lethalityRate > 0) {
                out += "I";
                thisState.lethalityRate -= 4;
            } else {
                out += "N";
            }
        }

        System.out.println(out.substring(0, 3));
    }

    private class State {

        private final int ownerId;
        private int sane;
        private int infected;
        private int dead;
        private int infectionRate;
        private int contagionRate;
        private int lethalityRate;
        private int migrationRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            sane = Integer.parseInt(args[1]);
            infected = Integer.parseInt(args[2]);
            dead = Integer.parseInt(args[3]);
            infectionRate = Integer.parseInt(args[4]);
            contagionRate = Integer.parseInt(args[5]);
            lethalityRate = Integer.parseInt(args[6]);
            migrationRate = Integer.parseInt(args[7]);
        }

        public int getOwnerId() {
            return ownerId;
        }

        public int getSane() {
            return sane;
        }

        public int getInfected() {
            return infected;
        }

        public int getDead() {
            return dead;
        }

        public int getInfectionRate() {
            return infectionRate;
        }

        public int getContagionRate() {
            return contagionRate;
        }

        public int getLethalityRate() {
            return lethalityRate;
        }

        public int getMigrationRate() {
            return migrationRate;
        }

        public boolean isMine() {
            return getOwnerId() == playerID;
        }
    }
}

@Thrax, схоже, мій бот не був включений у ваш останній запуск. Мені цікаво подивитися, як це відбувається!
театральні труси

5

Трідж, Ява

import java.util.ArrayList;
import java.util.List;

public class Triage {

    int round;
    int phase;
    int playerID;

    List<State> states;
    List<State> otherStates;

    State thisState;

    public static void main(String[] args){
        new Triage().sleep(args[0].split(";"));
    }

    private void sleep(String[] args) {

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        states = new ArrayList<>();
        otherStates = new ArrayList<>();

        for (int i = 2; i < args.length; i++){
            states.add(new State(args[i]));
        }

        for (State state : states){
            if (state.isMine()) {
                thisState = state;
            } else {
                otherStates.add(state);
            }
        }

        if (round == 50) {
          System.out.println("CCC");
          return;
        }

        String output = "";

        while( thisState.lethalityRate >= 4) {
          output += "I";
          thisState.lethalityRate -= 4;
        }

        while( thisState.lethalityRate > 0) {
          output += "V";
          thisState.lethalityRate -= 2;
          thisState.contagionRate -= 4;
          thisState.infectionRate -= 1;
        }

        while( thisState.contagionRate >= 8) {
          output += "E";
          thisState.contagionRate -= 8;
        }

        while( thisState.contagionRate > 0) {
          output += "V";
          thisState.lethalityRate -= 2;
          thisState.contagionRate -= 4;
          thisState.infectionRate -= 1;
        }

        while( thisState.infectionRate > 0) {
          output += "M";
          thisState.infectionRate -= 4;
        }

        while( output.length() < 3) {
          output += "C";
        }

        System.out.println(output.substring(0,3));

    }

    private class State {

        private final int ownerId;
        public int sane;
        public int infected;
        public int dead;
        public int infectionRate;
        public int contagionRate;
        public int lethalityRate;
        public int migrationRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            sane = Integer.parseInt(args[1]);
            infected = Integer.parseInt(args[2]);
            dead = Integer.parseInt(args[3]);
            infectionRate = Integer.parseInt(args[4]);
            contagionRate = Integer.parseInt(args[5]);
            lethalityRate = Integer.parseInt(args[6]);
            migrationRate = Integer.parseInt(args[7]);
        }

        public int getOwnerId() {
            return ownerId;
        }

        public boolean isMine(){
            return getOwnerId() == playerID;
        }

    }

}

Спочатку тримає живих своїх громадян, потім утримує їх від зараження інших, потім виліковує їх.

Mooch, Java

import java.util.ArrayList;
import java.util.List;

public class Mooch {

    int round;
    int phase;
    int playerID;

    List<State> states;
    List<State> otherStates;

    State thisState;

    public static void main(String[] args){
        new Mooch().sleep(args[0].split(";"));
    }

    private void sleep(String[] args) {

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        states = new ArrayList<>();
        otherStates = new ArrayList<>();

        for (int i = 2; i < args.length; i++){
            states.add(new State(args[i]));
        }

        for (State state : states){
            if (state.isMine()) {
                thisState = state;
            } else {
                otherStates.add(state);
            }
        }

        if (round == 50) {
          System.out.println("CCC");
          return;
        }

        String output = "";

        while( thisState.migrationRate < 100) {
          output += "O";
          thisState.migrationRate += 10;
        }

        while( thisState.lethalityRate >= 4) {
          output += "I";
          thisState.lethalityRate -= 4;
        }

        while( thisState.lethalityRate > 0) {
          output += "V";
          thisState.lethalityRate -= 2;
          thisState.contagionRate -= 4;
          thisState.infectionRate -= 1;
        }

        while( thisState.contagionRate >= 8) {
          output += "E";
          thisState.contagionRate -= 8;
        }

        while( thisState.contagionRate > 0) {
          output += "V";
          thisState.lethalityRate -= 2;
          thisState.contagionRate -= 4;
          thisState.infectionRate -= 1;
        }

        while( thisState.infectionRate > 0) {
          output += "M";
          thisState.infectionRate -= 4;
        }

        while( output.length() < 3) {
          output += "C";
        }

        System.out.println(output.substring(0,3));

    }

    private class State {

        private final int ownerId;
        public int sane;
        public int infected;
        public int dead;
        public int infectionRate;
        public int contagionRate;
        public int lethalityRate;
        public int migrationRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            sane = Integer.parseInt(args[1]);
            infected = Integer.parseInt(args[2]);
            dead = Integer.parseInt(args[3]);
            infectionRate = Integer.parseInt(args[4]);
            contagionRate = Integer.parseInt(args[5]);
            lethalityRate = Integer.parseInt(args[6]);
            migrationRate = Integer.parseInt(args[7]);
        }

        public int getOwnerId() {
            return ownerId;
        }

        public boolean isMine(){
            return getOwnerId() == playerID;
        }

    }

}

Те саме, що і Трідж, за винятком того, що він починається повністю відкривши свої кордони. Це забезпечує величезну вічну популяцію інфікованих, що незручно створює інших ботів і, можливо, служить перемикачем.


Triage продовжує давати сімейні цінності за гроші. Мух, з іншого боку, продовжує створювати страшно велику армію хворих людей. Молодці!
Mwr247

хіба moochbot намагається зберегти всіх незаражених? Чи не змінює thisState.x значення State, а потім гра знову змінює його з рядка, даючи подвійний ефект? Чудова ідея про ТКК в останньому турі
Еумель

Я зрозумів код зараз і визнав моє друге питання досить дурним
Еумель

Moochbot зрештою намагається створити здорове населення, але відкриті межі + нульова летальність гарантує, що заражене населення зросте набагато швидше.
гістократ

4

Інфікований Ворон, Пітон 3

Безпечний пристрій для інфікованих із закритими кордонами. Намагається мінімізувати летальність. Якщо їх звести до мінімуму, намагається збільшити летальність в інших державах, щоб "принести користь" місцевим зараженим.

# parsing code
from sys import argv
args = argv[1].split(";")

n = int(args[0])
pid = int(args[1])
dic = ["pid","healthy","infected","dead","infection","contagion","lethality","migration"]
players = []
for p in args[2:]:
    players += [{dic[i]:int(p.split("_")[i]) for i in range(len(p.split("_")))}]
    if int(p.split("_")[0]) == pid:
        me = players[-1]

# bot code

actions =""

if n == 50:
    print("CCC")
    exit()
elif n == 1:
    actions += "B"
    if me["lethality"] <= 6:
        actions += "WI"
    else:
        actions += "II"
    print(actions)
    exit()

if me["lethality"] >= 9:
    actions += "III"
elif me["lethality"] >= 3:
    actions += "WII"
else:
    actions += "WWI"
print(actions)

Внесені вами зміни будуть враховані під час наступного запуску. Він все одно не буде конкурувати у другому циклі, оскільки ваша стратегія створити Безпечний привал для заражених. Дуже цікаво все-таки!
Thrax

2
@Thrax Lol дякую, це насправді не стратегія. Я просто думав, що інфіковані, ймовірно, будуть заперечувати або дискримінувати здорових, тому в хаотичному світі це, ймовірно, каталізуватиме формування держави "для інфікованих". Якщо чесно, це бот, який був просто для задоволення, але потім я побачив у ньому невеликий потенціал, тому я подав заяву.
busukxuan

@Thrax вибачте, якщо це незручно, але я щойно з’ясував, що я прорахував умови внизу, тому я знову оновився.
busukxuan

4

Перехрестя, Python2

Перехрестя - це демократична нація з акцентом на футуристичні наукові цінності. Як і в більшості демократій, більшість рішень приймаються неспецифічно навченими, егоїстичними та нефункціональними комітетами, які часто приймають дуже дивні та погані - мабуть, випадкові, рівномірні рішення. Однак уряд в кінцевому підсумку працює для загального блага свого народу та людського роду.

import sys
import random
import itertools
def sample_wr(population, k):
    "Chooses k random elements (with replacement) from a population"
    n = len(population)
    _random, _int = random.random, int  # speed hack
    return [population[_int(_random() * n)] for i in itertools.repeat(None, k)]
a = sys.argv[1].split(';')
round = int(a[0])
myid = a[1]
players = {}
Sane = 0
Infected = 1
Dead = 2
InfectionRate = 3
ContagionRate = 4
LethalityRate = 5
MigrationRate = 6
worldpopulation = 0
for i in range(2,len(a)):
    b = a[i].split('_')
    players[b[0]]=map(int,b[1:])
    worldpopulation += (int(b[1])+int(b[2]))*int(b[7])/100
output = ""
if round == 1:
    output="BM"
    if players[myid][Infected]>6: output+="C"
    else: output+="E"
if round == 50: 
    if players[myid][Infected] > 20: output = "CCC"
    elif players[myid][Infected]> 6: output = "CTC"
    else: output = "TTC"
if round == 48 and players[myid][Infected] > 45 and players[myid][InfectionRate]>12:
    output = "MMM"
if round == 49 and players[myid][Infected] > 30:
    output = "CCC"
if (round+1)%5==0:
    if players[myid][Sane]==0 or players[myid][Infected]/players[myid][Sane] > 2: output+="I"*(players[myid][LethalityRate]/4)
    output+="M"*(players[myid][InfectionRate]/4)
    output+="C"*max((players[myid][Infected]/10),1)
if players[myid][InfectionRate] < 8 and players[myid][ContagionRate] < 20 and players[myid][Sane]+min(players[myid][Infected]/5,60)>players[myid][Infected] and (round+2)%5==0:
    output+="C"*max((players[myid][Infected]/10),1)
    players[myid][Infected] -= min(max((players[myid][Infected]/10),1)*10,players[myid][Infected])
if players[myid][Sane] > players[myid][Infected] > 30: 
    output +="Q"
    players[myid][Infected] -= min(players[myid][Infected],30)
if players[myid][Sane] > players[myid][Infected] > 20:
    output+="CC"
    players[myid][Infected] -= min(players[myid][Infected],20)
if (players[myid][Sane] > 2*players[myid][Infected] > 20):
    output+="C"
    players[myid][Infected] -= min(players[myid][Infected],10)
if round <= 5 and players[myid][Infected] > 10:
    output+="C"
    players[myid][Infected] -= min(players[myid][Infected],10)
if 25 <= players[myid][Infected] < 40 and players[myid][InfectionRate]<10:# and players[myid][ContagionRate]*(players[myid][Infected]-20)/100 < 10:
    output+="CCC"

if players[myid][InfectionRate]-players[myid][ContagionRate]>10: output+="M"
if players[myid][ContagionRate]-players[myid][InfectionRate]>20: output+="E"
population = []
population +=["I" for i in range(int(1.15**players[myid][LethalityRate]))]
if players[myid][Sane]<10 or players[myid][Infected]-players[myid][Sane]>10: population+=["I" if players[myid][LethalityRate]>8 else "V" for i in range(players[myid][InfectionRate])]
if players[myid][Sane]+players[myid][Infected]>10 and (players[myid][Sane]>15 or players[myid][LethalityRate]<10): population += ["M" if players[myid][InfectionRate] > 6 else "V" for i in range(2*max(players[myid][InfectionRate]*players[myid][Sane]/100,int((1.15+0.002*(50-round))**min(50,players[myid][InfectionRate]))))]
if players[myid][Sane]+players[myid][Infected]>10 and (players[myid][Sane]>15 or players[myid][LethalityRate]<10): population += ["E" if players[myid][ContagionRate] > 10 else "V" for i in range(max(min(players[myid][Sane],players[myid][ContagionRate]*players[myid][Infected]/100),int(1.15**min(50,players[myid][ContagionRate]))))]
if players[myid][InfectionRate]+players[myid][ContagionRate]<15: population += ["C" for i in range(players[myid][Infected])]
if players[myid][Infected] < 10: population += ["WV" for i in range(int(1.05**round))]
output += ''.join(sample_wr(population,3))
print output[:3]

4 пробігу, в яких беруть участь усі:

1. Crossroads (36, 12, 185)
2. InfectedTown (14, 1040, 510)
3. InfectedHaven (14, 977, 481)
4. Triage (14, 668, 531)
5. ZombieState (14, 523, 393)

1. AllOrNothing (541, 0, 312)
2. InfectedTown (30, 1125, 574)
3. InfectedHaven (30, 1020, 612)
4. WICKED (30, 732, 622)
5. Triage (30, 553, 554)
6. Mooch (30, 80, 240)
7. Crossroads (25, 0, 162)

1. AllOrNothing (846, 12, 241)
2. Crossroads (440, 15, 146)
3. FamilyValues (388, 34, 201)
4. Salt (170, 0, 176)
5. InfectedHaven (18, 1290, 664)

1. Crossroads (80, 14, 365)
2. InfectedHaven (30, 1596, 603)
3. InfectedTown (30, 1286, 576)
4. Triage (30, 1084, 412)
5. WICKED (18, 1286, 578)

4 тиражі без "ботів до суду":

1. Salt (6790, 0, 58)
2. FamilyValues (6697, 7, 9)
3. Crossroads (6616, 4, 16)
4. PureBot (6454, 0, 50)
5. Piecemeal (6260, 0, 111)

1. Crossroads (6970, 0, 39)
2. PureBot (6642, 0, 77)
3. CureThenQuarantine (6350, 2, 51)
4. FamilyValues (6153, 13, 21)
5. Piecemeal (5964, 4, 132)

1. PureBot (6142, 0, 34)
2. CureThenQuarantine (6010, 4, 75)
3. Piecemeal (5971, 4, 72)
4. CullBot (5409, 8, 115)
5. Crossroads (5129, 0, 27)

1. FamilyValues (7277, 12, 26)
2. Crossroads (6544, 4, 32)
3. Salt (5830, 26, 103)
4. Piecemeal (5757, 8, 164)
5. PureBot (5657, 8, 127)

EDIT: Побачивши успішну стратегію CullBot «ігнорувати летальність і зосередити увагу на збереженні здорових людей», я збільшив пріоритет щодо зменшення зараження та зараження та вилікування над зменшенням летальності, не відмовляючись від суттєвого випадкового чуття від комітету.

EDIT2: Виявляється, ігнорування летальності з великою кількістю терористів є поганим. пріоритет зменшення летальності знову збільшився, тепер масштабування залежить від рівня летальності. Також було виправлено деякі інші погані рішення, такі як відкриття та закриття кордонів на тому ж повороті, і підвищений поріг для карантину, вважаючи за краще вилікувати замість того, де це можливо.

EDIT3: Кілька незначних пріоритетних коригувань для вирішення ситуацій, з якими не впоралися. Тепер він балів біля вершини, включаються чи ні дні судів, думав Сіль, що долає це в обох випадках. Наразі я голосую з Сіллю за переможця цієї речі.

EDIT4: Покращені терміни та ефективність затвердіння.

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

EDIT6: Підвищити пріоритетність зниження рівня зараження в ранній грі. Видаліть коментовані рядки. Я не оновлював результати тестових пробіжок, але тепер він набирає значно вищих результатів у небіжному дні (вибиваючи FamilyValues, але не TrumpBot)

EDIT7: показник швидкості зараження / зараження шапки на 50, щоб запобігти високому використанню пам'яті.


Зачекайте ... Чи моделюється Ізраїль після Єрусалиму WWZ з дуже високими стінами?
busukxuan

@busukxuan це було натхненним так, за винятком того, що цей Ізраїль більше нагадує Єрусалим у фільмі (швидко його обганяють інфіковані), оскільки він, в основному, відкриває його межу з широкою a la Mooch. Спочатку планувалося, що це здебільшого робити "P", але це не була ефективною стратегією.
Кінтопія

Гм ... Здається, дорогий CullBot не міг більше йти в ногу, коли є більше ботів, які намагаються посилити зараження.
busukxuan

це чудово, коли мене додали в бота, щоб знищити інфекцію (до випадковості порядку замовлення)
Quintopia

Тож CullBot в основному досить нестабільний і залежить від ситуації. Дійсно, я припускав зараженість інфекцією, коли писав код. Єдиним резервом було до 1 карантину за оборот.
busukxuan

3

Хранитель, Луа

KotH, зроблений товаришем по французькій жабі! Я повинен був бути в цьому конкурсі!

Цей бот зробить усе можливе, щоб максимально знизити рівень зараження / зараження та летальності. Найбільшим його пріоритетом є летальність близько 0. Потім він спробує здогадатися, коли добре спробувати «імпортувати» більше людей.

Редагувати: Я припускав, що ми отримуємо через, argбуло відсортовано за програмою playerId. Це неправильне припущення, тому я додав сортування бульбашок для datas.

input=arg[1]

datas={}
format={"playerID","sane","infected","dead","infection","contagion","lethality","migration"}
i=1
for s in input:gmatch("[^;]+") 
do
  j=1
  if round==nil then round=tonumber(s) 
  elseif me==nil then me=tonumber(s)+1
  else
    table.insert(datas,{})
    for r in s:gmatch("%d+")
    do
      datas[i][format[j]]=tonumber(r)
      j=j+1
    end
    i=i+1
  end
end
for i=#datas-1,1,-1
do
  for j=1,i
  do
    if datas[j].playerID>datas[j+1].playerID
    then
      datas[j],datas[j+1]=datas[j+1],datas[j]
    end
  end
end

-- First, we put ourself in a safe state
if round==1 then print("VVV")os.exit(0)end
if round==50 then print("CCC")os.exit(0)end

actions=""

-- Safety actions first
if datas[me].lethality>2 
then 
  actions=actions.."I"
  datas[me].lethality=datas[me].lethality-4>0 and datas[me].lethality-4 or 0
end

if datas[me].infected>=10
then
  if(datas[me].infection+datas[me].contagion+datas[me].lethality>4)
  then
    actions=actions.."V"
    datas[me].infection=datas[me].infection-1>0 and datas[me].infection-1 or 0
    datas[me].contagion=datas[me].contagion-4>0 and datas[me].contagion-4 or 0
    datas[me].lethality=datas[me].lethality-2>0 and datas[me].lethality-2 or 0
  end
  actions=actions.."C"
  datas[me].sane=datas[me].sane+10
  datas[me].infected=datas[me].infected-10
end

-- We can now try taking some initiatives
while #actions<3
do
  rates={}
  for i=1,#datas
  do
    if i~=me 
    then
      table.insert(rates,(datas[i].infected/datas[i].sane>0 and datas[i].sane or 0)*(datas[i].migration/100))
    end
  end
  rates["total"]=0
  for i=1,#rates
  do
    rates.total=rates.total+rates[i]
  end
  rates.total=(rates.total/#rates)*100


  if datas[me].migration<=15 and datas[me].migration+10>rates.total
  then
    actions=actions.."O"
    datas[me].migration=datas[me].migration+10>0 and datas[me].migration+10 or 0
  elseif (datas[me].sane/datas[me].infected)*100<rates.total
  then
    actions=actions.."B"
    datas[me].migration=datas[me].migration-10>0 and datas[me].migration-10 or 0
  elseif datas[me].infected>=10
  then
    actions=actions.."C"
    datas[me].infected=datas[me].infected-10
  else
    actions=actions.."V"
    datas[me].infection=datas[me].infection-1>0 and datas[me].infection-1 or 0
    datas[me].contagion=datas[me].contagion-4>0 and datas[me].contagion-4 or 0
    datas[me].lethality=datas[me].lethality-2>0 and datas[me].lethality-2 or 0
  end
end
print(actions)
os.exit(0)

@Thrax Oh .. Виправлено вихідний код, тепер використовуйте input=arg[1]замість input=io.read().
Katenkyo

3

MadScienceBot, Python2

Ви знаєте, що потребує цей світ?

БІЛЬШЕ НАУКА!

Як ми отримуємо БІЛЬШУ НАУКУ?

З БРЕЙНЗ

Тільки виліковує людей в останню секунду, не можу менше піклуватися про них, крім 50-го раунду. Намагається бути зомбі-фермою кожен другий тур

import sys, copy
import itertools

mults = {'mig_rate': -15, 'let_rate': -15, 'dead': -20, 'inf_rate': -20, 'sane': 0, 'infected': 60, 'con_rate': -30, 'id': 0}
def get_score(player_data):
    score = 0
    for k in player_data:
        score += player_data[k] * mults[k] / 100.
    return score


def add_rates(player_data):
    #Infection
    no_sane_converted = player_data["sane"]*player_data["inf_rate"]/100.
    player_data["infected"] += no_sane_converted
    player_data["sane"] -= no_sane_converted
    #Contagion
    no_sane_converted = player_data["con_rate"]
    player_data["infected"] += no_sane_converted
    player_data["sane"] -= no_sane_converted
    #Extinction
    no_killed = player_data["infected"]*player_data["let_rate"]/100.
    player_data["dead"] += no_killed
    player_data["infected"] -= no_killed

def correct(data):
    if round % 5 == 4:
        data["sane"] += int(data["sane"])/2
        data["infected"] += int(data["infected"])/2
    data["inf_rate"] += 2
    data["con_rate"] += 5
    data["let_rate"] += 5

args = sys.argv[1].split(";")
round = int(args[0])
self_id = int(args[1])
player_data = [map(int, player.split("_"))for player in args[2:]]
player_data = [dict(zip(("id", "sane", "infected", "dead", "inf_rate", "con_rate", "let_rate", "mig_rate"), player)) for player in player_data]
self_data = [player for player in player_data if player["id"] == self_id][0]

f = open("MadScienceBot.txt", "a")
f.write("\n")
f.write(`round`+"\n")
f.write("INPUT: "+`self_data`+"\n")

def m(p): p["inf_rate"] -= 4
def e(p): p["con_rate"] *= 92/100.
def i(p): p["let_rate"] -= 4
def v(p): p["inf_rate"] -= 1; p["con_rate"]-=4;p["let_rate"]-=2
def c(p): x=min(p['infected'], 10); p['infected']-=x; p['sane']+=x
def q(p): x=min(p['infected'], 30); p['infected']-=x; p['dead']+=x
def o(p): p["mig_rate"] += 10
def b(p): p["mig_rate"] -= 10

out = ""
instructions = {"M": m,
                "E": e,
                "I": i,
                "V": v,
                "C": c,
                "Q": q,
                "O": o,
                "B": b}

def run_inst(new_data, inst_id, i):
    inst = instructions[inst_id]
    if i != 2:
        inst(new_data)
        for j in new_data: new_data[j] = max(0, int(new_data[j]))
        #f.write("%s %s %s\n"%(inst_id, get_score(new_data), new_data))
    else:
        inst(new_data)
        for j in new_data: new_data[j] = max(0, int(new_data[j]))
        correct(new_data)
        add_rates(new_data)
        for j in new_data: new_data[j] = max(0, int(new_data[j]))
        #f.write("%s %s %s\n"%(inst_id, get_score(new_data), new_data))
    return new_data

def run_3_insts(self_data, insts):
    new_data = copy.copy(self_data)
    for i, inst in enumerate(insts):
        run_inst(new_data, inst, i)
    return get_score(new_data)

scores = {}
for combo in itertools.permutations(instructions.keys(), 3):
    joined = "".join(combo)
    score = run_3_insts(self_data, joined)
    scores[score] = joined
#print scores
out = scores[max(scores)]

if round == 50:
    out = "CCC"

f.write(out+"\n")
print out

3

ZombieState, Java

Гей, це моя перша публікація на цьому сайті. Я в основному просто взяв один із прикладів ботів і змінив рядки щодо виходу.

import java.util.ArrayList;
import java.util.List;

public class ZombieState {

int round;
int phase;
int playerID;
int thisTownID;

List<State> states;
List<State> otherStates;

State thisState;

public static void main(String[] args){
    new ZombieState().sleep(args[0].split(";"));
}

private void sleep(String[] args) {

    round = Integer.parseInt(args[0]);
    thisTownID = Integer.parseInt(args[1]);

    states = new ArrayList<>();
    otherStates = new ArrayList<>();

    for (int i = 2; i < args.length; i++){
        states.add(new State(args[i]));
    }

    for (State state : states){
        if (state.isMine()) {
            thisState = state;
        } else {
            otherStates.add(state);
        }
    }

    StringBuilder sb = new StringBuilder();
    if(round == 1)
        System.out.println("TTT");
    else if(round == 50)
        System.out.println("CCC");
    else
    {
        while(thisState.lethalityRate >= 4)
        {
            sb.append("I");
            thisState.lethalityRate -= 4;
        }
        sb.append("DDD");
        System.out.println(sb.toString().substring(0, 3));
    }
}

private class State {

    private final int ownerId;
    public int sane;
    public int infected;
    public int dead;
    public int infectionRate;
    public int contagionRate;
    public int lethalityRate;
    public int migrationRate;

    public State(String string) {
        String[] args = string.split("_");
        ownerId = Integer.parseInt(args[0]);
        sane = Integer.parseInt(args[1]);
        infected = Integer.parseInt(args[2]);
        dead = Integer.parseInt(args[3]);
        infectionRate = Integer.parseInt(args[4]);
        contagionRate = Integer.parseInt(args[5]);
        lethalityRate = Integer.parseInt(args[6]);
        migrationRate = Integer.parseInt(args[7]);
    }

    public int getOwnerId() {
        return ownerId;
    }

    public boolean isMine(){
        return getOwnerId() == playerID;
    }

}

}

Я сподіваюся, що це нормально, і бот зробив досить добре в моїх власних пробігах. Тому що кому потрібно життя, якщо ти можеш мати 30 здорових та максимальну кількість заражених наприкінці. Він починає гру з 3x BioTerrorism, щоб розпочати все, і намагається тримати низький рівень летальності. Якщо вона менше 4, вона намагається збільшити глобальний рівень зараження та зараження шляхом Поширення.


Ласкаво просимо до PPCG :-) Сподіваюсь, що тут добре провести час
busukxuan

Це, здається, поки що добре. Ласкаво просимо в PPCG, і хороша робота!
Rɪᴋᴇʀ

2

ПоширенняBot, Ruby

Цей бот вилікується до тих пір, поки не вилікується 10 або більше. Далі, якщо рівень зараження становить щонайменше 4, бот знизить його. Всі інші дії проводяться з підвищенням рівня зараження, що не зашкодить мені, оскільки у мене не залишилося заражених.

#You can copy this code if you want. Not specific to my strategy.
PlayerId = 0
Sane = 1
Infected = 2
Dead = 3
InfectionRate = 4
ContagionRate = 5
LethalityRate = 6
MigrationRate = 7

a = ARGV[0].split ';'
round = a.shift.to_i
my_id = a.shift.to_i
players = a.map{|s|s.split('_').map{|str| str.to_i}}

my_index = players.index{|p|
    p[PlayerId] == my_id
}
me = players[my_index]

#strategy specific code starts here.

commands = ""
commands += 'C' if me[Infected] >= 10
commands += 'C' if me[Infected] >= 20
commands += 'C' if me[Infected] >= 30
commands += 'M' if me[InfectionRate] >= 4 and commands.length < 3
commands += 'D' while commands.length < 3

print commands
$stdout.flush

2

XenoBot (Node.js)

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

Активуйте XenoBot так:

node xenobot.js [data]

Код:

const argv = String(process.argv),
    data = argv.split(";"),
    round = data[0],
    id = Number(data[1]),
    info = data[id + 1].split("_"),
    sane = info[1],
    infected = info[2],
    dead = info[3],
    infectionRate = info[4],
    contagionRate = info[5],
    lethalityRate = info[6],
    migrationRate = info[7]

var moves = 3
function exec(a) {
  process.stdout.write(a)
}
if(migrationRate >= 10) {
  exec("B")
}
if (infectionRate >= 8) {
  exec("MQ")
  moves-=2;
} else if(contagionRate >= 16) {
  exec("EC")
  moves-=2;
} else if(lethalityRate >= 8) {
  exec("IV")
  moves--;
} else {
  exec("B");
  moves--;
}

if (sane / 3 > infected + dead) {
  exec("Q")
  moves--;
}
if(moves > 0) {
  exec("B")
}

2

Стратег, Пітон

Цей бот справді серйозно ставиться до виживання. Він проаналізував можливі стратегії та придумав власний метод виграшу. Що він зараз збирається задокументувати у коментарях джерела, тому що він хороший хлопець і хоче, щоб і інші люди вижили.

Подзвонив с python strategist.py.

import sys
import random
import math


def main():
    id = int(get_player_id(sys.argv[1]))
    stats = get_player_stats(sys.argv[1], id)
    round = int(get_round(sys.argv[1]))

    if id == -1 or stats == None or round == -1:
        # Something is wrong here. RED ALERT! Close all possible entry routes and set 
        # quarantine levels to maximum!
        print("BQQ")
        sys.exit(1)

    if round == 1:
        # remove migration, cure some infected, and remove some danger
        print("BCM")
    elif round % 5 == 4:
        # Rounds 4, 9, 14 etc. One before repopulation. We want as many Healthy and as 
        # few Infected as possible to reproduce. Prioritise curing infected, because that
        # maximises Healthy for reproduction. If that's not possible, quarantine them.
        quarantine = math.ceil(int(stats['infected']) / 30)
        cure = math.ceil(int(stats['infected']) / 10)
        if cure <= 3:
            # we can deal with all our infections within 3 cures
            output = "C" * cure
            for i in range(3 - cure):
                # got moves left? Great, remove some danger.
                output += get_random_science()
            print(output)
        elif quarantine <= 3:
            # we can deal with all our infections within 3 quarantines
            output = "Q" * quarantine
            for i in range(3 - quarantine):
                # got moves left? Great, remove some danger.
                output += get_random_science()
            print(output)
        else:
            # We can't deal with all the infected in one round, so deal with some. Yes, we
            # don't get rid of as many as we could here, but we're about to reproduce so
            # we want Healthies in the next round.
            print("QQC")
    else:
        output = ""
        if int(stats['infected']) <= 10:
            # we can deal with all our infections by curing them
            output += "C"
        elif int(stats['infected']) <= 30:
            # we can deal with all our infections by quarantining them
            output += "Q"
        elif int(stats['infected']) >= int(stats['healthy']) * 0.5:
            # we're getting overrun with infected people, get rid of some
            output = "QCC"

        for i in range(3 - len(output)):
            # if we haven't used all our moves, we can remove some danger factors
            output += get_random_science()

        print(output)


def get_random_science():
    return random.choice(["M", "E", "I", "V"])


def get_player_id(args):
    splat = args.split(";")
    return splat[1] if len(splat) >= 2 else -1


def get_player_stats(args, id):
    splat = args.split(";")
    players_data = [x for x in splat if "_" in x]
    my_data = [y for y in players_data if y.split("_")[0] == str(id)]
    data_splat = my_data[0].split("_")

    if len(data_splat) == 8:
        # Id, Healthy, Infected, Dead, InfRate, ConfRate, LethRate, MigRate
        return {
            'healthy': data_splat[1],
            'infected': data_splat[2],
            'dead': data_splat[3],
            'inf_rate': data_splat[4],
            'conf_rate': data_splat[5],
            'leth_rate': data_splat[6],
            'mig_rate': data_splat[7]
        }
    else:
        return None


def get_round(args):
    splat = args.split(";")
    return splat[0] if len(splat) >= 1 else -1


if __name__ == "__main__":
    main()

2

OpenAndClose

Почніть гру, відкриваючи кордони, тоді нехай приходять всі хворі. Після того, як у нас є велика кількість хворих (30 раунд), закриваємо кордони та працюємо над вилікуванням хворих.

#You can copy this code if you want. Not specific to my strategy.
PlayerId = 0
Healthy = 1
Infected = 2
Dead = 3
InfectionRate = 4
ContagionRate = 5
LethalityRate = 6
MigrationRate = 7

a = ARGV[0].split ';'
round = a.shift.to_i
my_id = a.shift.to_i
players = a.map{|s|s.split('_').map{|str| str.to_i}}

my_index = players.index{|p|
    p[PlayerId] == my_id
}
me = players[my_index]

#strategy specific code starts here.

commands = ""
if round < 30
  commands += me[MigrationRate] == 100 ? (me[InfectionRate] <= 1 ? "V" : "M") : "O"
  commands += me[LethalityRate] <= 2 ? "V" : "I"
  commands += me[ContagionRate] <= 4 ? "V" : "E"
elsif round < 50
  commands += me[MigrationRate] == 0 ? "V" : "B"
  commands += me[LethalityRate] < 20 ? "C" : "I"
  commands += me[ContagionRate] <  5 ? "C" : "E"
else
  commands = "CCC"
end

print commands
$stdout.flush

2

Ще два боти Python

Ізраїль

Це схоже на Mooch, але, можливо, не так добре, як Mooch, за винятком рідкісних випадків, коли це набагато краще:

import sys
a = sys.argv[1].split(';')
round = int(a[0])
myid = a[1]
players = {}
Sane = 0
Infected = 1
Dead = 2
InfectionRate = 3
ContagionRate = 4
LethalityRate = 5
MigrationRate = 6
for i in range(2,len(a)):
    b = a[i].split('_')
    players[b[0]]=map(int,b[1:])
output=''
if round<=4:output = ["OOO","OOO","OOO","OII"][round-1]
if round==50: output = "CCC"
mycontrate = players[myid][ContagionRate]
myfatrate = players[myid][LethalityRate]
myinfrate = players[myid][InfectionRate]
if myinfrate+mycontrate<5:
    output+="V"
    myfatrate-=2
    if round < 47: 
        output+="I"*(myfatrate/4)
        if myfatrate%4: output+="V"
else:
    if round < 47: 
        output+="I"*(myfatrate/4)
        if myfatrate%4: output+="V"
    output+="M"*(myinfrate/4)
    if round < 47: 
        output+="E"*(mycontrate/4)
output+="CCC"

print output[:3]

Червоний Хрест

На зразок пацифістів, за винятком того, що намагається також утримати власних людей від вмирання. У цьому не виходить жалюгідна ситуація, але приємно мати ще одне товариство на ігровому полі.

import sys
a = sys.argv[1].split(';')
round = int(a[0])
myid = a[1]
players = {}
Sane = 0
Infected = 1
Dead = 2
InfectionRate = 3
ContagionRate = 4
LethalityRate = 5
MigrationRate = 6
for i in range(2,len(a)):
    b = a[i].split('_')
    players[b[0]]=map(int,b[1:])
output="PPPPP"
if round<=4:output = ["OOO","OOO","OOO","OII"][round-1]
elif round==50: output = "CCC"
else: output = output[:2-3*round%5]+"I"+output[2-3*round%5:]
print output[:3]

2

Smaug (Python)

Я вогонь; Я - смерть.

Смауг створює якомога більше смерті, незалежно від того, де це відбувається.

# "I am fire, I am death"
# Smaug has two goals: hoard gold and bring death...
#    and this world seems to be all out of gold

from sys import argv
args = argv[1].split(";")

round = int(args.pop(0))
me = int(args.pop(0))

if round==50: # can't cause more death on the last round, might as well infect
    print('TTT')

def predict_infected(infected, infection_rate, contagion_rate):
    i = infected + infection_rate
    return i + int(i*contagion_rate)

def predict_dead(infected, lethality_rate):
    return int(infected*lethality_rate)

strategies = {'WWW':0, 'WWD':0, 'WDD':0, 'DDD':0}
for player in args:
    player=player.split('_')
    healthy=int(player[1])
    infected=int(player[2])
    infection_rate=int(player[4])
    contagion_rate=int(player[5])/100.
    lethality_rate=int(player[6])/100.

    if round%5==0:
        healthy+=healthy/2
        infected+=infected/2

    pi_old = predict_infected(infected, infection_rate, contagion_rate)
    pd_old = predict_dead(pi_old, lethality_rate)

    for strat in strategies:
        ir_new = infection_rate + 3
        lr_new = lethality_rate + (strat.count('W')*.02) 
        cr_new = contagion_rate + (strat.count('D')*.02) 

        pi_new = predict_infected(infected, ir_new, cr_new)
        pd_new = predict_dead(pi_new, lr_new)

        increase = pd_new - pd_old

        strategies[strat]+=increase

print max(strategies, key=strategies.get)

Якщо ви намагаєтеся пограти в поліглот, порожній файл був би коротшим і робити саме те, що робить спостерігач (а також, як це буває, саме те, що робить PassiveBot - обидві поводяться однаково), оскільки інтерпретатор замінює NNN на 0 відповідь по довжині.
Кінтопія

@quintopia я не намагався, просто зрозумів, коли набрав це, що він зручно працював як поліглот, але я не усвідомлював, що робив PassiveBot, тому я просто видалю Watcher (немає сенсу мати два однакових)
ХропінняFrog

2

Видалити зараженого (Python)

Незважаючи на всі випадкової логіки, я дуже це рідкісний для цього повернути нічого , крім Q і С. - х (превентивні заходи ніколи не здається , що корисно). Ну добре. Ви можете позичити частину для іншого бота, але залишити його на випадок, якщо це допоможе.

# Remove as many of it's own infected as possible, preferably by curing, but quarantining if it's getting out of hand
# If not very many can be cured, takes preventative measures (B,E,M, or V)

from sys import argv

CMDS=3
C_RATE=10
E_RATE=.08
M_RATE=4
Q_RATE=30
V_RATE=(1,.04)

def find_me(args):
    for player in args:
        player=player.split('_')
        if int(player[0])==me:
            return player

def actions_available():
    global actions
    if len(actions) < CMDS:
        return True
    else:
        return False

def add_actions(new_actions):
    global actions
    actions = (actions + new_actions)[0:CMDS]

def get_remaining_infected(local_infected):
    global actions
    return local_infected - (Q_RATE*actions.count('Q')) - (C_RATE*actions.count('C'))

def too_many_infected(local_infected):
    max_infected = C_RATE*(CMDS+1) # If we can get down to 10 or less without quarantining, that's good
    if local_infected > max_infected:
        return True
    else: return False

def projection(infection_rate, remaining_infected, action):
    additional_M=0
    additional_E=0
    additional_V=0

    if action == "M":
        additional_M=1
    elif action == "E":
        additional_E=1
    else:
        additional_V=1

    M_level = M_RATE*(actions.count('M')+additional_M)
    E_level = E_RATE*(actions.count('E')+additional_E)
    V_level = (V_RATE[0]*(actions.count('V')+additional_V), V_RATE[1]*(actions.count('V')+additional_V))

    projection = infection_rate - M_level - V_level[0] + (remaining_infected * (contagion_rate - E_level - V_level[1])) 
    return int(projection)

def get_best_action(local_infected):
    global actions
    remaining_infected = get_remaining_infected(local_infected)

    # If we can leave no infected, do so
    if remaining_infected <= C_RATE and remaining_infected >= 0:
        return 'C'

    strategies = {'M':0, 'E':0, 'V':0,'C':min(remaining_infected,C_RATE)}

    pni = int(infection_rate + (remaining_infected*contagion_rate)) # predicted new infected
    strategies['M'] = pni - projection(infection_rate, remaining_infected, 'M')
    strategies['E'] = pni - projection(infection_rate, remaining_infected, 'E')
    strategies['V'] = pni - projection(infection_rate, remaining_infected, 'V')
    # any benefit to including P as an option? 

    #print(strategies)
    max_saved = 'C'
    for strat,saved in strategies.iteritems():
        if saved > strategies[max_saved]:
            max_saved=strat
        elif saved == strategies[max_saved]:
            #prioritize V because of it's extra benefit of reducind lethality_rate
            max_saved=max(strat,max_saved) 

    if strategies[max_saved] <= C_RATE/2:
        # can't save that many, just close borders instead
        selected_action = 'B'
    else: selected_action = max_saved
    return selected_action


args = argv[1].split(";")
round = int(args.pop(0))
me = int(args.pop(0))
actions = ""

my_town = find_me(args)

local_infected = int(my_town[2])
infection_rate = int(my_town[4])
contagion_rate = int(my_town[5])/100.

if round!=50 and too_many_infected(local_infected):
    # Things are getting out of hand, quarantine and consider preventative measures
    actions = ('Q'*(local_infected/Q_RATE))[0:CMDS]

    while actions_available():
        add_actions(get_best_action(local_infected))
else: actions='CCC'

print ''.join(sorted(actions)) # always cure first

@Thrax Цього бота оновлено
SnoringFrog

2

CureThenKarantine, Java

Держава запровадила політику вилікування нечисленних щасливців, а потім проведення карантину на залишок інфікованих. Після зменшення зараженої популяції слід зосередити увагу на зниженні місцевих показників, а потім допомогти знизити глобальні показники.

Кордони закриті для запобігання міграції заражених в державу.

Я протестував бота лише на ботах java та python ... він, схоже, тримається проти них. Також здається, що мій бот поводиться схоже на CullBot.

public class CureThenQuarantine {
    static int playerID;

    public static void main(String[] args)
    {
        State thisState=null;

        args = args[0].split(";");

        // Parse arguments
        int round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        for (int i = 2; i < args.length; i++){
            thisState = new State(args[i]);
            if(thisState.isMine()){
                break;
            }
        }

        String action="";
        if(round == 1) action = "B"; // ensure no migration.
        else if (round == 50 ) action ="CCC"; // not much else we can do so just cure some people.

        // Highest Priority to Curing and then Quarantining infected, but do not perform either action if it would be wasteful.
        if (thisState.infected>9)
        {
            if (thisState.infected<19) action+="C";
            else if (thisState.infected<29) action+="CC";
            else if (thisState.infected<39) action+="CCC";
            else if (thisState.infected<49) action+="CQ";
            else if (thisState.infected<59) action+="CCQ";
            else if (thisState.infected<79) action+="CQQ";
            else action+="QQQ";
        }

        // Next priority is to reduce infection rate
        if (thisState.infectionRate>8) action+="MMM";
        else if (thisState.infectionRate>4) action+="MM";
        else if (thisState.infectionRate>1) action+="M";
        else if (thisState.infectionRate>0) action+="V";

        // then reduce contagion rate
        if (thisState.contagionRate>16) action+="EEE";
        else if (thisState.contagionRate>8) action+="EE";
        else if (thisState.contagionRate>1) action+="E";
        else if (thisState.contagionRate>0) action+="V";

        // and least priority is lethality rate... since we are only going to quarantine infected persons anyway.
        if (thisState.lethalityRate>8) action+="III";
        else if (thisState.lethalityRate>4) action+="II";
        else if (thisState.lethalityRate>1) action+="I";
        else if (thisState.lethalityRate>0) action+="V";

        // and if we have managed to clean up our state then we help others states.
        action+="PPP";

        System.out.println(action.substring(0,3));
    }

    static private class State {
        public int ownerId;
        public int lethalityRate;
        public int healthy;
        public int infected;
        public int infectionRate;
        public int contagionRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            healthy = Integer.parseInt(args[1]);
            infected = Integer.parseInt(args[2]);
            infectionRate = Integer.parseInt(args[4]);
            contagionRate = Integer.parseInt(args[5]);
            lethalityRate = Integer.parseInt(args[6]);
        }

        public boolean isMine(){
            return ownerId == playerID;
        }
        public String toString()
        {
            return "H: "+healthy+" I: "+infected+" IR: "+infectionRate+" LR: "+lethalityRate+" CR: "+contagionRate;
        }
    }
}

2

Дослідник, Java

Цей бот орієнтований на дослідження. Якщо кількість заражених нижче 15, вона намагається їх вилікувати. Якщо вона вища за це, він вибирає більш ефективне рішення .

public class Researcher {
    public static void main(String[] args){
        String[] args1 = args[0].split(";");
        int id = Integer.parseInt(args1[1]);
        for (int i = 2; i < args1.length; ++ i) {
            String[] args2 = args1[i].split("_");
            if (Integer.parseInt(args2[0]) == id) {
                int infected = Integer.parseInt(args2[2]);
                if (infected == 0) {
                    System.out.println("MEI");
                } else if(infected < 15) {
                    System.out.println("MEC");
                } else {
                    System.out.println("MEQ");
                }
            }
        }
    }
}

1
Ява мова, я припускаю ??
кіт

2

Шматка, Ява

На підставі мого попереднього бота (CureThenQuarantine) я виявив, що з агресивними ботами, які грають, немає необхідності в карантині, оскільки інфіковані загинуть дуже швидко, тому цей бот буде умовно вилікувати 10 заражених за кожну чергу (або приїжджаючи з міграції, або від інфекцій здорового населення). Потім вони використовуватимуть інші дії для того, щоб здорове населення залишалося здоровим, покладаючись на народження, щоб зміцнити здорове населення.

Кордони закриті для запобігання міграції заражених в державу.

public class Piecemeal{
    static int playerID;

    public static void main(String[] args)
    {
        State thisState=null;

        args = args[0].split(";");

        // Parse arguments
        int round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);

        for (int i = 2; i < args.length; i++){
            thisState = new State(args[i]);
            if(thisState.isMine()){
                break;
            }
        }

        String action="";
        if(round == 1) action = "B"; // ensure no migration.
        else if (round == 50 ) action ="CCC"; // not much else we can do so just cure some people.

        // Highest Priority to Curing up to ten infected if there are any.
        if (thisState.infected>0)
        {
            action+="C";
        }

        // Next priority is to reduce infection rate
        if (thisState.infectionRate>8) action+="MMM";
        else if (thisState.infectionRate>4) action+="MM";
        else if (thisState.infectionRate>1) action+="M";
        else if (thisState.infectionRate>0) action+="V";

        // then reduce contagion rate
        if (thisState.contagionRate>16) action+="EEE";
        else if (thisState.contagionRate>8) action+="EE";
        else if (thisState.contagionRate>1) action+="E";
        else if (thisState.contagionRate>0) action+="V";

        // and least priority is lethality rate... since we are only going to quarantine infected persons anyway.
        if (thisState.lethalityRate>8) action+="III";
        else if (thisState.lethalityRate>4) action+="II";
        else if (thisState.lethalityRate>1) action+="I";
        else if (thisState.lethalityRate>0) action+="V";

        // and if we have managed to clean up our state then we help others states.
        action+="PPP";

        System.out.println(action.substring(0,3));
    }

    static private class State {
        public int ownerId;
        public int lethalityRate;
        public int healthy;
        public int infected;
        public int infectionRate;
        public int contagionRate;

        public State(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            healthy = Integer.parseInt(args[1]);
            infected = Integer.parseInt(args[2]);
            infectionRate = Integer.parseInt(args[4]);
            contagionRate = Integer.parseInt(args[5]);
            lethalityRate = Integer.parseInt(args[6]);
        }

        public boolean isMine(){
            return ownerId == playerID;
        }
        public String toString()
        {
            return "H: "+healthy+" I: "+infected+" IR: "+infectionRate+" LR: "+lethalityRate+" CR: "+contagionRate;
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.