Противостояние четырех человек


54

Противостояние 4-х человек

Описание

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

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

У каждого игрока есть 5здоровье, и он умирает, когда его здоровье падает до / ниже 0. Ход игрока умирает - это последний ход, когда игрок может получить урон.

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

действия

  • Стреляй : сделай выстрел в кого-нибудь.

    • 2 урон при стрельбе по живому врагу
    • 0 урон, если застрелить мертвого врага
    • health_at_start_of_turn+2повреждение при стрельбе в себя (Обратите внимание, что это оставит вас на -2здоровье.)
    • Если один враг стреляет в вас в тот же ход, когда вы стреляете в себя, вы прекратите противостояние с -4 ед. Здоровья (вы по-прежнему получаете урон от других игроков в тот ход, когда убиваете себя).
    • Ваше действие в следующем ходу будет проигнорировано (и предполагается, что будет Nothing).
  • Dodge : попытаться увернуться от единственного выстрела противника.

  • Приготовьтесь : отцепите гранату и приготовьтесь бросить ее.

    • У вас есть только три хода, чтобы бросить его, прежде чем вас взорвут ( 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, вы можете сохранять файлы в каталоге Players / 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
У вас есть только одна граната, или у вас много? Можете ли вы подготовить несколько гранат одновременно?
Исаак

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? Самоубийственный игрок все равно будет мертв
Cruncher

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
хахаха сноска
гордый haskeller

Я думаю, что бросать гранату, а затем стрельбу более эффективно. Вероятность того, что вы выживете 4 хода с этой стратегией, ошеломительно низка. Но 3 возможно (да, оба берут 2, но второй поворот для стрельбы - после действия, а не до)
Cruncher

@ Cruncher Ты наверное прав. Эрик сказал то же самое в чате. Я сказал ему, что мой парень не верит в оружие и слишком упрям, чтобы использовать эту логику, поэтому он опубликовал эту стратегию. Тем не менее, я все еще считаю, что это будет более эффективно , если мы строго говорим о нанесенном ущербе. Это не значит, что он более эффективен для победы в игре. Даже если я умру на третьем ходу, моя вторая граната все равно сработает. Так что если я доживу до этого времени, это гарантирует 6+ урона каждому, игра окончена.
Geobits

@ Geobits теперь, когда я думаю об этом, это может быть лучше. Самое главное - это разница между вами и противниками. Когда граната взорвется, вы получите +3 дельты с тем, кому ее бросили, и +0 с остальными. Сеть +3. Стрельба. Получает +2 дельты с тем, кого вы снимаете. +0 с остальными. Я думаю, что проблема в том, что вы -3 с людьми, которые уже мертвы. Вы должны стрелять, если кто-нибудь мертв :)
Cruncher

2
@ Codebreaker Никогда не играл в нее. Это реальная ссылка на жизнь .
Geobits

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
Geobits

4
На самом деле, лучший сценарий для человечества - надеяться, что гранату
бросят

1
@ Geobits Не пытаться остановить кого-то, кто представляет угрозу, против природы роботов. Он будет пытаться остановить кого-то, держащего гранату, чтобы предотвратить ранение большинства (двух других). Ты читал меня, робот? Эту логику поддерживают Little Lost Robot и The Eviable Conflict.
Уильям Барбоза,

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

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, поэтому, если вы видите какие-либо плохие практики, специфичные для Python, пожалуйста, дайте мне знать.


1
Стиль pep8 предполагает, что ваш метод должен бытьis_alive
Daenyth

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

2
Поздравляем с тем, что вы единственный бот со средним здоровьем больше 0 в раунде 8/11.
Исаак

6
ИМО, «руководства по стилю» предназначены для парикмахеров, а не для программистов.
Кайл Канос,

2
@KyleKanos Приятно иметь некоторую последовательность, хотя. Я имею в виду, что если половина разработчиков проекта использует верблюжий корпус и другие наполовину типы, подобные этому, результат будет "blergh"
Уильям Барбоза

12

EmoCowboy

Зачем ждать смерти? Просто убей себя сейчас. Надеемся, что остальные дураки раздувают друг друга до значения намного меньше -2.

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

питон

print('S0')

python EmoCowboy.py

РЕДАКТИРОВАТЬ: Это не шутка, и именно поэтому эти эмо эмоции не одобряются. Это законная стратегия. Быть живым смертельно!


11

пацифист

Он настоящий крутой парень, только что столкнулся с не той толпой.

main = putStr "N"

Запустите как runghc pacifist.hs, но вы можете скомпилировать его с -O3, если проблема в эффективности.


1
Пожалуйста, переименуйте его в Луиджи, и давайте посмотрим, выиграет ли он что-нибудь!
Уильям Барбоза

1
@WilliamBarbosa Луиджи? Ты сказал Луиджи ?
убийственное

7
Lol как будто -O3делает чертовски разницу.
Томсминг

