54
\$\begingroup\$

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.

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

\$\endgroup\$
32
  • 1
    \$\begingroup\$ Do you have exactly one grenade, or do you have many? Can you have multiple grenades being prepared at a time? \$\endgroup\$ – isaacg Aug 9 '14 at 23:52
  • 2
    \$\begingroup\$ @Bob Pretty sure EmoWolf got added to Standard Loopholes which are no longer funny. Though a suicidal entry might not actually do so terribly. \$\endgroup\$ – es1024 Aug 11 '14 at 1:48
  • 3
    \$\begingroup\$ Lesson to everyone : Don't drink and drive. \$\endgroup\$ – Zaenille Aug 11 '14 at 1:56
  • 8
    \$\begingroup\$ @es1024 Where suicide is actually a viable strategy, an EmoWolf-type submission really should be allowed. Especially when the available actions explicitly include suiciding! Not so much a "loophole" now, is it? And not really an unfair advantage, which most of those loopholes really are. But that's just my opinion. \$\endgroup\$ – Bob Aug 11 '14 at 2:20
  • 3
    \$\begingroup\$ Based on running the controller a couple times it seems pretty noisy. If this contest ever gets closed you should probably up the number of runs to smooth it out a bit. \$\endgroup\$ – Davis Yoshida Aug 12 '14 at 4:47

40 Answers 40

1
2
2
\$\begingroup\$

Late Boomer

Ruby

There are 3 types of players right now. Ones who never use grenades, ones who pull first turn, and one idiot who can do anything (that actually sounds inspiring). This class attempts to change that slightly. He pulls the 4th turn should more than 1 opponent be alive, he has no less than 3 health, and noone else has pulled. While I've included a python entry, these are clearly not colluding as he nukes this guy turn 2 ususally.

def health(guy)
    return guy.split(",")[1].to_i
end

def bomb(past)
    return past.count("P")-past.count("T")>0    
end

def maxhealth(players)
    target=players[0]
    for dude in players
        if health(dude)>health(target)
            target=dude
        end
    end
    return target
end

def reloading(past)
    return past[past.length-2]=="S"
end

input=ARGV[1]
them = input.split(" ")
me = "0,"+them.delete_at(0)
turn = me.split(",").length-1

x=0
y=0

while y<them.length do
    x +=1
    them[y]=x.to_s+","+them[y]
    if health(them[y])<1
        them.delete_at(y)
        y -=1
    end
    y +=1
end

if turn==1 
    print "D1"
elsif bomb(me)
    print "T"+ maxhealth(them)[0][0].to_s
elsif turn>2 and not(bomb(input)) and them.length>1 and health(me)>2 and not(reloading(me))
    print "P"
elsif bomb(input)
    print "S"+maxhealth(them)[0][0].to_s
else
    print "S"+them[0][0]
end 
\$\endgroup\$
2
\$\begingroup\$

Muhammad Ali - Java

Floats like a butterfly, stings like a bee; will normally dodge the player who has taken most shots and is ready to shoot. Shoots the healthiest looking player whenever no one can move or if it's one on one and the other player has a grenade prepared. Will not hesitate to take his own life should it be necessary.

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

public class MuhammadAli {

    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 turn = players[0].split(",").length;

        int highestHealth = -1;
        int healthiestPlayer = -1; 
        int livingPlayers = 0;
        for(int i=1; i<4; i++) // who is doing too well for their own good?
        {
            int health = getHealth(players[i]);
            if(health>=0)
            {
                livingPlayers++;
            }
            if(health>highestHealth || (health==highestHealth && rand.nextDouble()>0.5))
            {
                highestHealth = health;
                healthiestPlayer = i;
            }
        }
        
        if(livingPlayers==1 && ((turn==49 && highestHealth<2) || grenadeExplodes(players[healthiestPlayer])>-1))
        {
            System.out.print("S" + Integer.toString(healthiestPlayer).charAt(0)); // you had it coming dude
        }
        
        if(turn!=49)
        {
            int mostShots = -1;
            int triggerHappyPlayer = -1;        
            for(int i=1; i<4; i++) // who's the most trigger happy player?
            {
                int shots = shotsTaken(players[i]);
                if(canMove(players[i]) && (shots>=mostShots))
                {
                    if(shots>mostShots || ((grenadeExplodes(players[i])==-1 || rand.nextDouble()>0.5) && grenadeExplodes(players[triggerHappyPlayer])==-1)) // if you're holding a grenade, you'll have other things on your mind than shooting.
                    mostShots = shots;
                    triggerHappyPlayer = i;
                }           
            }
    
            if(mostShots>0 || turn < 2)
            {
                System.out.print("D" + Integer.toString(triggerHappyPlayer)); // you didn't get your hopes up, did you?
                return;
            }
        }
        
