Draw the Stickman Wars
JavaScript (E6) 336 344 356 369 424 478 522 570
Edit 6 Last edit was buggy. Bug fix and shortened. That's all I hope.
Edit 5 Finally found a way to get rid of multiply by 23 - bothered me from start. Plus another change to the input (@William shout when it's too much). Now the function expects one array parameter, containing 2 subarrays. Without this change it's 349 - still an improvement
Edit 4 Shaved some more bytes and a little change to input format.
With the new input format a missing class is represented as an empty array element. So D([1,,2,3,1],[,3,1,1,2])
instead of D([1,0,2,3,1],[0,3,1,1,2])
. I think it still obeys the rules.
Edit 3 Golfed more. No changes to the algorithm, but abusing a lot of array.map and local functions to avoid for loops.
Edit 2 String compression, the right way ...
Edit Added string compression, a lot of work and not much gained. Now the mirror stickmen are generated from a template, not stored.
Made a few tries, first running. To be golfed.
NB Kolmogorow-business still to be tackled.
Test In FireFox console. Change 'return' with Add 'alert(...)' to have an output statement (albeit not useful at all)
console.log(D([[1,,2,3,1],[,3,1,1,2]]))
Output
. . .
.' *. .' *. .* '.
' O * ' O * O / O / O / O A A O A O \ O * O ' O O O
O ' \|/ . ' \|/ . |/|\/ |/|\/ |/|\/ /|\| |/|\ |/|\ \/|\| . \|/ ' /|\ /|\ /|\
/|\ . | * . | * | | | | | | | | | | | | | | * | . | | |
/ \ './ \*. './ \*. / \ / \ / \ / \| |/ \ |/ \ / \ .*/ \.' / \ / \ / \
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Golfed Code
D=a=>
(J=v=>v.join(''))((l=[r=n=' ',3,6,13,19,23]).map(_=>f=(F=f=>J(a[f].map((c,q)=>
("9.299.' *.87O2' O *3O21 O A O 1|0' 0|1 .|1|01 1|0|1|0 | .2|2*| |4| |1 01 0'.1 0*. 1 021 0|"[R='replace'](/[2-9]/g,x=>n.repeat(x))
.slice(l[q]-r,l[q+1]-r)[R](/\d/g,x=>'\\/'[x^f])+n).repeat(c)+n+n
))+n)(0)+J([...F(1)].reverse(r-=23))+'\n'))+f[R](/./g,'¯')
Code (edit 2)
D=(a,b)=>{
F=(s,f)=>(s=s[R](/\d/g,x=>'/\\'[x^f]),f?s:[...s].reverse().join('')),
v="9.299.' *.87O2' O *3O21 O A O 1|0' 0|1 .|1|01 1|0|1|0 | .2|2*| |4| |1 01 0'.1 0*. 1 021 0|"
[R='replace'](/\d/g,x=>x>1?' '.repeat(x):x),
l=[0,3,6,13,19,23];
for(o='',r=0;v[r];r+=23,f=F(z,1)+' '+F(w,0),o+=f+'\n',f=f[R](/./g,'¯'))
for(z=w=p='';p<10;++p)
if(c=(p<5?a:b)[q=p%5])x=(v.slice(r+l[q],r+l[q+1])+' ').repeat(c)+' ',p<5?z+=x:w+=x
return o+f
}
Ungolfed code (1st version)
D=(a,b)=>{
v=" . . .' *. .* '. O ' O * O / O A * O ' \\ O A O O /|\\' \\|/ .|/|\\/ /|\\|. \\|/ ' \\/|\\||/|\\/|\\ | . | *| | | |* | . | || | / \\/ \\'./ \\*. / \\ / \\|.*/ \\'. / \\ |/ \\"
l=[0,3,6,13,19,23,30,36,40]
o=''
for(r=0;r<6;++r)
{
z=w=''
for(p=0;p<10;p++)
{
c=a[p]||b[p-5];
if (c)
{
q = p<7 ? p%5 : p-2
x = (v.slice(r*40+l[q],r*40+l[q+1])+' ').repeat(c)
if (p<5)
z+=x+' ';
else
w=x+' '+w
}
}
f = z + ' ' + w
o += f + '\n'
f = '¯'.repeat(f.length-3)
}
return o+f
}
Python 362 353
Edit: Removing one for-loop and using the exec statement saved 9 bytes
z,x,t,j=" ",input(),str.replace,0
w=0,3,6,13,19,23
a=9*z+"."+20*z+".' *."+15*z+"o ' o * o a o A o a|b' b|a .|a|ba a|b|a|b | . | *| | | |a ba b'.a b*. a b a b|"
exec"b=''\nfor c in 0,1:b+=z*8*c+t(t(' '.join([z.join([a[w[k]+j:w[k+1]+j]]*v)for k,v in enumerate(x[c])if v])[::1-2*c],'a','\/'[c<1]),'b','\/'[c])\nprint b;j+=23;"*6
print'-'*len(b)
Input:
[0,0,2,1,1],[1,0,2,1,2]
Output:
. . . .
.' *. .' *. .* '. .* '.
' o * ' o * o / o A A o A o \ o * o ' * o '
' \|/ . ' \|/ . |/|\/ /|\| |/|\ |/|\ \/|\| . \|/ ' . \|/ ' o
. | * . | * | | | | | | | | | | * | . * | . /|\
'./ \*. './ \*. / \ / \| |/ \ |/ \ / \ .*/ \.' .*/ \.' / \
---------------------------------------------------------------------------------
C, 418 414 404
−10 bytes thanks to ceilingcat
Example input:
stickwar.exe IVMMWWWS SWM
Example output:
. . . .' *. .' *. .* '. O ' O * ' O * O / O / O / O A A O \ O * O ' O /|\ ' \|/ . ' \|/ . |/|\/ |/|\/ |/|\/ /|\| |/|\ \/|\| . \|/ ' /|\ | . | * . | * | | | | | | | | | | | | * | . / \ / \ './ \*. './ \*. / \ / \ / \ / \| |/ \ / \ .*/ \'. ----------------------------------------------------------------------------------------
Golfed code:
char*s,d[8][999],*a;p,f,t,x,y,c,l;main(o,g)char**g;{for(memset(d,32,6993);o-=2,a=*++g;p+=3)for(;f=*a;t-4-o||strcpy(d[5]+p-1,"'."),p+=l&-o,f^*++a?p+=2:0)for(t=f%27%5,l=t*3%12%5+4,p+=l&o,y=6,s="(A(21;\0(A2:B(212;F\08A*B*0210KP\0-70A47/RT-A20G=CD?5D7_\0(A:(21;"+"V3'? "[t]-32;c=*s++;d[y][p+o*x]="/\\|O*'A."[c&7])x=c/16-2+(c&8?--y*0:x),c^=o-1&&!(c&6);for(y=!memset(d[6],45,p-=4);*(s=d[y++]);s[p]=0,puts(s));}
Maximal width of the battlefield is 999 (I could save 2 chars by limiting it to 99). I used a control structure of 1 byte per output character (non-space), drawing the figures from the bottom up.
- 1 bit for y-coordinate (either "stay" or "go up")
- 3 bits for x-coordinate displacement (0...4)
- 3 bits for output char (fortunately, there are only 8 different chars)
There are 5 offsets into the control structure.
Some other obscure bits:
- The code
f%27%5
translates the charactersVWSMI
to numbers0, 1, 2, 3, 4
- The code
t*3%12%5+4
calculates the width of the stickman of typet
- The code
t^3|~o||(s=d[5]+p,*s--=46,*s=39)
accounts for the left/right asymmetry - I use the fact that
argc=3
to generate drawing direction flags1
and-1
Ungolfed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char k[] = "(A(21;\0(A2:B(212;F\08A*B*0210KP\0-70A47/RT-A20G=CD?5D7_\0(A:(21;";
char d[8][999], // data of the battlefield
*s, // control string
*a; // cmdline argument
p, // position in the battlefield
f, // figure (char)
t, // type of the figure (0...4)
x,y, // coordinates while drawing the stickman
c; // control char, specifying what to draw
main(o, g) char**g; // o means "orientation" (+1, then -1)
{
freopen("out.txt", "w", stdout);
memset(d, ' ', 6993);
for (; o -= 2, a=*++g;)
{
for (; f=*a;)
{
t = f%27%5;
if (o<0)
p += t*3%12%5+4; // go to the next stickman
y = 6;
for (s=k+"V3'? "[t]-32; c = *s++;) // loop over the control
{
if (c & 8) // bit 3: next line; set x to 0
--y, x = 0;
x += c / 16 - 2; // bits 6...4: x coordinate
if (o == -1 && !(c & 6)) // mirror \ <-> /
c ^= 1;
d[y][p + o * x] = "/\\|O*'A."[c & 7];
}
if (t == 3 && o<0) // fix the asymmetrical mage
{
s=d[5]+p;
*s--='.';
*s='\'';
}
if (o>0)
p += t*3%12%5+4; // go to the next stickman
if (f != *++a) // is next stickman of different type?
p += 2;
}
p += 3; // separate the armies
}
p -= 4;
memset(d[6], '-', p); // draw the ground
for (y = 0; *(s=d[y++]); ) // print the battle field
{
s[p] = 0;
puts(s);
}
}