Simulate a 'battle' in the playing card game 'Oorlog'

q - 142 characters

{p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}

Note: zero indexed.

There is no notion of reading stdin in q, so you should call it as a function: {p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}[1,2,3]

Pretty long, actually, but there are plenty of corner cases. It keeps a roster of active players, and consumes the list of cards in a loop. The most problematic thing is to detect the correct winner in hands like [13, 2, 3], since 3 beats 2, as normal, but it had to be duplicated to be put into the corner case.


JavaScript (ES6), 146 bytes

f=a=>(b=a.splice(0,3)).filter(m=>m-n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length>1?b.indexOf(n):f([...b.map(m=>m-n?0:a.shift()),...a])

Returns a zero-based index. 127 bytes if I'm allowed the initial deal as a separate array (this also works for an arbitrary number of hands of course):

f=(b,a)=>b.filter(m=>m==n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length<2?b.indexOf(n):f(b.map(m=>m-n?0:a.shift()),a)