        if(highestHealth>2 && turn==49)
        {
            System.out.print("S0"); // Goodbye, cruel world
        }
        else
        {
            System.out.print("S" + Integer.toString(healthiestPlayer).charAt(0)); // seems like I can take a free shot at someone
        }

    }

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

    public static boolean canMove(String player)
    {
        return isAlive(player) && (player.length() == 1 || 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 shotsTaken(String player)
    {
        String[] actions = player.split(",");
        int shots = 0;
        for(int i=0; i<actions.length; i++)
        {
            if(actions[i].charAt(0)=='S')
            {
                shots ++;
            }
        }

        return shots;
    }

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

I'm hoping this will do quite well, since he is pretty smart about dodging and only starts agression when it really seems to play in his advantage.

\$\endgroup\$
4
  • \$\begingroup\$ Outputs nothing when java MuhammadAli 32 "5 5 5 5" is called. \$\endgroup\$ – es1024 Aug 18 '14 at 2:22
  • \$\begingroup\$ Whoops, forgot an exclamationmark. \$\endgroup\$ – overactor Aug 18 '14 at 5:50
  • \$\begingroup\$ Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.charAt(String.java:658) at MuhammadAli.canMove(MuhammadAli.java:82) at MuhammadAli.main(MuhammadAli.java:49) only for the input 5 5 5 5 \$\endgroup\$ – es1024 Aug 18 '14 at 23:01
  • \$\begingroup\$ @es1024 damn, I need to think more about what I code, should be fixed now. \$\endgroup\$ – overactor Aug 19 '14 at 4:35
1
\$\begingroup\$

DON'T NUKE ME BRO! - Lua

Doesn't like it when people use their grenades. Is a hypocrite when more than one person is shooting at him.

--Don't Nuke Me Bro

math.randomseed(os.time())

info=arg[2]

function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

function parseEnemies(s) -- Makes sense of the input Data
    local e={}
    local pStatus={{},{},{},{}}
    for w in string.gmatch(s, "%S+") do table.insert(e,w) end

    for p = 1, 4 do
        for a in string.gmatch(e[p], "%P+") do
            table.insert(pStatus[p], a)
        end
    end
    for i = 1 , 4 do
        pStatus[i][1]=tonumber(pStatus[i][1])
    end
    return pStatus
end

function analyseEnemies(ps)
    moveList={{},{}}
    sFlag = 0
    if tablelength(ps[1])>=35 then
        for i = 2, 4 do
            if ps[i][1]>0 then
                table.insert(moveList[1], "S"..i-1)
                table.insert(moveList[2], 100)

            end
        end
    elseif tablelength(ps[1])>=42 then
        table.insert(moveList[1], "P")
        table.insert(moveList[2], 100)
    elseif tablelength(ps[1])>=48 then
        table.insert(moveList[1], "S0")
        table.insert(moveList[2], 100)


    else
        for i=2,4 do
            pHealth = ps[i][1]
            lan=tablelength(ps[i])
            lAction=ps[i][lan]
            llAction=ps[i][lan-1]

            if pHealth <= 0 then
            else
                if lAction=="P" then -- Doesn't Like it when people goes nuclear
                    table.insert(moveList[1], tostring("S"..i-1))
                    h=8-pHealth
                    table.insert(moveList[2], h)
                end

                if llAction=="S0" then -- takes notice when someone shoots at him
                    sFlag = sFlag +1
                    if pHealt == 2 or 1 then
                        table.insert(moveList[1],tostring("S".. i-1))
                        table.insert(moveList[2], 2)
                    else
                        table.insert(moveList[1],tostring("D"..i-1))
                        table.insert(moveList[2], 3)
                    end
                end

            end
        end
    end
    nmla = tablelength(ps[1])

    if nmla == 2 and ps[1][nmla] == "P" then -- gotta get rid of this grenade
        tH= 0
        target = 1
        for i = 2, 4 do
            if ps[i][1]>=tH then
                target= i-1
            end
        end
        table.insert(moveList[1],tostring("T"..target))
        table.insert(moveList[2], 6)
    end


    if nmla == 3 and ps[1][nmla-1] == "P" then -- Makes sure he throws the damn grenade
        tH= 0
        target = 1
        for i = 2, 4 do
            if ps[i][1]>=tH then
                target= i-1
            end
        end
        table.insert(moveList[1],tostring("T"..target))
        table.insert(moveList[2], 20)

    end

    if sFlag >=2 then -- if 2 or more people shoot at him during a round, he goes nuclear.
        table.insert(moveList[1],tostring("P"))
        table.insert(moveList[2], 9)
    end
    r=math.random(3)
    table.insert(moveList[1], "D"..r) -- random ducking if all else fails
    table.insert(moveList[2], 1)
    lan=tablelength(ps[1])
        lAction=ps[1][lan]
        if lAction =="P" then
            for i = 2, 4 do
                if ps[i][1]>0 then
                    table.insert(moveList[1], "T"..i-1)
                    table.insert(moveList[2], 100)

                end
            end
        end
    return moveList
end

function makeMove(mList) -- picks the highest rated move
    m = ""
    nml = tablelength(mList[2])
    c = 0
    m = 1
    for i = 1, nml do
        if mList[2][i]>= c then
            c = mList[2][i]
            m = mList[1][i]
        end
    end

    print(m)
end

makeMove(analyseEnemies(parseEnemies(info)))

run it like

lua DONTNUKEMEBRO.lua "input string"
\$\endgroup\$
6
  • \$\begingroup\$ lua DONTNUKEMEBRO.lua 43 "5 5 5 5" gives: lua: DONTNUKEMEBRO.lua:28: bad argument #1 to gmatch (string expect, got nil), status traceback: [C]: in function 'gmatch' DONTNUKEMEBRO.lua:28: in function 'parseEnemies' DONTNUKEMEBRO.lua:119: in main chunk [C]: in ? \$\endgroup\$ – es1024 Aug 10 '14 at 5:07
  • \$\begingroup\$ @es1024 Yep, forgot about the unique stand off number. Sorry about that. It should be okay to go now. \$\endgroup\$ – AndoDaan Aug 10 '14 at 7:17
  • \$\begingroup\$ lua: DONTNUKEMEBRO.lua:43: attempt to call field 'getn' (a nil value) stack traceback: DONTNUKEMEBRO.lua:43: in function 'analyseEnemies' DONTNUKEMEBRO.lua:119: in main chunk [C]: ? \$\endgroup\$ – es1024 Aug 10 '14 at 7:22
  • \$\begingroup\$ @es1024 Okay, I think I got it now. I was using an out of date function. Sorry for the hassle. \$\endgroup\$ – AndoDaan Aug 10 '14 at 8:16
  • 1
    \$\begingroup\$ Everything works now. \$\endgroup\$ – es1024 Aug 10 '14 at 8:24
1
\$\begingroup\$

Take 'em with me -- VB (what, no love?)

This guy tries to hide while everyone else is shooting, and assuming he is still around when the truck rolls near, will try to nuke the healthiest looking target that is left standing. If he still sees the truck barreling down at him, then he takes the cowards way out.

Module Module1
    Dim players As String()
    Dim numTurns As Integer

Public Sub Main(args() As String)
    'split results into the different players
    players = args(1).Split(" ")
    'how many turns have we been going?
    numTurns = players(0).Split(",").Length
    If numTurns = 48 Then 'can hear the truck
        Console.Write("P")
    ElseIf numTurns = 49 Then ' can see the truck
        Console.Write("T" & PlayerWithHighestHealth())
    ElseIf numTurns = 50 Then 'can smell the truck
        Console.Write("S0")
    Else ' hiding is best
        Console.Write("D" & PlayerWithHighestHealth())
    End If
End Sub

Private Function PlayerWithHighestHealth() As Integer
    Dim p As Integer = 1
    Dim health As Integer = 1
    For i = 1 To 3
        If players(i).Split(",")(0) > health Then 'this is the healthiest looking guy
            p = i
            health = players(i).Split(",")(0)
        End If
    Next
    Return p
End Function

End Module

Run as Standoff.exe 5 "3,S2,N 5,P,N 3,S0,N -2,S3,N" for example

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Don't forget about the first integer argument that nobody seems to bother with. The players history is actually the second argument. \$\endgroup\$ – comperendinous Aug 11 '14 at 19:06
  • \$\begingroup\$ @comperendinous. Thanks. I don't know how I missed that little note about the first argument being the standoff #. Updated my code to get the right argument. \$\endgroup\$ – APrough Aug 11 '14 at 19:11
  • \$\begingroup\$ It's no fun shooting at you if the scoring program is just assigning you "N" all the time (-; \$\endgroup\$ – comperendinous Aug 11 '14 at 19:15
  • \$\begingroup\$ TakeEmWithMe.vb (7,23) : Error VBNC99999: After removing narrowing (except object) candidates for method 'Split', nothing was found \$\endgroup\$ – es1024 Aug 12 '14 at 0:27
1
\$\begingroup\$

Equivocator

The Equivocator finds those who are alive & closest in health to him and shoots them.

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

function RunRound()
   -- set up the players
   players = match:split(" ")
   myHealth = string.sub(players[1],1,1)
   closestHealth = 10
   enemy = 3
   if myHealth == "-" then
      return "N"
   end
   
   -- find someone with health close to mine
   for i=2,#players do
      moves = players[i]
      playerHealth = moves:sub(1,1)
      if playerHealth ~= "-" then
         if math.abs(playerHealth - myHealth) <= closestHealth then
            enemy = i-1
            closestHealth = math.abs(playerHealth - myHealth)
         end
      end
   end
   return "S"..enemy
end

local args = {...}  -- command line arguments
match = args[2]     -- store the set of matches
action = RunRound()
print(action)
\$\endgroup\$
1
\$\begingroup\$

SolidSnake - Java

Take advantage of enemy down times. Dodge all other times. A little aggressive for Snake... But he's mad because Big Boss is in the spot light all the time.

War... War never changes....

import java.util.Random;

public class SolidSnake {

    public static void main(String[] args) {
        int target;
        char hp;
        Random rand = new Random();

        if(args.length == 0) {
            target = rand.nextInt(3) + 1;
            System.out.println("D"+target);
            return;
        }

        String[] list = args[1].split(" ");

        for(int i = 1; i <= list.length; ++i) {
            hp = list[i].charAt(0);
            if(hp > 0) {
                char c = list[i].charAt(list[i].length()-1);
                String lastMove = String.valueOf(c);

                //Check for P
                if(lastMove.equals('P')) {
                    target = i;
                    System.out.println("S"+target);
                    return;
                }

                //Check for S*
                if(Character.isDigit(lastMove.charAt(lastMove.length() - 1))) {
                    target = i;
                    System.out.println("S"+target);
                    return;
                }
            }
        }

        //If not any P or S*
        for(int i = 1; i <= list.length; ++i) {
            hp = list[i].charAt(0);
            if(hp > 0) {
                target=i;
                System.out.print("D"+target);
                return;
            }
        }

        //Catch-safe
        System.out.print("D1");
        return;
    }

}

Compile/run:

javac SolidSnake.java 
java SolidSnake arg0 arg1
\$\endgroup\$
1
  • \$\begingroup\$ Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at SolidSnake.main(SolidSnake.java:19) when passed 30023 "5,S1 3,N 5,N 5,N" \$\endgroup\$ – es1024 Aug 18 '14 at 23:27
1
\$\begingroup\$

BiasedOne - Java

Pun intended


public class BiasedOne {
    public static void main(String[] args) {
        System.out.println("S1");
        return;
    }
}

Compile/run:

javac BiasedOne .java 
java BiasedOne arg0 arg1
\$\endgroup\$
3
  • \$\begingroup\$ I think you might have meant "S1" in stead of "S"+1 \$\endgroup\$ – overactor Aug 14 '14 at 15:34
  • \$\begingroup\$ oops! ty @overactor i was in a rush :P \$\endgroup\$ – Josef E. Aug 14 '14 at 15:35
  • \$\begingroup\$ This was Straight Shooter's original strategy, before Politically Correct Gunman came along. It'll be interesting to see if S1 does any better than S2, which is about as far from a winning strategy as it can get. There are a few bots which sweep through the numbers to choose a target, so I suppose it's possible the position of the fixed target might influence the outcome. \$\endgroup\$ – comperendinous Aug 14 '14 at 23:54
1
\$\begingroup\$

Hippolyta

This Amazon Warrior Shooter, like her namesake, is destined to be slain.

Since we now have an S0, an S1, and an S2 bot, for completeness, here's an S3 bot to see if the position of the fixed target makes any significant difference to the result.

void
main ()
{
  print ("S3");
}

Compile as Vala:

valac hippolyta.vala

Run as any other executable:

./hippolyta 3 "5 5 5 5"
\$\endgroup\$
1
\$\begingroup\$

Label1Goto1 - Python

I ran out of good names (or I'm too lazy to think about others), but I have been doing some relatively repetitive work nowadays, hence came the name of the lowest common denominator of a loop structure.

The bot is relatively simple (in comparison to Spock, my previous work). Label 1, Dodge it, Prepare it, Shoot it, Wait it, Throw it, Goto 1.

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

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

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

import random
target = random.choice(target_list)

round = (current_turn - 1) % 5

if   round == 0: action = "D" + str(target)
elif round == 1: action = "P"
elif round == 2: action = "S" + str(target)
elif round == 3: action = "N"
elif round == 4: action = "T" + str(target)

print(action)

Run it as:

python label1goto1.py
\$\endgroup\$
1
\$\begingroup\$

Less Simple Shooter

This is basically the Simple Shooter but with the added directive to shoot himself before the truck comes.

If, for some reason, another entry already uses this exactly strategy, then I will withdraw it.

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

I run it like this:

perl lesssimpleshooter.plx 5 "-2,S0 -2,S1 -2,S2 5,N"
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.