Четвертий чоловік


54

4-Чоловік Стандофф

Опис

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

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

Кожен гравець має 5здоров'я та вмирає, коли стан здоров'я падає до / нижче 0. Поворот гравця помирає - це останній крок, за який гравець може отримати шкоду.

Якщо в кінці протистояння є гравець у прямому ефірі, той грає. В іншому випадку виграє гравець з найменшим негативним здоров’ям.

Дії

  • Стріляйте : знімайте когось.

    • 2 пошкодження при стрільбі з живого ворога
    • 0 шкода, якщо стріляти по мертвому ворогу
    • health_at_start_of_turn+2пошкодження, якщо стріляти самостійно. (Зверніть увагу, що це залишить вас в НАЙКРАЩОМУ -2здоров'ї.)
    • Якщо один ворог стріляє в тебе в той же поворот, коли ти стріляєш сам, ти закінчиш протистояння з -4 здоров’ям (ти все одно спричиняєш шкоду від інших гравців, по черзі яких ти вбиваєш).
    • Ваша дія наступної черги буде проігноровано (і вважатиметься таким Nothing).
  • Додж : Спробуйте ухилитися від удару одного суперника.

  • Підготуйтеся : зніміть гранату і підготуйтеся кинути її.

    • У вас є лише три обороти, щоб кинути його, перш ніж ви підірветеся ( 6пошкодження себе, 3пошкодження всіх живих ворогів)
    • Вмирання з некинутою гранатою рівнозначно не кидати гранату протягом трьох оборотів.
  • Киньте : Вкиньте гранату на когось і сподівайтеся на краще.

    • Ціль отримує 8шкоду, якщо жива
    • Всі інші (включаючи себе) отримують 3шкоду, якщо живі
  • Нічого : стояти склавши руки на повороті і спостерігати, як усі помирають.

Вхідні дані

Вашій програмі буде передано таку інформацію:

  • Здоров’я кожного гравця
  • Перелік дій, здійснених цим гравцем з початку протистояння. Нижче наведено формат інформації, переданої на одного гравця:

    [Health],[Action 1],[Action 2],[Action 3],...
    

Дії будуть надані у форматі, визначеному в розділі Вихідні дані .

Ви отримаєте 4 такі рядки, розділені пробілом і передані як єдиний аргумент. Порядок цих рядків:

[Player Info] [Opponent 1 Info] [Opponent 2 Info] [Opponent 3 Info]

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

Наприклад:

$./Player.bash 5 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

На даний момент у гравця та другого суперника 3 здоров’я, у першого суперника 5 здоров’я, а у третього суперника -2 здоров’я і він мертвий.

Перша черга:

  • Гравець 1 вистрілив ворога 2
  • Ворог 1 підготував гранату
  • Ворог 2 стрілець
  • Ворог 3 застрелився

На другому ходу:

  • Усі гравці нічого не робили. (Гравець і противник 2 нічого не можуть зробити, оскільки вони вистрілили на попередньому рубежі. Ворог 3 мертвий: він зробить Nothingдля решти протистояння.)

Другий аргумент на початку протистояння є: 5 5 5 5.

Вихід

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

  • S[target]: Стріляє [ціль].
  • D[target]: Намагається ухилитися [ціль].
  • P: Підготуйте гранату.
  • T[target]: Киньте гранату в [ціль].
  • N: Нічого не робити.

Команда , яка потребує мети, але подається мета не між 0і 3чи не годували цілі повністю передбачатиметься цільовими 0(гравець).

Оцінка балів

В кінці кожного протистояння гравці отримують рахунок, обчислений за такою формулою:

35 + health at end of standoff 

У випадку, якщо гравець закінчить протистояння з негативним здоров'ям, він отримає бал нижче 35 . Наступні бали також винагороджуються як бонус:

  • Найбільше здоров'я: +4 бали
  • Другий за рівнем здоров'я: +2 бали
  • Третє за рівнем здоров'я: +1 бал.

У разі вирівнювання, нижчий бонус надається (якщо двоє людей мають кращий здоров’я, обом надається +2; якщо є 3 людини з найбільшим здоров’ям, +1, і якщо всі закінчуються однаково, +0).

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

Правила / подробиці

  • Порядок подій за чергою такий:
    • Усі гравці роблять свої дії.
    • Гравці, які мають 0 і менше здоров'я, гинуть.
    • Неврізані гранати, які повинні вибухнути, вибухнуть (гравці, які щойно загинули, все ще боляче, оскільки це ще черга, яку вони загинули).
  • Немає співпраці між записами.
  • Три протистояння відбудуться між кожним набором з 4 гравців. (Порядок гравців може змінюватися в залежності від протистояння).
  • Записи, що споживають надмірну кількість пам'яті місця на диску, будуть дискваліфіковані.
  • Читання з або змінення файлів, окрім записів, дискваліфікує ваш запис.
  • Вантажівка, керована п'яницею, перейде на всіх живих гравців після 50thповороту, якщо протистояння ще не закінчилося в кінці 50thповороту.
    • Цей вантажівка завдає 20 збитків всім гравцям, які живуть.
  • Залишки трапляються швидко. Програми відключаються через 1 секунду.
  • Ваша програма буде називатися щоразу, навіть після того, як ви померли.
  • Ви можете читати або записувати файли лише у свій каталог (якщо ваш запис названо JohnDoe, ви можете зберігати файли в програвачі програвачів / JohnDoe /); однак це не буде поточним каталогом під час запуску сценарію.
  • Протистояння відбуватимуться на машині під управлінням Arch Linux (випуск 2014.08.01).

Контролер доступний на GitHub .

Будь ласка, включіть у своє повідомлення:

  • Ім'я для вашого бота
  • Команда оболонки для запуску введення бота (наприклад java Doe.java) буде передана через командний рядок як єдиний аргумент ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")
  • Код вашого бота
  • Як слід скласти бот (якщо це застосовується)
  • Мова (та версія, якщо вона застосовується, особливо для python)

* Контролер занадто довго проходить шлях на шість.

Табло

                      Observer 43.280570409982
                   MuhammadAli 43.134861217214
                         Osama 43.031983702572
                    LateBoomer 42.560275019099
                 SimpleShooter 42.412885154062
             LessSimpleShooter 42.3772
                           Neo 42.3738
                        Scared 42.3678
                     Richochet 42.3263
                   Equivocator 42.2833
  TwentyFourthsAndAHalfCentury 42.2640
                        Darwin 42.1584
                       HanSolo 42.1025
                        Coward 42.0458
           ManipulativeBastard 41.8948
                        Sadist 41.7232
                     Aggressor 41.7058
                 CourageTheDog 41.5629
                     Grenadier 40.9889
                     Bomberman 40.8840
                         Spock 40.8713
                        Sniper 40.6346
                 DONTNUKEMEBRO 39.8151
               PriorityTargets 39.6126
                     Hippolyta 39.2480
                     EmoCowboy 39.2069
                      Zaenille 39.1971
                 AntiGrenadier 39.1919
      PoliticallyCorrectGunman 39.1689
                 InputAnalyzer 39.1517
                      Rule0Bot 39.1000
                     BiasedOne 39.0664
                      Pacifist 39.0481
               StraightShooter 39.0292
                         Ninja 38.7801
                           MAD 38.2543
                        Monkey 37.7089
                   Label1Goto1 36.2131
Generated: 2014/08/22 03:56:13.470264860 UTC

Журнали: на GitHub


1
У вас рівно одна граната, чи у вас багато? Ви можете одночасно готувати кілька гранат?
isaacg

2
@Bob Досить впевнений, що EmoWolf додали до стандартних лазівки, які вже не смішні . Хоча суїцидальний вступ може насправді не так страшно.
es1024

3
Урок усім: Не пити та не їздити.
Марк Габріель

8
@ es1024 Якщо самогубство насправді є життєздатною стратегією, справді слід дозволити подання EmoWolf. Особливо, коли доступні дії явно включають самогубство! Зараз не стільки «лазівка», чи не так? І не дуже несправедлива перевага, якою є більшість цих лазів. Але це лише моя думка.
Боб

3
На основі запуску контролера кілька разів, це здається досить галасливим. Якщо цей конкурс коли-небудь закриється, вам, ймовірно, слід збільшити кількість пробіжок, щоб трохи його згладити.
Девіс Йосіда

Відповіді:


7

Спостерігач

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

Перекласти: javac Observer.javaЗапустити:java Observer arg0 arg1

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

class Observer {
    private static List<Integer> aggressiveEnemies = new ArrayList<>();
    private static List<Integer> enemyGrenadiers = new ArrayList<>();
    private static List<Integer> aliveEnemies = new ArrayList<>();

    public static void main(String[] args) {
        if (args[1].length() <= 7) { //first round
            Random rand = new Random();
            printResult("D" + (rand.nextInt(3) + 1));
        }
        String players[] = args[1].split(" ");

        if (truckIsOnWay(players[0])) {
            printResult("P");
        }       

        calcEnemyInfo(players);

        // end this standoff now
        if (truckWillHit(players[0])) {
            if (isGrenadier(players[0]))
                printResult("T" + aliveEnemies.get(0));
            else
                printResult("S0");
        }

        // shoot enemy who is not aggressive
        if (aggressiveEnemies.size() == 0) {
            printResult("S" + aliveEnemies.get(0));
        }

        // only one enemy to handle
        if (aggressiveEnemies.size() == 1) {
            String player = players[aggressiveEnemies.get(0)];
            if (isGrenadier(player)) {
                printResult("S" + aggressiveEnemies.get(0));
            } else if (shotLastTurn(player, aggressiveEnemies.get(0))) {
                //safe to shoot him without receiving damage
                printResult("S" + aggressiveEnemies.get(0));
            } else {
                printResult("D" + aggressiveEnemies.get(0));
            }
        }

        // multiple aggressive enemies
        if (enemyGrenadiers.size() > 0) {
            printResult("S" + enemyGrenadiers.get(0));
        } else {
            int id = aggressiveEnemies.get(0);
            for (int playerId : aggressiveEnemies) {
                if (!shotLastTurn(players[playerId], playerId)) {
                    id = playerId;
                }
            }
            printResult("D" + id);
        }
    }

    private static void printResult(String result) {
        System.out.print(result);
        System.exit(0);
    }

    private static boolean isAlive(String player) {
        return !(player.charAt(0) == '-' || player.charAt(0) == '0');
    }

    private static void calcEnemyInfo(String[] players) {
        for (int i = 1; i < players.length; i++) {
            if (isAlive(players[i])) {
                aliveEnemies.add(i);
                if (isAggressive(players[i], i)) {
                    aggressiveEnemies.add(i);
                }
                if (isGrenadier(players[i])) {
                    enemyGrenadiers.add(i);
                }
            }
        }
    }

    private static boolean truckIsOnWay(String player) {
        return player.length() - player.replace(",", "").length() == 48;
    }

    private static boolean truckWillHit(String player) {
        return player.length() - player.replace(",", "").length() == 49;
    }

    private static boolean isAggressive(String player, int id) {
        return (player.contains("S") || player.contains("P")) && !player.contains("S" + id);
    }

    private static boolean isGrenadier(String player) {
        return player.contains("P");
    }

    private static boolean shotLastTurn(String player, int id) {
        return player.charAt(player.length() - 2) == 'S' && !player.contains("S" + id);
    }
}

!player.contains("S" + id)це необхідна умова у функції "isAggressive"? Суїцидальний гравець все одно буде мертвим
Крінчер

22

Гренадер

Гармати завищені. А справжнє протистояння Шотландського виглядає наступним чином :

  • Підготуватися
  • Киньте на ворога найбільше здоров’я
  • Повторіть (якщо якимось дивом ви ще живий)

Хоча це здається тривіальним, це, мабуть, не страшна стратегія. Так як гармати і гранати обидва мають два-обороту циклу, це, безумовно , більш ефективний 1 спосіб боротьби збиток.

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

public class Grenadier {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;

        if(list[0].charAt(list[0].length()-1) != 'P'){
            System.out.print("P");
            return;
        }

        int target = 1;
        for(int i=2;i<4;i++)
            if(list[i].charAt(0)>list[target].charAt(0))
                target = i;

        System.out.print("T"+target);
    }
}

