11
\$\begingroup\$

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

\$\endgroup\$
8
  • \$\begingroup\$ can we use 0 and 11 to represent S and B respectively? \$\endgroup\$
    – Leaky Nun
    Commented Jun 26, 2016 at 23:17
  • \$\begingroup\$ @LeakyNun no, that would make it too easy to rank them. \$\endgroup\$
    – Maltysen
    Commented Jun 26, 2016 at 23:18
  • 1
    \$\begingroup\$ I 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? \$\endgroup\$
    – msh210
    Commented Jun 27, 2016 at 15:33
  • 1
    \$\begingroup\$ @msh210 I was considering having an output of "Victory!" for them, but didn't want to complicate things too much \$\endgroup\$
    – Maltysen
    Commented Jun 27, 2016 at 19:00
  • \$\begingroup\$ 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?) \$\endgroup\$
    – mbomb007
    Commented Jun 29, 2016 at 20:30

5 Answers 5

3
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ ([a,d],[a])[g==d] -> [a,d][:(g!=d)+1] \$\endgroup\$
    – Leaky Nun
    Commented Jun 26, 2016 at 23:20
  • \$\begingroup\$ @Leaky Nun - Thanks, and [a]+[d]*(g==d) is shorter still. \$\endgroup\$ Commented Jun 27, 2016 at 0:13
1
\$\begingroup\$

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"
\$\endgroup\$
2
  • 1
    \$\begingroup\$ If you don't need to return an array, you can save a handful of bytes. \$\endgroup\$ Commented Jun 27, 2016 at 17:46
  • \$\begingroup\$ Your code isn't working correctly for me when a spotter does not make a guess. f("1","10") -> ["1","10"] rather than "10". \$\endgroup\$ Commented Jun 27, 2016 at 18:47
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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