Evaluate a Stratego Battle

11

In the game Stratego, the main game mechanic is when you attack an opponent's piece with yours. In this challenge, you job is to simulate one of these battles and say who survives.

Specs

You will get as input a pair of string representing Stratego pieces. The pieces are one of "S 1 2 3 4 5 6 7 8 9 10 B" (S is the Spy, and B are bombs). The first of the pair will be the attacker, and the second the attacked.

Here are the rules for determining the results of a battle:

  • The higher number beats the lower number: ["4", "6"] -> ["6"].
  • If both are the same, then both die: ["7", "7"] -> [].
  • Spies are at the bottom, underneath even 1: ["S", "2"] -> ["2"].
  • However, if a spy attacks the 10, then the spy wins: ["S", "10"] -> ["S"].
  • But the normal rules still apply if the 10 is the one attacking: ["10", "S"] -> ["10"].
  • If anything attacks a bomb, the bomb wins: ["5", "B"] -> ["B"].
  • However, a miner (a 3), can defuse a bomb: ["3", "B"] -> ["3"].
  • A bomb will never be the attacker.
  • A spotter (a 1), can attack using the normal mechanism, but they can also try to "guess" the rank of the other player, which can be denoted with any sane notation.
  • If they guess correctly, the other piece dies: ["1(5)", "5"] -> ["1"].
  • If they guess wrong, nothing happens: ["1(3)", "5"] -> ["1", "5"].
  • Spotters can spot bombs: ["1(B)", "B"] -> ["1"].

This is , so shortest code in bytes wins!