Скомпілювати / запустити стандартним способом Java:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 Безглузда виноска


41
hahaha виноска
гордий haskeller

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

@Cruncher Ви, мабуть, праві. Ерік сказав у чаті те саме. Я сказав йому, що мій хлопець не вірить у зброю і занадто впертий, щоб використовувати цю логіку, тому він виклав цю стратегію. Однак я все-таки вважаю, що це буде більш ефективним , якщо ми будемо чітко говорити про завдану шкоду. Це не означає, що він більш ефективний у виграші гри. Навіть якщо я загину на третьому ходу, моя друга граната все одно згасне. Тож якщо я доживу до цього, це гарантовано 6+ шкоди для всіх, гра закінчена.
Геобіць

@Geobits зараз, коли я думаю про це, це може бути краще. Найважливіше - дельта між вами та противниками. Коли граната підірветься, ви отримуєте +3 дельти, з ким кинули її, і +0 з рештою. Сітка +3. Стрільба. Ви отримуєте +2 дельту, з ким стріляєте. +0 з рештою. Я думаю, проблема полягає в тому, що ти -3 з людьми, які вже померли. Ви повинні стріляти, якщо хтось загинув :)
Cruncher

2
@codebreaker Ніколи не грав. Це реальна життєва орієнтир.
Геобіц

16

Асимов Правило № 0 Бот - Пітон

Робот може не нашкодити людству або, завдяки бездіяльності, дозволити людству заподіяти шкоду.

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

import sys

def total_humans_alive(humans):
  return sum([is_alive(human) for human in humans])

def is_alive(x):
  return int(x.split(",")[0]) > 0  

def is_threat_to_humanity(lastAction):
  return lastAction == "P"

action = "N"
threat_id = 1
humans = sys.argv[2].split()[1:];

if total_humans_alive(humans) == 3:
  for human in humans:
    if is_threat_to_humanity(human[-1]):
      action = "S" + str(threat_id)
      break
    threat_id= threat_id+ 1

print action

Виконайте це так:

python rule0bot.py

2
Ваш робот нелогічний. Якщо гравець, який тримає гранату, кидає, людство завдає 8 + 3 + 3 + 3 = 17 збитків. Якщо ви вб'єте його пострілом, людство завдає 2 + 6 + 3 + 3 + 3 = 17 збитків. В обох сценаріях той, хто підриває гранату, приймає 8, а всі інші беруть 3 (якщо вони раніше не вмерли). Людство в цілому не впливає. Мені все одно подобається. +1: D
Геобіт

4
Власне, найкращий сценарій для людства - сподіватися, що гранату
кинуто

1
@Geobits Не намагається зупинити когось, хто загрожує проти природи роботів. Це спробує зупинити когось, хто тримає гранату, щоб не допустити поранення більшості (інших двох). Ви читали я, робот? Цю логіку підтримують Little Lost Robot та The Evitable Conflict.
Вільям Барбоса

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

2
+1 Я не згоден з голосом Кайла Каноса і хочу його визнати недійсним. Також Геобіт помиляється, вважаючи, що це нічого не допомагає людству. Звичайно, людство може не вийти кращим за найгіршого сценарію, але якщо двоє інших гравців вистріляють з гранати, що володіє душем, то їм все краще.
FreeAsInBeer

14

Хан Соло - Пітон

Хан вистрілив першим. У цьому випадку він вистрілить першим, вибравши найближчу ціль у живих.

import sys

def is_alive(player):
  return int(player.split(",")[0]) > 0

closest_living_target = 1;

for player in sys.argv[2].split()[1:]:
  if is_alive(player):
    action = "S" + str(closest_living_target)
    break

  closest_living_target = closest_living_target + 1

print action

Виконайте це так:

python hansolo.py

Примітка . Це перше, що я коли-небудь писав у Python, тому, якщо ви бачите якісь питонські погані практики, будь ласка, повідомте мене про це.


1
стиль pep8 передбачає, що ваш метод повинен бутиis_alive
Daenyth

4
@WilliamBarbosa погляньте на pep8, це посібник із стилів пітона, яким користуються всі. legacy.python.org/dev/peps/pep-0008
Daenyth

2
Вітаємо вас з тим, що це єдиний бот із середнім здоров'ям, більшим за 0, у раунді 8/11.
isaacg

6
IMO, "посібники зі стилів" - це перукарі, а не програмісти.
Кайл Канос

2
@KyleKanos Хоча приємно мати певну консистенцію. Я маю на увазі, якщо половина розробників проекту використовує кейс верблюда, а інша половина таких типів, результат буде "blergh"
Вільям Барбоса

12

EmoCowboy

