program bmcp;
const
bs = 120; bc = bs - 1;
ms = 120; mc = ms - 1;
mp = 1200;
nsd = 3; { 2-3 quick idiot; 6 normal }
type
ti = integer;
tbo = boolean;
tb = array[0..bc] of ti;
tc = char;
tm = record
f, t, p, fl: byte;
end;
tma = record
a: array[0..mc] of tm;
c: ti;
end;
var
ba: tb;
cs, ep, bca, bf, ply: ti;
cbh: LongInt;
ha: array[0..mp] of LongInt;
bm: tm;
bmi: LongInt absolute bm;
const
ib: tb = (
7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,
7,12,10,11,13,14,11,10,12,7,
7,9,9,9,9,9,9,9,9,7,
7,0,0,0,0,0,0,0,0,7,
7,0,0,0,0,0,0,0,0,7,
7,0,0,0,0,0,0,0,0,7,
7,0,0,0,0,0,0,0,0,7,
7,1,1,1,1,1,1,1,1,7,
7,4,2,3,5,6,3,2,4,7,
7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7
);
pc: array[0..15] of char = ' PNBRQK pnbrqk ';
ps: array[0..7] of byte = (0,1,3,3,5,9,15,0);
po: array[0..7,0..8] of ti = (
(0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0),
(-21,-19,-12,-8,8,12,19,21,0),
(-11,-9,9,11,0,0,0,0,0),
(-10,-1,1,10,0,0,0,0,0),
(-11,-10,-9,-1,1,9,10,11,0),
(-11,-10,-9,-1,1,9,10,11,0),
(0,0,0,0,0,0,0,0,0)
);
pis: array[0..7] of boolean = (false,false,false,true,true,true,false,false);
cam: array[0..bc] of integer = (
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
7,15,15,15,3,15,15,11,0,0,
15,15,15,15,15,15,15,15,0,0,
15,15,15,15,15,15,15,15,0,0,
15,15,15,15,15,15,15,15,0,0,
15,15,15,15,15,15,15,15,0,0,
15,15,15,15,15,15,15,15,0,0,
13,15,15,15,12,15,15,14,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0
);
procedure hb;
var
i: ti;
j: LongInt;
begin
j := (LongInt(ep) * $40000000) xor (LongInt(bca) * $04000000);
for i := 20 to 99 do
j := j xor (LongInt(ba[i]) * i);
cbh := j;
end;
procedure nb;
begin
ba := ib;
cs := 0;
bca := 15;
ep := 1;
bf := 0;
ply := 0;
hb;
end;
procedure pb;
var
i, x, y: ti;
c: tc;
begin
for i := 10 to 109 do begin
x := i mod 10;
y := i div 10;
c := pc[ba[i] and 15];
if c = ' ' then
if y in [2..9] then
if x in [1..8] then
if (((x + y) and 1) <> 0) then c := #176 else c := #219
else
else
c := tc(48 + y)
else
if x in [1..8] then c := tc(96 + x);
write(c);
if x = 9 then writeln;
end;
writeln;
end;
function eb: integer;
var
i, j: ti;
begin
j := 0;
for i := 0 to bc do
if (ba[i] and 8) <> 0 then
dec(j, ps[ba[i] and 7])
else
inc(j, ps[ba[i] and 7]);
if cs = 8 then j := -j;
eb := j;
end;
procedure gm(var ma: tma; f, t, fl: ti);
var
i: ti;
begin
if ma.c >= ms then exit;
if ((fl and 16) <> 0) and (((cs = 0) and (t < 30)) or ((cs <> 0) and (t > 90))) then begin
for i := 2 to 5 do begin
if ma.c >= ms then exit;
ma.a[ma.c].f := f;
ma.a[ma.c].t := t;
ma.a[ma.c].p := i;
ma.a[ma.c].fl := fl or 32;
inc(ma.c);
end;
end else begin
ma.a[ma.c].f := f;
ma.a[ma.c].t := t;
ma.a[ma.c].p := 0;
ma.a[ma.c].fl := fl;
inc(ma.c);
end;
end;
procedure gma(var ma: tma);
var
i, j, p, n: integer;
begin
ma.c := 0;
for i := 21 to 99 do begin
if (ba[i] and 8) = cs then begin
p := ba[i] and 7;
if p = 1 then begin
if cs = 0 then begin
if (ba[i - 11] <> 0) and ((ba[i - 11] and 8) = 8) then gm(ma, i, i - 11, 17);
if (ba[i - 9] <> 0) and ((ba[i - 9] and 8) = 8) then gm(ma, i, i - 9, 17);
if ba[i - 10] = 0 then begin
gm(ma, i, i - 10, 16);
if (i >= 80) and (ba[i - 20] = 0) then gm(ma, i, i - 20, 24);
end;
end else begin
if (ba[i + 9] <> 0) and ((ba[i + 9] and 8) = 0) then gm(ma, i, i + 9, 17);
if (ba[i + 11] <> 0) and ((ba[i + 11] and 8) = 0) then gm(ma, i, i + 11, 17);
if ba[i + 10] = 0 then begin
gm(ma, i, i + 10, 16);
if (i <= 40) and (ba[i + 20] = 0) then gm(ma, i, i + 20, 24);
end;
end;
end else begin
j := 0;
while po[p, j] <> 0 do begin
n := i;
while true do begin
inc(n, po[p, j]);
if ba[n] = 7 then break;
if ba[n] <> 0 then begin
if (ba[n] and 8) = (cs xor 8) then gm(ma, i, n, 1);
break;
end;
gm(ma, i, n, 0);
if not pis[p] then break;
end;
inc(j);
end;
end;
end;
end;
if cs = 0 then begin
if (bca and 1) <> 0 then gm(ma, 95, 97, 2);
if (bca and 2) <> 0 then gm(ma, 95, 93, 2);
end else begin
if (bca and 4) <> 0 then gm(ma, 25, 27, 2);
if (bca and 8) <> 0 then gm(ma, 25, 23, 2);
end;
if ep >= 0 then begin
if cs = 0 then begin
if ba[ep + 9] = 1 then gm(ma, ep + 9, ep, 21);
if ba[ep + 11] = 1 then gm(ma, ep + 11, ep, 21);
end else begin
if ba[ep - 11] = 9 then gm(ma, ep - 11, ep, 21);
if ba[ep - 9] = 9 then gm(ma, ep - 9, ep, 21);
end;
end;
end;
function iia(s, ncs: ti): tbo;
var
ocs, i: ti;
ma: tma;
begin
iia := false;
ocs := cs;
gma(ma);
for i := 0 to ma.c - 1 do
if ma.a[i].t = s then begin
iia := true;
break;
end;
cs := ocs;
end;
function iic(ncs: ti): tbo;
var
i: integer;
begin
iic := false;
for i := 20 to 99 do
if ba[i] = (6 or ncs) then begin
iic := iia(i, ncs xor 8);
exit;
end;
end;
function mm(const m: tm): tbo;
var
f, t, obf, obca, oep: ti;
oba: tb;
begin
mm := false;
obf := bf;
oba := ba;
obca := bca;
oep := ep;
if ((ba[m.f] and 8) <> cs) or ((ba[m.t] and 8) = 6) then exit;
if (m.fl and 2) <> 0 then begin
if iic(cs) then exit;
case m.t of
97: begin
if (ba[96] <> 0) or (ba[97] <> 0) or iia(96, cs xor 8) or iia(97, cs xor 8) then exit;
f := 98; t := 96;
end;
93: begin
if (ba[92] <> 0) or (ba[93] <> 0) or (ba[94] <> 0) or iia(93, cs xor 8) or iia(94, cs xor 8) then exit;
f := 91; t := 94;
end;
27: begin
if (ba[26] <> 0) or (ba[27] <> 0) or iia(26, cs xor 8) or iia(27, cs xor 8) then exit;
f := 28; t := 26;
end;
23: begin
if (ba[22] <> 0) or (ba[23] <> 0) or (ba[24] <> 0) or iia(23, cs xor 8) or iia(24, cs xor 8) then exit;
f := 21; t := 24;
end;
else begin f := 0; t := 0; end;
end;
ba[t] := ba[f];
ba[f] := 0;
end;
bca := bca and (cam[m.f] and cam[m.t]);
if (m.fl and 8) <> 0 then
if cs = 0 then ep := m.t + 8 else ep := m.t - 8
else ep := -1;
if (m.fl and 17) <> 0 then bf := 0 else inc(bf);
if (m.fl and 32) <> 0 then begin
ba[m.t] := (m.p and 7) or (ba[m.f] and 8);
ba[m.f] := 0;
end else begin
ba[m.t] := ba[m.f];
ba[m.f] := 0;
end;
if (m.fl and 4) <> 0 then
if cs = 0 then ba[m.t + 10] := 0 else ba[m.t - 10] := 0;
cs := cs xor 8;
if iic(cs xor 8) then begin
cs := cs xor 8;
bf := obf;
ba := oba;
bca := obca;
ep := oep;
exit;
end;
hb;
if ply < mp then begin
ha[ply] := cbh;
inc(ply);
end;
mm := true;
end;
function rc: ti;
var
i, j: ti;
begin
j := 0;
for i := ply - bf to ply - 1 do
inc(j, ord(ha[i] = cbh));
rc := j;
end;
function nss(a, b, d: ti): ti;
var
i, s, obf, obca, oep: ti;
oba: tb;
ma: tma;
f, c: tbo;
begin
if d <= 0 then begin
nss := eb;
exit;
end;
c := iic(cs);
inc(d, ord(c));
gma(ma);
f := false;
obf := bf;
oba := ba;
obca := bca;
oep := ep;
for i := 0 to ma.c - 1 do begin
if not mm(ma.a[i]) then continue;
f := true;
s := -nss(-b, -a, d - 1);
cs := cs xor 8;
bf := obf;
ba := oba;
bca := obca;
ep := oep;
if s > a then begin
if s >= b then begin
nss := b;
exit;
end;
a := s;
if d = nsd then bm := ma.a[i];
end;
end;
if not f then
if c then nss := -10000 + ply else nss := 0
else
if bf >= 100 then nss := 0 else nss := a;
end;
begin
nb;
pb;
writeln('Thinking...');
while true do begin
bmi := 0;
nss(-10000, 10000, nsd);
mm(bm);
if bmi = 0 then begin
if iic(cs) then writeln('CHECKMATE!') else writeln('STALEMATE!');
break;
end else if (bf >= 100) or (rc >= 3) then begin
writeln('DRAW!');
break;
end;
if iic(cs) then writeln('CHECK!');
pb;
end;
readln;
end.