@tomsmeding Это медленно на runghcстороне. На самом деле это в 10 раз медленнее на моем компьютере с Linux.
Рэй

5
Это подразумевает существование насилия, а это означает, что наш пацифист не готов с этим справиться
убийственный

9

Обезьяна - Питон (Первая запись!)

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

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 вернет последний элемент? Если так, круто! Я обязательно добавлю это.
Элиас Беневедес

И не забудьте первый (целочисленный) аргумент. Вы должны argv[2]получить историю игроков.
Конкурсный

Просто надеюсь, что вы не подобраны с Emo Cowboy.
код

6

Simple Shooter - 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"

Ух ты. Просто и умно.
Сохам Чоудхури

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 Спасибо за напоминание (которое объясняет поведение), но, похоже, есть некоторые скрытые ошибки. Например, в этом Спок должен был выстрелить 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 еще раз, я благодарю вас за помощь. Я бы сделал это раньше, но я был завален вещами. Спок был в конечном счете построен на ошибочной концепции о том, как это будет развиваться, отсюда и относительно более низкий балл, который он получил. У меня есть некоторые идеи для новых ботов, но теперь я должен убедиться, что основная идея оригинальна.
Доктор Рейхард

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? Это отлично подходит для такого рода выборов.
comperendinous

ничего не может быть до действия и цели в выводе, хотя что-либо после игнорируется
es1024

Это выглядит лучше @ es1024?
Отмена

@ Отмена Да, теперь работает отлично
es1024

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

5

Стрелок прямо

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

print('S2')

Perl, Python 2/3, Ruby: эта лошадь действительно является полиготной записью.

Я все равно выигрываю. Я не могу проиграть. Вы можете застрелить меня, но вы не можете убить меня. Мистер Эд, мне все равно!

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


5

Anti-гренадер

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

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

Рикошет - Perl

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

@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

агрессор

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

#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 будет ниндзя увернуться от своих собственных снимков?
Скеггс

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

4

Название : PriorityTargets

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

Язык : Ruby V2.1.2

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

Примечание : подача First Code Golf! Гораздо больше, чем другие представления, потому что я немного с ума сошел.

#!/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
Мне нравится ваш подход, я с нетерпением жду возможности увидеть, как он будет работать.
overactor

К сожалению, похоже, что в нем была ошибка, из-за которой появился гренадер. Ах, хорошо, будет лучше в следующий раз :)
fingerco

3

Трус - Perl

Действует очень трусливо. Когда он чувствует себя здоровым, он выбирает врага, который не чувствует этого, и стреляет в него. Бонусные очки для тех врагов, которые стреляли в последний ход (потому что они, как известно, делают 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 [...]. Я проверил синтаксис, и все было в порядке, поэтому я надеюсь, что с этим проблем не возникнет.

E: исключен потенциал деления на 0 ошибок.


3

Bomberman

Бот написан на 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);
    }
}

Я не ожидаю многого от этого парня против гранатометов, но против стрелков это может сработать довольно хорошо. Посмотрим.


Я использовал некоторые из ваших стандартных кодов в своем ответе . Я надеюсь, что все в порядке.
overactor

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 Должно быть хорошо идти и не будет делать ничего при каждом первом повороте.
Geobits

2

Двадцать четвертый с половиной века

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

Если я не сделал что-то не так, это функциональный Python. Это, конечно, не похоже на тот Python, который я написал до того, как Хаскелл и друзья нашли меня, и я не думаю, что что-то мутировал на месте. Но если вы знаете лучше, пожалуйста, скажите мне.

#!/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, вопрос о Lua: случайное семя 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-го), можно выделить три отдельные группы: выжившие; эффективно самоубийственный; и хуже, чем бесполезно. Выжившие делятся простыми стратегиями стрельбы. Хотя пара других ботов ( Спок , Трус ) будут нацеливаться на наименее здорового врага, они также усложняют свои стратегии другими действиями. Этот не делает. Как и в Simple Shooter , у него есть четкое определение цели, и он неуклонно ее придерживается. Будет интересно посмотреть, как это вписывается в результаты.

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

Zaenille - C

Приоритеты:

  1. Стреляй, если слева 1
  2. Стрелять гренадеры
  3. изворачиваться
  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.
Соревновательный

В самом деле? D: Спасибо @comperendinous. Буду редактировать код.
Марк Габриэль

2

InputAnalyzer

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

Редактировать: я сейчас

  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 --make InputAnalyzer.hs

Команда Shell для запуска должна быть следующей

./InputAnalyzer

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


1
Ну, я полагаю, это один из способов получить взвешенный псевдослучайный генератор в Хаскеле.
comperendinous

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

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


Некоторые кредиты должны быть получены от Geobits, я украл код котельной пластины его записи Neo.
overactor

Вы не взяли много, кредит не нужен :)
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.
kaine

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.