Навіщо чекати померти? Просто вбий себе зараз. Сподіваємось, решта дурнів підірватиметься набагато менше -2.

Оцінка зазвичай буде -2. Іноді -4, якщо люди вирішили відстріляти мене. Рідко більше, ніж це означає, що це повинно перемогти декілька поточних матеріалів.

Пітон

print('S0')

python EmoCowboy.py

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


11

Пацифіст

Він справжній набряклий хлопець, просто потрапив у неправильну юрбу.

main = putStr "N"

Виконати як runghc pacifist.hs, але ви можете скомпілювати його з -O3, якщо ефективність викликає проблеми.


1
Будь ласка, перейменуйте його на Луїджі, і давайте подивимось, чи він щось виграє!
Вільям Барбоса

1
@WilliamBarbosa Luigi? Ти сказав Луїджі ?
вбивчий

7
Лол ніби -O3робить чудовисько різницею.
Томмедінг

@tomsmeding Це повільно на runghcбоці. Насправді це в 10 разів повільніше на моїй скриньці Linux.
Рей

5
Це означає наявність насильства, наслідки, які наш пацифіст не готовий впоратися
убивчий

9

Мавпа - Python (перший в історії!)

Мавпа бачить мавпа робить. Повториться саме остання дія, зроблена випадковим гравцем.

import sys, random
targetData = sys.argv[2].split()[random.randint(0,3)]
print(targetData.split(',')[len(targetData.split(','))-1])

Можна запустити так: "python monkey.py args" Не потрібні додаткові кроки.


2
Я сподіваюся, що вони не стріляли у вас! Python підтримує індекси негативного масиву, тому вам не потрібно обчислювати довжину і віднімати один; просто використовуйте -1безпосередньо.
змагальний

@comperendinous Скажіть, що я S3 у своєму списку. Якщо я виконаю S3, він не почне дурити мене. Також індекс -1 поверне останній елемент? Якщо так, круто! Я обов’язково додам.
Elias Benevedes

І не забувайте перший (цілий) аргумент. Вам потрібно argv[2]отримати історію гравців.
змагальний

Просто сподівайтеся, що ви не зрівняєтеся з Emo Cowboy.
codebreaker

6

Простий шутер - Perl (виправлена ​​помилка)

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

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$target = 1;
for(2..3){
 if($history[$_][0] >= $history[$target][0]){$target = $_}
}
print "S$target"

Ось як це запустити за допомогою прикладу введення:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

Ого. Простий і розумний.
Soham Chowdhury

6

Спок, в Python 3.x

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


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

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

Те, як Спок грає в решті гри, можна підсумувати його відомою цитатою: " Потреби багатьох переважають над потребами кількох ". Іншими словами, Спок повинен переконатися, що понесе найменшу шкоду, вбивши тих, хто це завдає. Як він це робить:

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

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


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

def IsAlive(player):
  return int(player[1].split(",")[0]) > 0
def IsTarget(player, target_health):
  return int(player[1].split(",")[0]) < target_health
def HasGrenade(player):
  max_range = max(-4,-current_turn)
  for foo in range(-1,max_range,-1):
    if "P" in player[1].split(",")[foo]:
      for bar in range(-1,foo-1,-1):
        if player[1].split(",")[bar] not in ["T0", "T1", "T2", "T3"]:
          return True
  return False

import sys
info_list = sys.argv[2].split()
current_turn = len(info_list[0].split(","))
action = "N"

def Startgame():
  global action

  target = 1
  target_health = 5
  grenade_list=[]

  for player in zip(range(1,4),info_list[1:]):
    if HasGrenade(player):
      grenade_list.append(player)

  if not grenade_list:
    foo_list = []
    for player in zip(range(1,4),info_list[1:]):
      foo_list.append(player)
    target_list = foo_list
  else:
    target_list = grenade_list

  # Choose the least healthy player
  for player in target_list:
    if IsAlive(player) and IsTarget(player, target_health):
      target = player[0]
      target_health = int(player[1][0])

  action = "S" + str(target)

def Endgame(turn):
  global action

  if turn in [47, 49]:
    # Check if in 2 moves he can do enough damage
    rem_health = 0
    for player in zip(range(1,4),info_list[1:]):
      if IsAlive(player): rem_health += player[0]

    if rem_health < 5:
      Startgame() # It's lazy, but it should work
      return
    else:
      action = "P"
      return

  if turn in [48, 50]:
    # If Spock shot someone before, it needs to shoot again
    if info_list[0].split(",")[-1] in ["S0", "S1", "S2", "S3"]:
      Startgame()
      return
    else:
    # There's no rule against throwing grenades to dead bodies, so if
    # possible it will be thrown there.    
      target = 1
      target_health = 5

      foo_list = []
      for player in zip(range(1,4),info_list[1:]):
        foo_list.append(player)
      target_list = foo_list

      for player in target_list:
        if IsTarget(player, target_health):
          target = player[0]
          target_health = int(player[1][1])

      action = "T" + str(target)
      return

if current_turn > 46:
  Endgame(current_turn)
else:
  Startgame()

print(action)

Виконайте це так:

python spock.py

2014-08-12 - Незначна помилка щодо виявлення гранати
2014-08-14 - Незначна помилка щодо кінцевої гри, завдяки isaacg за її вказівку раніше


Вам не дозволяється стріляти більше одного разу на два раунди. Прочитайте специфікацію про зйомки.
isaacg