(You can use the examples up there as test-cases, because I'm too lazy to put them all together in one list).

Maltysen

Posted 2016-06-26T18:02:36.687

Reputation: 25 023

can we use 0 and 11 to represent S and B respectively? – Leaky Nun – 2016-06-26T23:17:00.403

@LeakyNun no, that would make it too easy to rank them. – Maltysen – 2016-06-26T23:18:46.653

1I knew about the reversal of ranks (1s used to be best, beaten only by attacking spies, 8s were miners, and 9s were worst), but I never heard of the spotter rank or guess-and-you-win rule. But that's just me babbling. Of actual interest here: What about flags? – msh210 – 2016-06-27T15:33:53.257

1@msh210 I was considering having an output of "Victory!" for them, but didn't want to complicate things too much – Maltysen – 2016-06-27T19:00:00.187

Doesn't a Spy win any battle (if the one attacking), with the exception of a Bomb, and lose all defenses? And what set of Stratego rules is this from? Spotters (Scouts) would be 2s, and there were no 1s in my Stratego game... (or are they just modified for the purpose of the challenge?) – mbomb007 – 2016-06-29T20:30:19.297

@mbomb007 idk, its the one I have in my house. 2s are still scouts, but don't have any special rule for attacking. And yeah, I don't know if all the games have special rules for 1's , but mine did. – Maltysen – 2016-06-29T20:37:24.163

2s could move like Rooks in mine. – mbomb007 – 2016-06-29T20:38:48.700

@mbomb007 they do in mine also, but the attacking mechanics are the same. – Maltysen – 2016-06-29T20:39:24.600

Answers

3

Haskell, 131 bytes

This solution is in the form of an infix function # with type String -> String -> String

Input is accepted through the two string arguments. The format for spotter input is 1 x where x is the guess.Output is given as a string. In the case where both units survive, the returned string contains both separated by a space.

My original solution was unfortunately bugged and the fix cost me a few bytes.

('1':' ':x)#y|x==y="1"|1>0="1 "++y
"S"#"10"="S"
"3"#"B"="3"
_#"B"="B"
x#y|x==y=[]
t@"10"#_=t
_#t@"10"=t
"S"#x=x
x#"S"=x
x#y=max x y

ankh-morpork

Posted 2016-06-26T18:02:36.687

Reputation: 1 350

1

Python, 180 153 bytes

def f(a,d,g=0):T=([[d]],[[a]]);return([[a]+[d]*(g!=d)]*(g!=0)+[[]]*(a==d)+T[d=="10"]*(a=="S")+T[1]*(d=="S")+T[a=="3"]*(d=="B")+T[int(a,36)>int(d,36)])[0]

The function takes the attacker, defender and optionally the spotter's guess (if the attacker is the spotter) as arguments. It returns an array containing the live pieces that remain.

Ungolfed

def f(a,d,g=0):
 if g: return [a] if g==d else [a,d]
 if a==d: return []
 if a=="S": return [a] if d=="10" else [d]
 if d=="S": return[a]
 if d=="B": return [a] if a=="3" else [d]
 return [a] if int(a)>int(d) else [d]

Demo

https://repl.it/C6Oz/2

Chuck Morris

Posted 2016-06-26T18:02:36.687

Reputation: 456

([a,d],[a])[g==d] -> [a,d][:(g!=d)+1] – Leaky Nun – 2016-06-26T23:20:20.810

@Leaky Nun - Thanks, and [a]+[d]*(g==d) is shorter still. – Chuck Morris – 2016-06-27T00:13:03.490

1

Javascript ES6, 98 86 bytes

(a,b,g)=>a==1?b==g?a:[a,b]:b=="B"?a==3?a:b:a=="S"?b==10?a:b:b=="S"?a:a==b?[]:+a>+b?a:b

Accepts 3 args (attacker, defender, spotter guess).

Example runs:

f("4","6")     -> "6"
f("7","7")     -> []
f("S","2")     -> "2"
f("S","10")    -> "S"
f("10","S")    -> "10"
f("5","B")     -> "B"
f("3","B")     -> "3"
f("1","5","5") -> "1"
f("1","5","3") -> ["1","5"]
f("1","B","B") -> "1"

Dendrobium

Posted 2016-06-26T18:02:36.687

Reputation: 2 412

1If you don't need to return an array, you can save a handful of bytes. – Not that Charles – 2016-06-27T17:46:35.447

Your code isn't working correctly for me when a spotter does not make a guess. f("1","10") -> ["1","10"] rather than "10". – ankh-morpork – 2016-06-27T18:47:39.517

0

Javascript, 179 166 160 bytes

f=(a,c,b,n="")=>{if(c)if(c==b)return[a];else return[a,b];if(a==b)return[];a+b=="3B"&&(b=n);a=b=="B"?n:a;b=b=="S"?n:b;a+b=="S10"&&(a=n,b="S");return[+a>+b?a:b]}

This function takes 3 arguments - first one is attacker, second is used for spotters (their guess) and third is defender.

f = ( a, c, b, n = "" ) =>
{
 //Takes attacker (a), guess (c) and defender (b), n is only declaration
 //c should never be set unless a == 1 
 if ( c )
  if ( c == b ) return [ a ];
  else return[ a, b ]; //Spotters
 
 if( a == b ) return [ ]; //Kill each other if same

 a + b == "3B" && ( b = n ); //Miners destroy bombs
 a = b == "B" ? n : a; //Bomb kills almost everything
 b = b == "S" ? n : b; //Spy dies if anything attacks him
 a + b == "S10" && ( a = n, b = "S" ); //Spies kill 10s

 console.log( JSON.stringify( [a,b] ) );

 return [ +a > +b ? a : b ] //Higher number wins
}

function fight( )
{
 var input = [ [ attacker.value, guess.value], defender.value ];
 out.innerHTML += JSON.stringify( input ) + "   ->   " + JSON.stringify( f( input[0][0], input[0][1], input[1] ) ) + "<br>";
}
#sword
{
 width: 40px;
 height: auto;
 margin: 10px;
 cursor: pointer;
 
}

#guess
{
 width: 40px;
}

textarea
{
 height: 20px;
 margin-top: 0px;
}

.panel
{
 background-color: #DDDDDD;
 padding: 5px;
 border: 3px solid black;
}

#out
{
 border: 3px solid black;
 font-family: monospace;
 padding: 10px;
}
<table>
 <tr>
  <td class=panel>
   <textarea id=attacker placeholder="Attacker"></textarea>
   <textarea id=guess></textarea>
  </td>
  
  <td>
   <img onclick="fight()" id=sword src="http://cliparts.co/cliparts/8cx/Kjq/8cxKjqAKi.png"></img>
  </td>
  
  <td class=panel>
   <textarea id=defender placeholder="Defender"></textarea>
  </td>
 </tr>
  
 <tr>
  <td colspan=3>
   <div id=out></div>
  </td>
 </tr>
</table>

Sword icon comes from cliparts.co

Jacajack

Posted 2016-06-26T18:02:36.687

Reputation: 501

0

TSQL, 162 124 bytes

Golfed:

DECLARE @1 varchar(2)='1',@ varchar(2)='3',@s varchar(2)='4'

PRINT IIF(@s>'',IIF(@=@s,@1,@1+','+@),IIF(@1=@,'',IIF(@1+@
IN('S10','3B')or'S'=@,@1,IIF(@='B'or'S'=@1,@,IIF(@1/1<@,@1,@)))))

Ungolfed:

DECLARE 
  @1 varchar(2)='1', -- first piece
  @  varchar(2)='3',  -- second piece
  @s varchar(2)='4'  -- spotter(only fill this value for spotters)

PRINT
  IIF(@s>'',
    IIF(@=@s,@1,@1+','+@),
      IIF(@1=@,'',
        IIF(@1+@ IN('S10','3B')or'S'=@,@1,
          IIF(@='B'or'S'=@1,@,
            IIF(@1/1<@,@1,@)))))

Fiddle

t-clausen.dk

Posted 2016-06-26T18:02:36.687

Reputation: 2 874