program test1; uses crt,my_input; {$R+} const n=10; inf=2000000000; drow=0; nol=-2; cross=-1; null=4; rad1=1; rad2=2; out=-3; max_ply1=2; max_ply=3; type tmove=record x,y,s : shortint; end; type toffset=record x,y : shortint; end; const mr1:array[1..16] of shortint =(-1,0,1, -1, 1, -1,0,1, -1,-1,-1, 0, 0, 1,1,1); const mr2:array[1..32] of shortint =(-2,-1,0,1,2, -2, 2, -2, 2, -2, 2, -2,-1,0,1,2, -2,-2,-2,-2,-2, -1, -1, 0, 0, 1, 1, 2, 2, 2, 2, 2); var field : array[-2..n+3,-2..n+3] of integer; history : array[0..max_ply,-2..n+3,-2..n+3] of shortint; pos : array[0..max_ply] of longint; position : longint; function evaluate(color:integer):longint;forward; procedure print;forward; function ev_step(color:integer;ii,jj:longint):longint;forward; procedure makemove(move:tmove;ply:integer); var i,j:integer; begin for i:=1to n do for j:=1 to n do history[ply,i,j]:=field[i,j]; with move do begin field[x,y]:=s; for i:=1 to 8 do begin if field[x+mr1[i],y+mr1[i+8]]>0 then field[x+mr1[i],y+mr1[i+8]]:=rad1; end; for i:=1 to 16 do if field[x+mr2[i],y+mr2[i+16]]>1 then field[x+mr2[i],y+mr2[i+16]]:=rad2; end; end; procedure unmakemove(ply:integer); var i,j : integer; begin for i:=1 to n do for j:=1 to n do field[i,j]:=history[ply,i,j]; end; function seach1(var move : tmove; color:integer; ply : integer):longint; var _move,bestmove,fmove : tmove; score,tmp : longint; i,j,opcolor : integer; begin score:=-inf-1; if color=cross then opcolor:=nol else opcolor:=cross; if ply=max_ply1 then if ply mod 2<>0 then begin seach1:=evaluate(color) -evaluate(opcolor)div 1000; exit; end else begin seach1:=evaluate(color)div 7 -evaluate(opcolor); exit; end; for i:=1 to n do for j:=1 to n do begin _move.x:=i; _move.y:=j; if (field[_move.x,_move.y]<>rad1) and(field[_move.x,_move.y]<>rad2) then continue; _move.s:=color; makemove(_move,ply); if ev_step(color,_move.x,_move.y)=inf then begin seach1:=inf; unmakemove(ply); move:=_move; exit; end; tmp:=-seach1(fmove,opcolor,ply+1); unmakemove(ply); if tmp>score then begin score:=tmp; bestmove:=_move; end; end; move:=bestmove; seach1:=score; end; function seach2(var move : tmove; color:integer; ply : integer; alpha,beta:longint):longint; var _move,bestmove,fmove,amove : tmove; score,tmp : longint; i,j,opcolor : integer; begin score:=-inf-1; if color=cross then opcolor:=nol else opcolor:=cross; if ply=max_ply then if ply mod 2<>0 then begin seach2:=evaluate(color) -evaluate(opcolor)div 100; exit; end else begin seach2:=evaluate(color)div 10 -evaluate(opcolor); exit; end; for i:=1 to n do for j:=1 to n do begin _move.x:=i; _move.y:=j; if field[_move.x,_move.y]<>rad1 then continue; _move.s:=color; makemove(_move,ply); if ev_step(color,_move.x,_move.y)=inf then begin seach2:=inf; unmakemove(ply); move:=_move; exit; end; tmp:=-seach2(fmove,opcolor,ply+1,-beta,-alpha); unmakemove(ply); if tmp>score then begin score:=tmp; bestmove:=_move; end; if score>alpha then begin alpha:=score; amove:=bestmove; end; if alpha>beta then begin seach2:=alpha; move:=amove; exit; end; end; move:=bestmove; seach2:=score; end; procedure activate_field; var i,j : integer; begin for i:=-2 to 0 do for j:=-2 to n+3 do field[i,j]:=out; for i:=-2 to 0 do for j:=-2 to n+3 do field[j,i]:=out; for i:=n+1 to n+3 do for j:=-2 to n+3 do field[i,j]:=out; for i:=n+1 to n+3 do for j:=-2 to n+3 do field[j,i]:=out; for i:=1 to n do for j:=1 to n do field[i,j]:=null; end; {----------------------------EVALUATE-----------------------------------} type tvert=array[1..20] of integer; const vert : tvert = (0,0,0,0,0, -1,-2,-3,-4,-5, 0,0,0,0,0, 1,2,3,4,5); hor : tvert = (-1,-2,-3,-4,-5, 0,0,0,0,0, 1,2,3,4,5, 0,0,0,0,0); diag1 : tvert = (-1,-2,-3,-4,-5, -1,-2,-3,-4,-5, 1,2,3,4,5, 1,2,3,4,5); diag2 : tvert = (1,2,3,4,5, -1,-2,-3,-4,-5, -1,-2,-3,-4,-5, 1,2,3,4,5); const ee=10; function evaluate(color:integer):longint; var ii,jj,i,j,k,l,pos,ev,pol : longint; fl,fl1,win,fl2 : boolean; procedure ev_(vert:tvert); var i : integer; begin pos:=1; pol:=1; fl:=false; fl1:=true; fl2:=false; for i:=1 to 4 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<4 then if field[ii+vert[i+1],jj+vert[i+6]]=color then fl:=true else break else if field[ii+vert[i+1],jj+vert[i+6]]=color then begin pol:=pol*ee; fl2:=true; end; fl1:=false; end; else begin fl:=true; k:=i; break; end; end;{case} end; fl1:=true; for i:=11 to 14 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<14 then if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then fl2:=true else break else if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then begin pol:=pol*ee; end; fl1:=false; end; else begin if fl and(k+i-10<5) then pol:=0; fl:=true; break; end; end;{case} end; if pol>10000000 then pol:=10000000; if fl or fl2 then ev:=ev+pol else ev:=ev+pol*ee; if pos>4 then win:=true; end; begin ev:=0; win:=false; for ii:=1 to n do begin for jj:=1 to n do begin if field[ii,jj]=color then begin ev_(vert); ev_(hor); ev_(diag1); ev_(diag2); end;{if} if win then break; end; if win then break; end; if win then ev:=inf; evaluate:=ev; end; function ev_step(color:integer;ii,jj:longint):longint; var i,j,k,l,pos,ev,pol : longint; fl,fl1,win,fl2 : boolean; procedure ev_(vert:tvert); var i : integer; begin pos:=1; pol:=1; fl:=false; fl1:=true; fl2:=false; for i:=1 to 4 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<4 then if field[ii+vert[i+1],jj+vert[i+6]]=color then fl:=true else break else if field[ii+vert[i+1],jj+vert[i+6]]=color then begin pol:=pol*ee; fl2:=true; end; fl1:=false; end; else begin fl:=true; k:=i; break; end; end;{case} end; fl1:=true; for i:=11 to 14 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<14 then if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then fl2:=true else break else if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then begin pol:=pol*ee; end; fl1:=false; end; else begin if fl and(k+i-10<5) then pol:=0; fl:=true; break; end; end;{case} end; if pol>10000000 then pol:=10000000; if fl or fl2 then ev:=ev+pol else ev:=ev+pol*ee; if pos>4 then win:=true; end; begin win:=false; if field[ii,jj]=color then begin ev_(vert); ev_(hor); ev_(diag1); ev_(diag2); end;{if} if win then ev:=inf; ev_step:=ev; end; {------------------END OF EVULATE-------------------------------------} procedure print; var i,j : integer; begin clrscr; for i:=1 to n do begin for j:=1 to n do begin case field[i,j] of rad1: write('1'); rad2: write('2'); cross: write('x'); nol: write('o'); null: write('.'); out: write('t'); else write('?'); end; end; writeln; end; end; procedure print2; var i,j : integer; begin clrscr; writeln(' THE GAME ''CROSSES AND NILS'' '); writeln(' FOR EXIT INPUT COORDINATES (0;0)'); writeln; write(' '); for i:=1 to n do write(i mod 10); writeln; for i:=1 to n do begin write(i mod 10); for j:=1 to n do begin case field[i,j] of rad1: write('.'); rad2: write('.'); cross: write('X'); nol: write('O'); null: write('.'); out: write('t'); else write('?'); end; end; writeln; end; end; var i,j : integer; move : tmove; res : longint; rk : char; Begin clrscr; activate_field; writeln(' THE GAME ''CROSSES AND NILS'' '); writeln; writeln('INPUT ''1'' IF YOU WANT TO BE THE FIRST'); readln(rk); if rk='1' then begin {repeat j:=1; print2; writeln('YUOR MOVE'); writeln('INPUT NUMBER OF VERTICAL'); inputshort(move.x); writeln('INPUT NUMBER OF HORISONTAL'); inputshort(move.y); move.s:=cross; if ((move.x>0)and(move.x<=n)and(move.y>0)and(move.y<=n)) then makemove(move,0) else if (move.x=0)and(move.y=0) then halt(0) else begin writeln('YOU ARE WRONG'); wait; continue; end; break; until false;} end else begin randomize; j:=1; move.x:=random(n-4)+2; move.y:=random(n-4)+2; move.s:=nol; makemove(move,0); end; repeat print2; writeln('YUOR MOVE'); writeln('INPUT NUMBER OF VERTICAL'); inputshort(move.x); writeln('INPUT NUMBER OF HORISONTAL'); inputshort(move.y); move.s:=cross; if ((move.x>0)and(move.x<=n) and(move.y>0)and(move.y<=n)) then if (field[move.x,move.y]<>cross) and(field[move.x,move.y]<>nol) then makemove(move,0) else begin writeln('YOU ARE WRONG'); wait; continue; end else if (move.x=0)and(move.y=0) then break else begin writeln('YOU ARE WRONG'); wait; continue; end; print2; if evaluate(cross)=inf then begin write('YOU WIN'); wait; halt(0); end; if j>=n*n-1 then break; seach1(move,nol,0); makemove(move,0); print2; if evaluate(nol)=inf then begin writeln('YOU LOSE'); wait; halt(0); end; j:=j+2; until false; writeln('DRAW'); wait; End.