@isaacg Дякую за нагадування (яке пояснює поведінку), але, схоже, є деякі приховані помилки. Наприклад, у цьому Споку слід було застрелити InputAnalyser, оскільки у нього була граната (навіть якщо у Соло було б більше 2 здоров'я).
Докторо Рейхард

Traceback (most recent call last): File "./players/Spock/Spock.py", line 87, in <module>: Endgame(current_turn) File "./players/Spock/Spock.py", line 79, in Endgame: if IsTarget(player, target_health): File "./players/Spock/Spock.py", line 4, in IsTarget: return int(player[1].split(",")[0]) < target_health TypeError: unorderable types: int() < str()
es1024

player[1][1]повинно бути int(player[1][1]).
isaacg

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

5

Політично коректний Ганман

Дуже політично коректно, оскільки це не дискримінує нічого. Таким чином, це не дуже розумно.

import random

array = ["P", "N", "S0", "S1", "S2", "S3", "D1", "D2", "D3", "T1", "T2", "T3"]

print(array[random.randrange(0,11)])

Це ... не важливо, які аргументи передаються йому як. python politicallycorrectgunman.py


Я не думаю, що квадратні дужки повинні бути частиною результату. Можливо, @ es1024 може це підтвердити. А ви знаєте про random.choice? Це чудово підходить для подібних виділень.
змагальний

перед дією та ціллю у виході не може бути нічого, хоча все після цього ігнорується
es1024

Це краще виглядає @ es1024?
Скасувати

@Undo Так, ідеально працює зараз
es1024

7
Не могли ви просто використати random.choice(array)?
user2357112

5

Прямий шутер

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

print('S2')

Perl, Python 2/3, Ruby: цей кінь справді є поліготом.

Я все одно виграю. Я не можу програти. Ви можете застрелити мене, але ви не можете мене вбити. Пан Ед мене не лає!

Для відповіді, яка має трохи більше роздумів (і деякої функціональної парадигми), див. « Двадцять четверте і півстоліття» .


5

Анти-гренадер

Гранати погані. Дуже погано. Тож якщо хтось готує, найкраще - це застрелити їх. Інакше ми просто повісимось.

-- Antigrenadier
local args = {...}  -- command line arguments

match = args[2]     -- store the set of matches

-- why this isn't standard in Lua....
function string:split( inSplitPattern, outResults )
  if not outResults then
    outResults = { }
  end
  local theStart = 1
  local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  while theSplitStart do
    table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
    theStart = theSplitEnd + 1
    theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  end
  table.insert( outResults, string.sub( self, theStart ) )
  return outResults
end

-- set up the players
players = match:split(" ")

-- search other players for someone who pulled a grenade
for i=2,#players do
   moves = players[i]
   -- test if person is alive
   if moves:sub(1,1) ~= "-" then
      -- cycle through all elements of the string
      for j=#moves,2,-1 do
         -- if found, shoot!
         if moves:sub(j,j) == "P" then
            print("S"..i-1)
            os.exit()
         end
      end
   end
end

-- otherwise we just relax
print("N")

4

Рікочет - Перл

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

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$health = $history[0][0];
@options = ();
for(1..3){
 if($history[$_][0] > 0){
  push(@options,$_);
 }
}
$target = @options[int(rand(~~@options))];
if(~~@{$history[0]} == 50){
 $target = 0;
}
print"S$target";

Бігайте так:

perl ricochet.plx 5 "-2,S0 -2,S1 -2,S2 5,N" 

4

Агресор

Тягнеться в перший раунд, кидає найвищого суперника здоров'я на 2-му раунді, після чого стріляє в суперника найвищого здоров’я.

#include <cstdio>
#include <cstring>

int main(int argc, char** argv){
   char* t;
   t = strtok(argv[2]," ");
   int len = strlen(t);
   int max = -50, maxP;
   for(int i=1;i<4;i++){
      int cur;
      t = strtok(NULL," ");
      if(t[0]=='-'){cur = -1*(t[1]-'0');}
      else{cur = t[0]-'0';}
      if(cur>max){
         max = cur;
         maxP = i;
      }
   }
   if(len == 1){printf("P\n"); return 0;}
   if(len == 3){printf("T%d\n",maxP); return 0;}
   printf("S%d\n",maxP);
   return 0;
}

Виконайте так ./agg ID "5 5 5 5".


4

Ніндзя

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

math.randomseed(os.time())
print("D"..tostring(math.random(4)-1))

бігти як

lua ninja.lua

Аргументи непотрібні, але їх можна додати без випуску.


2
@KyleKanos буде ніндзя ухилятися від власних пострілів?
skeggse

2
@distiiledchaos: ... так, так, так і буде.
Кайл Канос

4

Назва : PriorityTargets

Команда оболонки : ruby ​​PriorityTargets.rb 5 [game_state]

Мова : Ruby V2.1.2

Опис : PriorityTargets намагається знайти загальні стилі гри. Потім він вирішує, грунтуючись на тих стилях, кого хоче атакувати та яку зброю використовувати.

Примітка : Подання першого коду для гольфу! Набагато більше, ніж інші матеріали, тому що я трохи збожеволів.

#!/usr/bin/env ruby

class PriorityTargets
  class PlayerAction
    SHOOT = 'S'
    DODGE = 'D'
    PREPARE_GRENADE = 'P'
    THROW_GRENADE = 'T'
    NOTHING = 'N'
    attr_accessor :action, :target

    def initialize(action_string)
        @action = action_string[0, 1]
        @target = self.has_target? ? action_string[1, 1].to_i : false
    end

    def to_s
      string = @action
      string << @target.to_s if self.has_target?
      string
    end

    def has_cooldown?
      [SHOOT].include? @action
    end

    def is_aggressive?
      [SHOOT, PREPARE_GRENADE, THROW_GRENADE].include? @action
    end

    def has_target?
      [SHOOT, DODGE, THROW_GRENADE].include? @action
    end
  end


  class Player
    attr_reader :identifier, :health, :history
    attr_accessor :playstyles

    def initialize(player_identifier, player_string)
      @identifier = player_identifier
      @playstyles = []

      player_info = player_string.split(',')
      @health = player_info.shift.to_i
      @history = parse_history(player_info)
    end


    def has_attacked?(player, round = nil)
      round ||= self.history.length - 1
      player.history[0, round].each do |turn|
        did_attack = true and break if turn.is_aggressive? && turn.has_target? && turn.target == player.identifier
      end
      did_attack ||= false
    end

    def is_holding_grenade?(round = nil)
      round ||= self.history.length
      turn_history = self.history[0, round]
      is_holding = false

      turn_history.each_with_index do |turn, curr_round|
        if turn.action == PlayerAction::PREPARE_GRENADE && curr_round >= round - 3
          is_holding = true if turn_history.drop(curr_round).select{|turn| turn.action == PlayerAction::THROW_GRENADE }.length == 0
        end
      end

      is_holding
    end

    def is_dead?; self.health <= 0; end
    def is_on_cooldown?
      return false if self.history.length == 0
      self.history.last.has_cooldown?
    end

    def turn_at_round(round); self.history[round-1]; end

    private

      def parse_history(history_array)
        parsed = []
        history_array.each {|action_string| parsed << PlayerAction.new(action_string) }
        parsed
      end
  end

  class PlayerList
    include Enumerable

    def initialize(player_list = [], filter_list = false)
      @list = player_list
      @filter = filter_list if filter_list
    end

    #Enumerable Methods
    def each
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.each {|player| yield(player) }
    end

    def <<(player); @list << player; end
    def [](key)
      player = @list.select{|player| @filter.include?(player.identifier) }[key] if @filter
      player = @list[key] unless @filter
      player
    end

    def length
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.length
    end

    def empty?; self.length == 0; end
    def not_empty?; self.length > 0; end

    def create_filtered_list(player_ids)
      new_player_list = PlayerList.new(@list, player_ids)
      new_player_list
    end

    #PlayerList Methods
    def includes_playstyle?(playstyle)
      (self.with_playstyle(playstyle).length > 0)
    end

    def have_executed_action?(action)
      action_found = false
      self.each {|player| action_found = true and break if player.history.select {|turn| turn.action == action}.length > 0 }
      action_found
    end

    def direct_damages(round = nil)
      round ||= self.first.history.length

      damage_list = {}
      @list.each {|player| damage_list[player.identifier] = 0 }

      if round >= 1
        @list.each do |player|
          player.history[0, round].each_with_index do |turn, curr_round|

            if turn.has_target?
              target_player = @list.select{|curr_player| curr_player.identifier == turn.target }.first
              target_turn = target_player.turn_at_round(curr_round)

              damage_list[turn.target] += 8 if turn.action == PlayerAction::THROW_GRENADE

              if turn.action == PlayerAction::SHOOT
                damage_list[turn.target] += 2 unless target_turn.action == PlayerAction::DODGE && target_turn.target == player.identifier
              end
            end
          end
        end
      end

      damage_list.select! {|key| @filter.include? key } if @filter
      damage_list
    end


    def filtered_with_condition(&condition_block)
      player_ids = []
      self.each {|player| player_ids << player.identifier if condition_block.call(player) }
      create_filtered_list(player_ids)
    end

    def on_cooldown; filtered_with_condition {|player| player.is_on_cooldown?} end
    def not_on_cooldown; filtered_with_condition {|player| !player.is_on_cooldown?} end

    def dead; filtered_with_condition {|player| player.is_dead?} end
    def not_dead; filtered_with_condition {|player| !player.is_dead?} end

    def with_playstyle(playstyle); filtered_with_condition {|player| player.playstyles.include?(playstyle)} end
    def not_with_playstyle(playstyle); filtered_with_condition {|player| !player.playstyles.include?(playstyle)} end

    def with_max_health(round = nil)
      round ||= self.first.history.length
      player_damages = direct_damages(round)
      filtered_with_condition {|player| player_damages[player.identifier] == player_damages.values.min }
    end

    def with_identifier(identifier)
      matches = self.with_identifiers([ identifier ])
      return nil if matches.empty?
      matches.first
    end

    def with_identifiers(identifiers)
      create_filtered_list(identifiers)
    end
  end

  class PlayerTypes
    GRENADIER = :GRENADIER
    COWBOY = :COWBOY
    SKIDDISH = :SKIDDISH
    AGGRESSOR = :AGGRESSOR
    DEFENSIVE = :DEFENSIVE
    ANTI_GRENADIER = :ANTI_GRENADIER
    PLAYSTYLE_ORDER = [GRENADIER, COWBOY, SKIDDISH, AGGRESSOR, DEFENSIVE, ANTI_GRENADIER]

    def initialize(player_list)
      @players = player_list
    end

    def analyze_playstyles
      return if @players.first.history.length == 0

      PLAYSTYLE_ORDER.each do |playstyle|
        check_fnc = "is_"+playstyle.to_s+'?'
        @players.each {|player| player.playstyles << playstyle if self.send(check_fnc, player) }
      end
    end

    def is_GRENADIER?(player)
      #Grenade on first turn
      #Used more than one grenade
      #Never used gun, only grenade
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if player.history.first.action == PlayerAction::PREPARE_GRENADE
      profiled ||= true if grenade_count > 1
      profiled ||= true if shoot_count == 0 && grenade_count > 0
      profiled ||= false
    end

    def is_COWBOY?(player)
      #Never used grenade, only gun
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if grenade_count == 0 && shoot_count > 0
      profiled ||= false
    end

    def is_SKIDDISH?(player)
      #Dodged more than once
      #Never hurts anybody
      dodge_count = player.history.count {|turn| turn.action == PlayerAction::DODGE }
      attack_count = player.history.count {|turn| turn.is_aggressive? }

      profiled ||= true if dodge_count > 1
      profiled ||= true if attack_count == 0 && player.history.length > 1
      profiled ||= false
    end

    def is_AGGRESSOR?(player)
      #Only shoots person >= most health
      profiled = false
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          profiled = false if !@players.with_max_health(round).include? @players.with_identifier(turn.target)
        end
      end
      profiled
    end

    def is_DEFENSIVE?(player)
      #Only hurts people who hurt them first
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          profiled = false unless target_player.has_attacked?(player, round)
        end
      end
      profiled ||= false
    end

    def is_ANTI_GRENADIER?(player)
      #After a Grenadier has been shown, only shoots grenadier
      shots_fired = 0
      shots_fired_while_holding = 0

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          shots_fired += 1
          shots_fired_while_holding += 1 if target_player.is_holding_grenade?(round)
        end
      end

      (shots_fired > 0 && shots_fired/2.0 <= shots_fired_while_holding)
    end
  end




  def initialize(game_state)
    players_info = game_state.split(' ')
    @player = Player.new(0, players_info.shift)
    @players = PlayerList.new
    @players << @player
    enemy_identifiers = []

    players_info.each_with_index {|info, index| @players << Player.new(index+1, info); enemy_identifiers << index+1; }

    @enemies = @players.with_identifiers(enemy_identifiers  )
  end

  def analyze_playstyles
    types = PlayerTypes.new(@players)
    types.analyze_playstyles
  end

  def find_dodge_target
    armed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).not_on_cooldown().not_dead()

    if armed_aggressors.not_empty?
      return armed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return @enemies[Random.rand(3)] if @player.history.length == 0
    nil
  end

  def find_target
    unarmed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).on_cooldown().not_dead()
    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()
    grenadiers = @enemies.with_playstyle(PlayerTypes::GRENADIER).not_dead()
    cowboys = @enemies.with_playstyle(PlayerTypes::COWBOY).not_dead()
    skiddish = @enemies.with_playstyle(PlayerTypes::SKIDDISH).not_dead()
    defensive = @enemies.with_playstyle(PlayerTypes::DEFENSIVE).not_dead()

    if unarmed_aggressors.not_empty?
      return unarmed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return anti_grenadiers.with_max_health().first if anti_grenadiers.not_empty?
    return grenadiers.with_max_health().first if grenadiers.not_empty?
    return cowboys.with_max_health().first if cowboys.not_empty?
    return skiddish.with_max_health().first if skiddish.not_empty?
    return defensive.with_max_health().first if defensive.not_empty?
    return @enemies.with_max_health().not_dead().first if @enemies.with_max_health().not_dead().length > 0
    nil
  end

  def find_weapon
    return PlayerAction::THROW_GRENADE if @player.is_holding_grenade?

    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()

    return PlayerAction::PREPARE_GRENADE if anti_grenadiers.empty? && @enemies.have_executed_action?(PlayerAction::PREPARE_GRENADE)
    PlayerAction::SHOOT
  end

  def make_decision
    dodge_target = self.find_dodge_target
    target = self.find_target
    weapon = self.find_weapon

    decision ||= PlayerAction.new(PlayerAction::NOTHING) if @player.is_on_cooldown? || @enemies.with_max_health().not_dead().length == 0
    decision ||= PlayerAction.new(PlayerAction::DODGE + dodge_target.identifier.to_s) if dodge_target
    decision ||= PlayerAction.new(weapon + target.identifier.to_s)
    STDOUT.write decision.to_s
  end
