[Question]
  [
# 4-Man Standoff
## Description
You've somehow found yourself into a four-way standoff. A loaded gun rests in your hands, and some grenades are hooked on your belt. 
The objective is to have the most health at the end of a standoff. A standoff is over when at most one person has a positive amount of health.
Each player has `5` health, and dies when their health drops to/below `0`. The turn a player dies is the last turn that player can take damage.
If there is a live player at the end of a standoff, that player wins. Otherwise, the player with the least negative health wins.
## Actions
* **Shoot**: Take a shot at someone. 
	+ `2` damage if shooting a live enemy
	+ `0` damage if shooting a dead enemy
	+ `health_at_start_of_turn+2` damage if shooting yourself. (Note that this will leave you with at MOST `-2` health.)
	+ If one enemy shoots at you on the same turn you shoot yourself, you will end the standoff with -4 health (you still take damage from other players the turn you kill yourself).
	+ Your action the following turn will be ignored (and assumed to be `Nothing`).
* **Dodge**: Try to dodge a single opponent's shot.
* **Prepare**: Unhook your grenade and prepare to throw it.
	+ You only have three turns to throw it, before you get blown up (`6` damage to yourself, `3` damage to all live enemies)
	+ Dying with an unthrown grenade is equivalent to not throwing the grenade for three turns.
* **Throw**: Chuck the grenade towards someone and hope for the best.
	+ Target receives `8` damage if alive
	+ Everyone else (including yourself) receives `3` damage if alive
* **Nothing**: Stand idly for a turn and watch everyone die.
## Input
Your program will be passed the following information:
* The health of each player
* A list of actions taken by that player since the start of the standoff
Below is the format for the information passed per player:
```
[Health],[Action 1],[Action 2],[Action 3],...
```
Actions will be given in the format specified in the **Output** section. 
You will recieve 4 such strings, separated by a space, and passed as a single argument. The order of these strings is:
```
[Player Info] [Opponent 1 Info] [Opponent 2 Info] [Opponent 3 Info]
```
The strings are passed as the second argument. The first argument contains an integer that uniquely identifies the standoff being enacted. Standoffs between the same set of players are guaranteed not to be simultaneous. However, multiple standoffs *will* occur at the same time.
For example:
```
$./Player.bash 5 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
```
Currently, the player and the second opponent have 3 health, the first opponent has 5 health, and the third opponent has -2 health and is dead.
On the first turn:
* Player 1 shot enemy 2
* Enemy 1 prepared a grenade
* Enemy 2 shot player
* Enemy 3 shot himself
On the second turn:
* All players did nothing. (Player and enemy 2 can not do anything since they shot on the previous turn. Enemy 3 is dead: he will do `Nothing` for the rest of the standoff.)
The second argument at the start of a standoff is: `5 5 5 5`.
## Output
A command should be outputted in the below listed format. An invalid output is interpreted as 'Nothing'. A command requiring a target should be followed by an integer (`0-3`, with `0` representing the player, and `1-3` representing enemies 1-3).
* `S[target]`: Shoots [target].
* `D[target]`: Tries to dodge [target].
* `P`: Prepare a grenade.
* `T[target]`: Throw the grenade at [target].
* `N`: Do nothing.
A command that needs a target, but is fed a target not between `0` and `3` or not fed a target entirely will be assumed to target `0` (the player).
## Scoring
At the end of each standoff, players receive a score calculated by the following formula:
```
35 + health at end of standoff 
```
In the case that a player ends a standoff with negative health, they **will** receive a score **below 35**. The following points are also rewarded as a bonus:
* Most health: +4 points
* Second most health: +2 points
* Third most health: +1 point.
In case of a tie, the lower bonus is granted (if two people tie with most health, both are granted +2; if there are 3 people with the most health, +1, and if everyone ends equally, +0).
The final score is determined by calculating the mean of all individual scores.
## Rules/Details
* Order of events within a turn are as follows:
	+ All players do their actions.
	+ Players who have 0 or less health die.
	+ Unthrown grenades that need to explode, will explode (players who just died are still hurt, as this is still the turn they died).
* No collaboration between entries.
* Three\* standoffs will occur between each set of 4 players. (Order of players may vary with each standoff).
* Entries consuming excessive amounts of memory of disk space will be disqualified.
* Reading from or modifying files other than your entry's will disqualify your entry.
* A truck, driven by a drunkard, will run over all living players after the `50th` turn, if the standoff is not yet over at the end of the `50th` turn.
	+ This truck deals **20** damage to all live players.
* Standoffs happen quickly. Programs are cut off after 1 second.
* Your program will be called every turn, even after you have died.
* You may read or write files to your directory only (if your entry is named JohnDoe, you may save files in the directory players/JohnDoe/); however, this will NOT be the current directory while your script is running.
* The standoffs will take place on a machine running Arch Linux (Release 2014.08.01).
The controller is available on [GitHub](https://github.com/es1024/4-Man-Standoff-controller).
Please include the following in your post:
* A name for your bot
* A shell command to run the bot (ex. `java Doe.java`) Input will be passed through the command line as a single argument (`java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N"`)
* Code of your bot
* How the bot should be compiled (if applicable)
* Language (and version if applicable, especially for python)
\*Controller is taking way too long for six.
## Scoreboard
```
                      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
```
Logs: [on GitHub](https://github.com/es1024/4-Man-Standoff-controller/tree/master/build/results)
  
[Answer]
# Grenadier
Guns are overrated. A *true* Scotsman's standoff goes like this:
* Prepare
* Throw at enemy with most health
* Repeat (if by some miracle you're still alive)
While this seems trivial, it's probably not a *terrible* strategy. Since guns and grenades both have a two-turn cycle, this is by far the more efficient1 way to deal damage.
Of course, if all three opponents shoot me on the first round it's no good. But not much else would be, either.
```
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);
    }
}
```
Compile/run in the standard Java way:
```
> javac Grenadier.java
> java Grenadier arg0 arg1
```
---
1 Pointless footnote
[Answer]
## Asimov's Rule Number 0 Bot - Python
> 
> A robot may not harm humanity, or, by inaction, allow humanity to come
>  to harm.
> 
> 
> 
Pretty straight forward, he'll attack the first player he sees holding a grenade in order to protect the majority of humans. If no one is a threat to the majority of humans, he'll do nothing.
```
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
```
Run it like:
```
python rule0bot.py
```
[Answer]
## Han Solo - Python
Han shot first. In this case, he'll shoot first by picking the closest target alive. 
```
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
```
Run it like:
```
python hansolo.py
```
 **Note**: This is the first thing I ever wrote in Python, so if you see any python-specific bad practices, please let me know. 
[Answer]
**EmoCowboy**
Why wait to die? Just kill yourself now. Hopefully the rest of the fools will blow eachother up to much less than -2.
Score will normally be -2. Sometimes -4 if people decide to shoot me off the bat. Rarely more than that, which means this should beat several of the current submissions.
Python
```
print('S0')
python EmoCowboy.py
```
EDIT: This isn't a joke, which is generally why these emo submissions are frowned upon. This is a legitimate strategy. Being alive is deadly!
[Answer]
# Pacifist
He's a real swell guy, just got caught up with the wrong crowd.
```
main = putStr "N"
```
Run as `runghc pacifist.hs`, but you might want to compile it with -O3 if efficiency is an issue.
[Answer]
**Monkey** -- Python (First ever entry!)
Monkey see, monkey do. Will repeat exactly the last action taken by a random player.
```
import sys, random
targetData = sys.argv[2].split()[random.randint(0,3)]
print(targetData.split(',')[len(targetData.split(','))-1])
```
Can be run like this: "python monkey.py args"
No extra steps required.
[Answer]
# Observer
This guy analyses his enemies. The goal is to survive until only one "aggressive" opponent is left, and then kill that one in an epic standoff.
Compile: `javac Observer.java` Run: `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);
    }
}
```
[Answer]
# Simple Shooter - Perl *(fixed bug)*
This bot shoots at the opponent with the most health. It's a very simple strategy, but I think it has a decent chance of actually doing well.
```
@history = map([split(",",$_)],split(" ",$ARGV[1]));
$target = 1;
for(2..3){
 if($history[$_][0] >= $history[$target][0]){$target = $_}
}
print "S$target"
```
This is how to run it using some example input:
```
perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
```
[Answer]
# Spock, in Python 3.x
This code is more of a though experiment (hence named after Spock because... he's a vulcan, and they're pretty good at these sort of things) but was fun building it nonetheless. The main reasoning behind all this code are assumptions a good, logical being, like Spock, would do, if given the game's rules:
---
The objective of this game is to **maximize** score, which would be done by everyone just standing still, which isn't possible, due to the truck.
* One of the directives Spock has to follow is to prevent the truck from appearing, making sure that everyone but one is dead before the truck appears.
The way Spock plays in the rest of the game can be summed up by his famous quote: "*The needs of the many outweigh the needs of the few*". In other words, Spock has to make sure that the least amount of damage is suffered, by killing those that do it. How he does it:
* If no player has prepped a grenade, target the least healthy player that's still playing.
* If there are players that prepped grenades, from those target the least healthy.
The reasoning is that, by targeting the weakest players, we are terminating sources of damage. The reasoning behind the grenades is that they are going off regardless and they do less damage if they aren't thrown.
---
And so this bot works. I haven't tested extensively for input failures (so please warn me if something goes awry) but I'm confident I worked out most of the kinks. I based a small part of the code from the HanSolo bot but for the most part it's a tangled mess of code. Enjoy.
```
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)
```
Run it like:
```
python spock.py
```
2014-08-12 - Minor bugfix regarding grenade detection  
2014-08-14 - Minor bugfix regarding endgame, thanks to isaacg for pointing it out before
[Answer]
## Politically Correct Gunman
Very politically correct, as it doesn't discriminate against anything. Thus it isn't very smart.
```
import random
array = ["P", "N", "S0", "S1", "S2", "S3", "D1", "D2", "D3", "T1", "T2", "T3"]
print(array[random.randrange(0,11)])
```
It... doesn't really matter what arguments get passed to it how. `python politicallycorrectgunman.py`
[Answer]
# Straight Shooter
He's a trained part of the cavalry and talks in many languages but, being blinkered, Straight Shooter can only see the one enemy in front of him. Being a horse, he doesn't understand that you have to wait between shots.
```
print('S2')
```
Perl, Python 2/3, Ruby: this horse really is a polygot entry.
> 
> I'm winning anyway. I can't lose. You can shoot me but you can't kill me. Mister Ed ain't got shit on me!
> 
> 
> 
For an answer that has a little more thought (and some functional paradigm) put into it, see [Twenty-Fourth and a Halfth Century](https://codegolf.stackexchange.com/questions/35988/four-man-standoff#36051).
[Answer]
# Anti-grenadier
Grenades are bad. Very bad. So if anyone is preparing one, best thing to do is shoot them. Otherwise, we'll just hang out.
```
-- 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")
```
[Answer]
# Ricochet - Perl
Simple strategies seem to do decently in this challenge, so here's another. It shoots a random living player. It has the added feature of committing suicide at the end to avoid the truck.
```
@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";
```
Run like so:
```
perl ricochet.plx 5 "-2,S0 -2,S1 -2,S2 5,N" 
```
[Answer]
## Aggressor
Pulls on round one, throws at highest health opponent on round 2, shoots at highest health opponent thereafter.
```
#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;
}
```
Run this like ./agg ID "5 5 5 5".
[Answer]
# Ninja
Just dodges randomly trying to avoid getting hit.
```
math.randomseed(os.time())
print("D"..tostring(math.random(4)-1))
```
run as
```
lua ninja.lua
```
Args are unnecessary, but can be added w/o issue.
[Answer]
**Name**: PriorityTargets
**Shell Command**: ruby PriorityTargets.rb 5 [game\_state]
**Language**: Ruby V2.1.2
**Description**: PriorityTargets attempts to find common playstyles. It then decides, based on those playstyles, who it wants to attack and what weapon to use.
**Note**: First Code Golf submission! Much larger than the other submissions because I went a little crazy.
```
#!/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 [[email protected]](/cdn-cgi/l/email-protection)_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
```
[Answer]
# Coward -- Perl
Acts very cowardly. When he feels healthy, he chooses an enemy who does not feel so and shoots him. Bonus points for those enemies which were shooting the last turn (because they are known to be doing `Nothing` this turn and so be absolutely defenceless). When he feels not so good, he runs for cover to save his hide in, occassionally shooting someone.
```
#!/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);
}
```
Pretty standard Perl code; save it in some file and then run `perl file argument argument [...]`. I have checked for syntax and it was OK, so I hope for no problems with this.
E: eliminated a potential for division by 0 error.
[Answer]
# Bomberman
Bot written in R, command line should be: `Rscript Bomberman.R arg0 arg1`  
I realized after starting to write this bot that Geobits already made a [grenadier](https://codegolf.stackexchange.com/a/35991/6741) but I think mine is significantly different, in that it checks its health is above 3 before preparing a grenade, throws it at the last shooter first, and the most healthy second, and if its health is below 3 it will dodge the dangerous player (neither dead nor shooter in the last round) or shoot one of the remaining player.
```
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)
```
**Edit**
There seems to be some communication problem between this bot and your controller since all logs that I looked showed that my bot only output `N`. So, here is the same bot but rewritten in Python, in the hope that if this one also have communications problem, someone will see it.  
To be called with `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)
```
[Answer]
# Neo
Dodge a living player who did not shoot last turn. If everybody alive shot last turn, shoot a random living player. Suicide when you see headlights.
```
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);
    }
}
```
I don't expect much from this guy against grenade-chuckers, but against shooters it might work pretty well. We'll see.
[Answer]
# Twenty-Fourth and a Halfth Century
This Python entry ducks and dodges until only passive players or a single aggressive player remains, then starts shooting. It hopes a passing martian takes care of grenadiers and drunken truck drivers.
Unless I've done something wrong, this is functional Python. It certainly doesn't look like the kind of Python I wrote before Haskell and friends found me, and I don't think I've mutated anything in place. But if you know better, please do tell me.
```
#!/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))
```
Run as:
```
python twenty-fourth-and-a-halfth-century.py 0 "5 5 5 5"
```
[Answer]
# Scared
This submission is scared of everyone. But it's especially scared of some people. So it figures out who's the most dangerous, and shoots them. If multiple enemies look the most dangerous, it shoots at a random one.
```
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))
```
This is python (2 or 3, same result in either.) Save as `scared.py`, run with `python3 scared.py`
[Answer]
# Manipulative Bastard – Python
Prepares and throws grenades. If he thinks there's no time or there are too few enemies, he shoots. If he's alone he tries to outsmart the other guy.
```
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')
```
[Answer]
# Osama
I've been trying this for a day or so, now it's time to post and see how the others have evolved in the meantime.
```
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
```
Compile with `ghc -O2 osama.hs`, then run using `./players/Osama/osama`.
[Answer]
## Sniper - Lua
On the first turn it will shoot a random person, then it will shoot any players that it can kill (2 or 1 health). If neither of those work it will try to shoot the player that shot it last, otherwise it will shoot a random player. Run with `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)))
```
[Answer]
# Darwin
Survival of the fittest means the least healthy must die.
### Rationale
Looking at the batch of results from Tuesday (12th), there seem to be three distinct groupings: survivors; the effectively suicidal; and the worse than useless. The survivors share simple shooting-based strategies. While a couple of other bots (*Spock*, *Coward*) will target the least healthy enemy, they also complicate their strategies with other actions. This one does not. Like *Simple Shooter*, it has a clear definition of the target and sticks with it relentlessly. It'll be interesting to see where it fits into the results.
```
#!/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))
```
This is a stripped-down, slightly modified version of my earlier *Twenty-Fourth and a Halfth Century*, and shares its invocation:
```
python darwin.py 3 "5 5 5 5"
```
[Answer]
# Zaenille - C
## Priorities :
1. Shoot if it's a 1 on 1 left
2. Shoot grenadiers
3. Dodge
4. Nothing (just to confuse some)
Compile with `gcc <filename.c>`.
Run with `./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;
}
```
[Answer]
# InputAnalyzer
The key a game such as this is analyze how all your opponents are playing to respond accordingly. My bot will do just that using complicated algorithms that will result in using my opponents turns to my advantage giving a decisive victory!
Edit: I now
1. dodge any player who has a live grenade
2. will no longer attempt to shoow/throw/dodge myself.
---
```
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
```
Compile the bot with the following command (Need to have ghc) 
> 
> ghc --make InputAnalyzer.hs
> 
> 
> 
Shell Command to run should be the following
> 
> ./InputAnalyzer
> 
> 
> 
Note: I tested on windows so if you have any trouble regarding compling/running please say so in comment in and I will do my best to find out the correct command. 
[Answer]
# Dog named Courage
First thing - shoot the bad guys on sight.
Then dodge randomly until someone prepares a grenade.
Then when everyone shoots at him, prepare my own grenade and throw it on anyone.
But the distraction man.
Edit: Now implemented as I thought It should be. Before, the score was: 35.9
*Updated: Sometimes shoots instead of dodgeing*
### 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()
```
Run as
```
python couragethedog.py
```
[Answer]
# MAD - Java
The MAD bot trust in the power of intimidation through [mutual assured destruction](http://en.wikipedia.org/wiki/Mutual_assured_destruction). Whenever he doesn't have a ready grenade, he prepares one. He then dodges possible gunners until either someone tries to deal damage to him or his grenade is about to explode. From the moment he gets attacked, **he chucks grenades at whoever has *tried* to deal more damage to him this match so far.** If his grenade is about to explode, he bombs the leading player. MAD is not against taking a shot at someone when there's nothing to dodge or directly chuck a grenade at and his grenade is still good for at least one turn.
```
    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]);
    }
}
```
This Bot will likely perform poorly, but I liked the idea anyway.
MAD would probably do better in a field with smarter bots that log the behavior of other bots and with more matches run between 4 bots.
[Answer]
## Sadist
python 
His priority is to cause pain and grenades hurt. He pulls first turn. He likes to kill when you can't attack. He toys with SSSs (single simple shooters) by dodging and pulling to prolong the domination. He even choses to attack those first who've done nothing to anyone.
Because he uses grenades, he (and everyone else) will ususally not survive the second or third round. If he is paired up with another grenadeer, everyone will die. This means I don't expect to win but I wrote this to learn python (never used it before and I'm trying to get an introduction into a bunch of new languages). There are several other, "pull firsts" so if you feel it is too simular let me know. The others don't seem to be willing to pull and then dodge, however.
```
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)))
```
]