end

priority_targets = PriorityTargets.new(ARGV[1])
priority_targets.analyze_playstyles
priority_targets.make_decision

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

На жаль, здається, що в ньому була помилка, яка створила гренадер. Ну добре, буде краще наступного разу :)
fingerco

3

Трус - перл

Діє дуже боягузливо. Коли він почуває себе здоровим, він вибирає ворога, який не відчуває цього, і стріляє в нього. Бонусні бали для тих ворогів, які стріляли в останню чергу (бо, як відомо, вони роблять Nothingцей поворот і тому бути абсолютно беззахисними). Коли він почуває себе не так добре, він біжить на прикриття, щоб врятувати свою сховку, випадково стріляючи в когось.

#!/usr/bin/perl

@allinfo = map { [split/,/] } split / /, $ARGV[1];
@life = map { $_->[0] } @allinfo;
@action = map { @$_>1 ? $_->[-1] : () } @allinfo;

if($life[0] < 3 && rand() < .5 )
{
    printf "D%d", +(sort { ($life[$a]>0)*($action[$a] eq "N") <=> ($life[$b]>0)*($action[$b] eq "N") } 1..3)[2]
}
else
{
    @score = map { $life[$_]>0 ? (5/$life[$_] + 2*($action[$_] =~ /S./)) : 0 } 1..3;
    printf "S%d", +(sort { $score[$a] <=> $score[$b] } 1..3);
}

Досить стандартний код Perl; збережіть його в якомусь файлі та запустіть perl file argument argument [...]. Я перевірив на синтаксис, і це було нормально, тому сподіваюся, що з цим не виникне проблем.

Е: усунув потенціал ділення на 0 помилок.


3

Бомбермен

Bot написано в R, командний рядок повинна бути: Rscript Bomberman.R arg0 arg1
я зрозумів , після того, як почав писати цей бот , який Geobits вже зробив гренадер , але я думаю , що моє значно відрізняється, в тому , що він перевіряє його здоров'я вище 3 перед приготуванням гранати, кидає його на останній стрілець перший, і найздоровіший другий, і якщо його здоров'я нижче 3, він ухилиться від небезпечного гравця (ні мертвого, ні стрільця в останньому раунді) або застрелить одного з гравців, що залишилися.

input <- commandArgs(TRUE)
history <- do.call(rbind,strsplit(scan(textConnection(input[2]),"",quiet=TRUE),","))
health <- as.integer(history[,1])
last_shooter <- which(grepl("S",history[-1,ncol(history)]))
last_prepare <- which(history[1,]=="P")
if(!length(last_prepare)) last_prepare <- -1
last_throw <- which(grepl("T",history[1,]))
if(!length(last_throw)) last_throw <- 0
most_healthy <- which.max(health[-1])
dead <- which(health[-1]<=0)
inoffensive <- c(last_shooter,dead)
danger <- which(!(1:3)%in%inoffensive)
alive <- which(!(1:3)%in%dead)
if(health[1]>3 & last_throw > last_prepare) out <- "P"
if(last_throw < last_prepare) out <- ifelse(length(last_shooter),paste("T",last_shooter[1],sep=""),paste("T",most_healthy[1],sep=""))
if(health[1]<=3 & last_throw > last_prepare){
    if(length(danger)){
        out <- paste("D",sample(danger,1),sep="")
    }else{
        out <- paste("S",sample(alive,1),sep="")
    }
}
cat(out)

Редагувати

Здається, що між цим ботом і контролером є певна проблема зв'язку, оскільки всі журнали, які я переглянув, показали, що мій бот тільки виводить N. Отже, ось той самий бот, але переписаний на Python, сподіваючись, що якщо у цього також буде проблема з комунікацією, хтось його побачить.
Для дзвінка з python Bomberman.py arg0 arg1.

import sys,re,random

history = sys.argv[2]
history = [k.split(",") for k in history.split()]
health = [k[0] for k in history]
last_turn = [k[-1] for k in history]
last_shooter = [i for i,x in enumerate(last_turn) if re.search(r'S[0-3]',x)]
last_prepare = [i for i,x in enumerate(history[0]) if x=='P']
if not len(last_prepare):
    last_prepare = [-1]

last_throw = [i for i,x in enumerate(history[0]) if re.search(r'T[0-3]',x)]
if not len(last_throw):
    last_throw = [0]

most_healthy = [i for i,x in enumerate(health) if x==max(health)]
dead = [i for i,x in enumerate(health) if x<=0]
inoffensive = last_shooter+dead
danger = [k for k in range(1,4) if k not in inoffensive]
alive = [k for k in range(1,4) if k not in dead]
if health[0]>3 and last_throw[-1] > last_prepare[-1]:
    out = 'P'

if last_throw[-1] < last_prepare[-1]:
    if len(last_shooter):
        out = 'T'+random.choice(last_shooter)
    else:
        out = 'T'+random.choice(most_healthy)

if health[0]<=3 and last_throw[-1] > last_prepare[-1]:
    if len(danger):
        out = 'D'+random.choice(danger)
    else:
        out = 'S'+random.choice(alive)

print(out)

Назва бота порівняно слабка, але у мене виникла ідея, якщо хтось може придумати краще ім’я, будь ласка, прокоментуйте його :)
plannapus

GymnastBomber !!
Cruncher

3

Нео

Додж живого гравця, який не стріляв останньою чергою. Якщо всі живі вистрілили в останню чергу, стріляйте у випадкового живого гравця. Самогубство, коли ви бачите фари.

import java.util.Random;
public class Neo {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;
        Random rand = new Random();
        int turn = list[0].split(",").length;
        if(turn == 49){
            System.out.print("S0");
            return;
        }
        int target=0;
        for(int i=1;i<4;i++)
            if(list[i].length()<2 || (list[i].charAt(0)!='-' && list[i].charAt(list[i].length()-2)!='S'))
                target=i;
        if(target>0){
            System.out.print("D"+target);
            return;
        }
        while(target<1){
            int i=rand.nextInt(3)+1;
            if(list[i].charAt(0)!='-')
                target=i;
        }
        System.out.print("S"+target);
    }
}

Я не чекаю багато від цього хлопця проти гранатометів, але проти стрільців це може працювати досить добре. Ми побачимо.


У своїй відповіді я використав частину коду вашого котла . Я сподіваюся, що це нормально.
супектор

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.charAt(String.java:658) at Neo.main(Neo.java:17)
es1024

@ es1024 Слід піти зараз, і не робити нічого на кожному першому кроці.
Геобіт

2

Двадцять четверте і півстоліття

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

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

#!/usr/bin/env python
import sys
import random

## ==== Move Types ================================================== ##
def move_type (move):
    if "" == move:
        return "N"
    return move[0]

def is_passive_move (move):
    if "N" == move:
        return True
    if "D" == move_type (move):
        return True
    return False

def is_aggressive_move (move):
    return not is_passive_move (move)

def passive_moves (moves):
    return [m for m in moves if is_passive_move (m)]

def aggressive_moves (moves):
    return [m for m in moves if is_aggressive_move (m)]
## ================================================== Move Types ==== ##

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health, moves):
        self.number = number
        self.health = health
        self.moves  = moves

    def last_move (self):
        if 0 == len (self.moves):
            return ""
        return self.moves[-1]

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())
    moves = [move.strip () for move in x[1:]]

    return Player (number, health, moves)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def can_shoot (player):
    return "S" != move_type (player.last_move ())

def is_passive (player):
    passive_move_count = len (passive_moves (player.moves))
    aggressive_move_count = len (aggressive_moves (player.moves))

    return passive_move_count > (aggressive_move_count + 1)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_who_can_shoot (players):
    return [p for p in players if can_shoot (p)]

def players_who_stand_around (players):
    return [p for p in players if is_passive (p)]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def dodge_one_of_the (potential_shooters):
    chosen_shooter = random.choice (potential_shooters)
    return "D{0}".format (chosen_shooter.number)

def do_nothing ():
    return "N"

def pick_move (game_state):

    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    living_enemies = players_who_can_breathe (enemies)
    if 1 == len (living_enemies):
        return shoot_randomly_at (living_enemies)

    passive_enemies = players_who_stand_around (living_enemies)
    if len (living_enemies) == len (passive_enemies):
        return shoot_randomly_at (passive_enemies)

    potential_shooters = players_who_can_shoot (living_enemies)
    if 0 < len (potential_shooters):
        return dodge_one_of_the (potential_shooters)

    return do_nothing ()
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

Виконувати як:

python twenty-fourth-and-a-halfth-century.py 0 "5 5 5 5"

2

Налякані

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

import sys
import random


def is_alive(player):
    return int(player.split(",")[0]) > 0


# Anyone with a live grenade who is alive is dangerous
def is_dangerous(player):
    return player.count("P") > player.count("T") and \
        int(player.split(",")[0]) > 0


def health(player):
    return int(player.split(",")[0])


# Failing that, healthy people are dangerous
def danger_rating(player):
    return 6 if is_dangerous(player) else health(player)

enemies = sys.argv[2].split()[1:]

highest_danger = max(danger_rating(enemy) for enemy in enemies)
most_dangerous_enemy = random.choice(
    [enemy_num+1 for enemy_num in range(len(enemies))
     if danger_rating(enemies[enemy_num]) == highest_danger])

print("S"+str(most_dangerous_enemy))

Це python (2 або 3, такий же результат у будь-якому.) Зберегти як scared.py, запуститиpython3 scared.py


2

Маніпулятивний ублюдок - пітон

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

import sys

def health(p):
    return int(p[0])

def is_alive(p):
    return health(p) > 0

def can_act(p):
    return is_alive(p) and p[-1][0] != 'S'

def can_throw(p):
    return is_alive(p) and p[-1][0] == 'P'

def shot_first(p):
    if len(p) == 1:
        return False
    return p[1][0] == 'S'

def act(a):
    print a
    sys.exit(0)

player = sys.argv[2].split()[0].split(',')
enemies = [e.split(',') for e in sys.argv[2].split()[1:]]
healthiest = sorted(enumerate(enemies, 1), key=lambda e:health(e[1]))[-1]
alive = sum(is_alive(e) for e in enemies)

if alive == 1:
    i, e = healthiest
    if health(e) <= 2 and not can_act(e):
        act('S%d' % i)
    if can_throw(player):
        act('T%d' % i)
    if can_throw(e):
        act('S%d' % i)
    if can_act(e) and shot_first(e) and len(player) < 40:
        act('D%d' % i)
    if len(player) > 45:
        act('P')
    act('S%d' % i)

if can_throw(player):
    i, e = healthiest
    act('T%d' % i)

if len(player) > 45:
    act('P')

if health(player) <= 2 or any(can_throw(e) for e in enemies) or alive == 2:
    i, e = healthiest
    act('S%d' % i)

act('P')

2

Осама

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

module Main where

import Data.List
import Data.Ord
import System.Environment

words' "" = []
words' s = s' : words' (tail' s'')
  where
    (s', s'') = break (==',') s
    tail' (',':r) = r
    tail' r = r

nRound = length . words'

lastAction = last . words'

health :: String -> Int
health = read . head . words'

alive = (>0) . health

grenadeAge :: String -> Int
grenadeAge p | not (alive p) = 0
             | otherwise = g 0 $ tail $ words' p
  where
    g n (a:b:r) | head a == 'S' = g (if n>0 then n+2 else 0) r
    g 0 ("P":r) = g 1 r
    g n (('T':_):r) | n>0 = g 0 r
    g n (_:r) | n>0 = g (n+1) r
    g n (_:r) = g n r
    g n [] = n

prepared :: String -> Bool
prepared p = alive p && head (lastAction p) /= 'S'

nShotMe = length . filter (=="S0") . words'

getPlayer = (!!)

action players@(me:them) | not (prepared me) = "S2" -- bogus
                         | nRound me >= 49 = "S0"
                         | grenadeAge me >= 1 = 'T':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | any prepared them && nRound me > 0 = 'D':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | otherwise = 'S':(show $ maximumBy (comparing (health . getPlayer players)) l)
  where l = filter (alive . (getPlayer players)) [1..3]



main = do
  players <- fmap (words . head . tail) getArgs
  putStrLn $ action players

Компілюйте ghc -O2 osama.hs, а потім запустіть ./players/Osama/osama.


2

Снайпер - Луа

З першого ж повороту він застрелить випадкову людину, потім застрелить будь-яких гравців, яких він може вбити (2 або 1 здоров'я). Якщо жоден з цих не буде працювати, він спробує застрелити гравця, який останній його вистрілив, інакше він запустить випадкового гравця. Бігайте зlua Sniper.lua

turns = arg[2]
health = string.sub(turns, 1, 1)
--make random numbers random
math.randomseed(io.popen("date +%s%N"):read("*all"))
math.random(); math.random(); math.random()
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end
enemies = Split(turns, " ")
--first turn
if #enemies[1] == 1 then
  print(string.format("S%i",math.random(1,3)))
  os.exit()
end
--kills if possible
for enemy=1,3 do
  if (tonumber(string.sub(enemies[enemy + 1],1,1)) or 0) < 3 and string.sub(enemies[enemy + 1],1,1) ~= "-" then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--shoots the last person that shot at it
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],#enemies[enemy + 1]-1) == "S0" and tonumber(string.sub(enemies[enemy + 1],1,1)) > 0 then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--otherwise shoot a random alive person
local aliveEnemies = {}
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],1,1) ~= "-" then
    aliveEnemies[#aliveEnemies+1]=enemy
  end
end
print(string.format("S%i",math.random(1,#aliveEnemies)))

Він фактично буде запущений спочатку додатковим аргументом; наприклад, lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". Можливо, вам доведеться перевірити свій argіндекс.
змагальний

@comperendinous, дякую, виправлено зараз
waylon531

Привіт, @ waylon531, питання про Луа: випадкове насіння math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" недостатньо для рандомізації сценарій?
AndoDaan

1
AndoDaan, згідно з lua-users.org/wiki/MathLibraryTutorial, деякі ОС завжди повертають те саме число під час першого виклику math.random ().
waylon531

lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberстек ./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
прослідкування

2

Дарвін

Виживання найбільш придатних означає, що найменш здоровий повинен померти.

Обґрунтування

З огляду на сукупність результатів від вівторка (12), схоже, існує три чіткі групи: вижили; ефективно самогубні; і гірше, ніж марне. Вцілілі люди поділяють прості стратегії на основі стрілянини. У той час як пара інших ботів ( Спок , Трус ) націлюватиметься на найменш здорового ворога, вони також ускладнюють свої стратегії з іншими діями. Цього немає. Як і простий шутер , він має чітке визначення цілі і невпинно дотримується її. Буде цікаво подивитися, де воно вписується в результати.

#!/usr/bin/env python

import sys
import random

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health):
        self.number = number
        self.health = health

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())

    return Player (number, health)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_by_health (players):
    return sorted (players, key=lambda p: p.health)

def least_healthy_players (players):
    sorted_living_players = \
        players_by_health (players_who_can_breathe (players))
    lowest_living_health = sorted_living_players[0].health
    return [p for p in players if lowest_living_health == p.health]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def do_nothing ():
    return "N"

def pick_move (game_state):
    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    least_healthy_enemies = least_healthy_players (enemies)
    return shoot_randomly_at (least_healthy_enemies)
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

Це позбавлена, трохи модифікована версія моєї попередньої « Двадцять четвертого і півстоліття» , яка ділиться своїм покликанням:

python darwin.py 3 "5 5 5 5"

2

Зенілле - С

Пріоритети:

  1. Стріляйте, якщо зліва 1 на 1
  2. Стріляйте в гранадерів
  3. Dodge
  4. Нічого (просто дещо плутати)

Компілювати з gcc <filename.c> .

Бігайте з ./a.out <parameters>.

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

int main(int argc, char *argv[]){
    char* input = argv[2];
    int enemyCount=1;
    int aliveCount=0;
    int aliveEnemy=0;

    //default
    char action = 'N';
    int target = NULL;

    const char delim[1] = " ";
    char *token;

    //first turn
    if(strcmp(input,"5 5 5 5")==0){
        printf("D1");
        return 0;
    }

    token = strtok(input, delim);
    token = strtok(NULL, delim); //skip to the first enemy

    while(token != NULL){
        //if someone is alive :
        if(strstr(token,"-")==NULL && token[0]!='0'){
            aliveCount++;
            aliveEnemy=enemyCount;
            //if that person did nothing this turn, take it as a tip that he will shoot next turn, and dodge
            if(strstr(token, "N")!=NULL){
                action = 'D';
                target=enemyCount;
            }

            //if that person prepared a grenade, shoot him down
            if(strstr(token, "P")!=NULL){
                action = 'S';
                target=enemyCount;
            }
        }

        token = strtok(NULL, delim);
        enemyCount++;
    }

    //if there is 1 enemy left, shoot him down
    if(aliveCount==1){
        action='S';
        target=aliveEnemy;
    }

    printf(action=='N'?"N":"%c%d",action,target);

    return 0;
}

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

Дійсно? Д: Дякую @comperendinous. Відредагує код.
Марк Габріель

2

Вхідний аналізатор

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

Редагувати: Я зараз

  1. ухиляйтесь від будь-якого гравця, який має живу гранату
  2. більше не намагатимусь збивати / кидати / ухилятися.

import System.Environment   
import Data.Char (ord)
import Data.List.Split

main = do 
    args <- getArgs
    let secondArg = (last args)
    let opt = (argCount secondArg 0)
    let list = (splitOn " " secondArg)
    let enemysToCheck = [1,2,3]
    let target = (avoidShootingSelf (findTarget (last args) 0 0 0 0))
    putStrLn (decide list enemysToCheck opt target)

argCount :: String -> Int -> Int
argCount (s:str) i
    |(length str) == 0 = i `mod` 4
    | otherwise = (argCount str (i + (ord s)))

--myPseudo takes number 0-3, and a possible target and translates it to a command 
myPseudo :: Int -> Int -> String
myPseudo 0 b = "S" ++ (show b)
myPseudo 1 b = "D" ++ (show b)
myPseudo 2 b = "P"
myPseudo 3 b = "T" ++ (show b)

decide :: [String] -> [Int] -> Int -> Int -> String
decide [] [] a b = (myPseudo a b)
decide (x:xs) [] a b = (myPseudo a b)
decide xs (y:ys) a b
    | (liveGrenade z 0) == True = "D" ++ (show y)
    | otherwise = (decide xs ys a b)
    where z = xs!!y

--checks if a player has a live grenade
liveGrenade :: String -> Int -> Bool
liveGrenade [] a = a > 0
liveGrenade (s:str) a
    | s == 'T' = (liveGrenade str (a - 1))
    | s == 'P' = (liveGrenade str (a + 1))
    | otherwise = (liveGrenade str a)

--findTarget picks a target by doing some irrelevant string processing on the 2nd argument
findTarget :: String -> Int -> Int -> Int -> Int -> Int
findTarget [] a b c d = ((maximum [a,b,c,d]) `mod` 4)
findTarget (s:str) a b c d
    | s == 'S' = (findTarget str (a + 1) b c d)
    | s == 'D' = (findTarget str a (b + 1) c d)
    | s == 'P' = (findTarget str a b (c + 1) d)
    | s == 'T' = (findTarget str a b c (d + 1))
    | s == 'N' = (findTarget str a b c (d + 1))
    | otherwise = (findTarget str a b c d)

--Makes sure I do target myself takes int 0-3
avoidShootingSelf :: Int -> Int
avoidShootingSelf 0 = 1
avoidShootingSelf a = a

Скомпілюйте бота за допомогою наступної команди (Потрібно мати ghc)

ghc - зробити InputAnalyzer.hs

Команда оболонки для запуску має бути наступною

./InputAnalyzer

Примітка. Я протестував на Windows, тому якщо у вас виникли проблеми щодо компіляції / запуску, будь ласка, скажіть це у коментарі, і я зроблю все можливе, щоб з'ясувати правильну команду.


1
Ну, мабуть, це один із способів отримати зважений генератор псевдовипадкових випадків у Haskell.
змагальний

2

Собака на ім'я Відвага

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

Редагувати: Зараз реалізовано так, як я вважав, що має бути. Раніше оцінка була: 35,9

Оновлено: Іноді стріляє замість ухилення

couragethedog.py

import sys
from collections import defaultdict as ddict
from random import choice
args = sys.argv
info = " ".join(args[2:]).strip('"').split(" ")
players = ddict(dict)
for i,s in enumerate(info):
    parts = s.split(",")
    players[i]["health"]=int(parts[0])
    players[i]["last"]=parts[-1]
    players[i]["history"]=parts[1:]
    players[i]["turn"]=len(parts)
me=0
others=[1,2,3]
turn=players[me]["turn"]
alive = filter(lambda p:players[p]["health"]>0,others)
def act():
    if turn is 1:
        return "S%d" % choice(alive)
    if "P" == players[me]["history"][-1]:
        targets = set(alive)
        for i in alive:
            if "P" == players[i]["history"][-2]:
                targets.remove(i)
        return "T%d" % choice(list(targets))
    for i in others:
        if players[i]["history"][-1] is "P":
            return "P"
    if choice([True,False,False]):
        return "S%d" % choice(alive)
    return "D%d" % choice(alive)
print act()

Виконати як

python couragethedog.py

2

MAD - Java

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

    import java.util.ArrayList;
import java.util.Random;

public class MAD 
{
    public static void main(String[] args) 
    {
        if(args.length < 2)
        {
            return; // nothing to do here
        }
        String[] players = args[1].split(" ");
        if(players.length < 4 || !isAlive(players[0]))
        {
            return; // nothing to do here
        }
        Random rand = new Random();

        int grenadeExplodes = grenadeExplodes(players[0]);        
        if(grenadeExplodes==-1)
        {
            System.out.print("P"); // I don't feel safe without a prepared grenade in my hand
            return;
        }

        int highestDamage = -1;
        int playerToShoot = -1;        
        for(int i=1; i<4; i++) // did anyone try to hit me?
        {
            int damage = damageAttempted(players[i], 0);
            if(isAlive(players[i]) && (damage>highestDamage || (damage==highestDamage && rand.nextDouble()>0.5)))
            {
                highestDamage = damage;
                playerToShoot = i;
            }           
        }

        if(highestDamage > 0)
        {
            System.out.print("T" + Integer.toString(playerToShoot)); // don't tell me I didn't warn you
            return;
        }

        int highestHealth = -1;
        int healthiestPlayer = -1;      
        for(int i=1; i<4; i++) // who is doing too well for their own good?
        {
            int health = getHealth(players[i]);
            if(health>highestHealth || (health==highestHealth && rand.nextDouble()>0.5))
            {
                highestHealth = health;
                healthiestPlayer = i;
            }
        }

        if(grenadeExplodes==0)
        {
            System.out.print("T" + Integer.toString(healthiestPlayer).charAt(0)); // get this hot head outta here!!
            return;
        }

        // I've got time to flaunt my grenade around

        ArrayList<Integer> playersToDodge = new ArrayList<Integer>();       
        for(int i=1; i<4; i++) // lets see who could shoot me
        {
            if(canMove(players[i]) && grenadeExplodes(players[i])!=0)
            {
                playersToDodge.add(i);
                if(grenadeExplodes(players[i])==-1) // players who have no grenade are more likely to shoot
                {
                    playersToDodge.add(i);
                }
            }
        }

        if(playersToDodge.size()>0)
        {
            System.out.print("D" + Integer.toString(playersToDodge.get(rand.nextInt(playersToDodge.size() - 1))).charAt(0)); // what do we say to would-be gunners?
            return;
        }

        if(grenadeExplodes!=1)
        {
            System.out.print("S" + Integer.toString(healthiestPlayer).charAt(0)); // seems like I can take a free shot at someone
        }
        else
        {
            System.out.print("N"); // wouldn't want to end up with an exploding grenade in my hand while being unable to throw it.
        }

    }

    public static boolean isAlive(String player) 
    {
        return player.charAt(0)!='-'; 
    }

    public static boolean canMove(String player)
    {
        return isAlive(player) && player.charAt(player.length()-2)!='S';
    }

    public static int grenadeExplodes(String player)
    {
        String[] actions = player.split(",");

        if(actions.length>3 && actions[actions.length - 3].charAt(0)=='P' 
            && actions[actions.length - 2].charAt(0)=='T' 
            && actions[actions.length - 1].charAt(0)=='P')
        {
            return 0;
        } 
        else if(actions.length>2 && actions[actions.length - 2].charAt(0)=='P' 
            && actions[actions.length - 1].charAt(0)=='T')
        {
            return 1;
        } 
        else if(actions.length>1 && actions[actions.length - 1].charAt(0)=='P')
        {
            return 2;
        }
        else
        {
            return -1;
        }
    }

    public static int damageAttempted(String player, int target)
    {
        String[] actions = player.split(",");
        int damage = 0;
        char targetChar = Integer.toString(target).charAt(0);
        for(int i=0; i<actions.length; i++)
        {
            if(actions[i].charAt(0)=='S' && actions[i].charAt(1)==targetChar)
            {
                damage += 2;
            } 
            else if (actions[i].charAt(0)=='T')
            {
                if(actions[i].charAt(1)==targetChar)
                {
                    damage += 8;
                }
                else
                {
                    damage += 3;
                }
            }
        }

        return damage;
    }

    public static int getHealth(String player)
    {
        return Integer.parseInt(player.split(",")[0]);
    }
}

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


Якийсь кредит повинен їхати до Геобітса, я вкрав код кодової пластини його запису Neo.
суперактор

Ви не брали багато, кредиту не потрібно :)
Geobits

java MAD 43 "5 5 5 5"Здається, виклик нічого не видає.
es1024

2

Садист

пітон

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

Оскільки він використовує гранати, він (і всі інші) звичайно не переживе другий чи третій раунд. Якщо він з’єднається з іншим гранатомером, всі помруть. Це означає, що я не сподіваюсь на перемогу, але я написав це, щоб вивчити python (ніколи не використовував його раніше, і я намагаюся ознайомитись з купою нових мов). Є кілька інших "тягніть перших", тож якщо ви вважаєте, що це занадто симулятор, повідомте мене. Інші, здається, не бажають тягнути, а потім ухилятися.

import sys    

def ident(thatguy):

    return int(thatguy.split(",")[0])

def health(thatguy):
    return int(thatguy.split(",")[1])

def shooter(thatguy):
    if(len(thatguy.split(","))<3):
        return 1==1
    else: return thatguy.split(",")[2][0]=="S"

def mosthealth(group):
    bigbad=group[0]
    for foe in group:
        if (health(foe)>health(bigbad)): bigbad=foe
    return bigbad

def igotanuke(mine):
    return mine.count("P")-mine.count("T")>0

def guytonuke(allguys,fighters):
    backup=allguys[:]
    for Aguy in backup:
        if(health(Aguy)<4):
            allguys.remove(Aguy)
            if (shooter(Aguy)): fighters.remove(Aguy)

    if(len(allguys)==0): return mosthealth(backup)
    if (len(allguys)==len(fighters)):
        return mosthealth(allguys)
    else:
        for fighter in fighters: allguys.remove(fighter)
        return mosthealth(allguys)

raw = sys.argv[2]
player = raw.split(" ")
thisisme=player.pop(0)
turn = len(player[0].split(","))-1

guys=[]
gunners=[]
c=1
for dude in player:
    dude=str(c)+","+dude
    c+=1
    if (health(dude)>0): 
        guys.append(dude)
        if (shooter(dude)):
            gunners.append(dude)

if (turn==0): print "P"
elif(turn==49): print"S0"
elif(igotanuke(thisisme))&( turn % 2 == 1): print "T"+str(ident(guytonuke(guys,gunners)))
elif(len(guys)<2)&(len(gunners)>0) & (turn % 2 == 1): print P
elif(turn % 2 == 0) & (len(gunners)>0): print "D"+str(ident(mosthealth(gunners)))
elif(turn % 2 == 1) & (len(gunners)>0): print "S"+str(ident(mosthealth(gunners)))
else: print "S"+str(ident(mosthealth(guys)))

Я не думаю, що raw_inputце спрацює. sys.argv[2]Здається, є консенсус для записів Python. Ви також можете знайти для цього використання pop, що дозволить вам конденсуватися thisisme=player[0];player.remove(player[0])в простіший thisisme=player.pop(0).
змагальний

@comperendinous Я тестував код на Ideone і sys.argv взагалі не працює (можливо, через імпорт sys). Ось чому я використовував raw_input. Чи є різниця, через яку останні не працюватимуть? Якщо так, то, швидше за все, мені знадобиться знайти інший онлайн-компілятор для python. Дякую за пропозицію з попсом! Я не розумів, що команда дозволяє вказати індекс. Я буду використовувати його для будь-якого майбутнього коду python.
каїн

1
raw_inputвитягується з STDIN, але історія гравця передається вашій програмі як аргумент командного рядка, саме тому вам потрібно sys.argv. Для тестування ви можете просто встановити його вручну sys.argv = ["sadist.py", "0", "5 5 5 5"]. Тоді ви повинні мати можливість зателефонувати player=sys.argv[2].split(). Якщо імпорт sysсправді неможливий, для тестування ви навіть можете скинути крапку та викликати масив sysargv. Поки все інше працює, і ви повернетесь до sys.argvсвого подання, це повинно бути добре.
змагальний

@comperendinous для підтвердження, якщо я зателефоную на sys.argv, він поверне як масив ім'я програми в 0, це єдине число в 1 і фактичну частину, яку я використовую в 2? Вони всі струнні. З цією інформацією я маю змогу її правильно відредагувати. Дуже дякую!
kaine
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.