* Игра написана весьма тупо - из-за множества циклов
* Аналитика на несколько ходов вперед отсутствует
* Играет компьютер с компьютером (это легко изменить)
program reverse;
{ Copyright (C) Igor Salnikov 2015 }
type
TCell = record
fig: integer;
mark: integer;
end;
TField = array[1..8,1..8] of TCell;
var
Field:TField;
function FigName(fig:integer):string;
begin
FigName:='.';
if fig=1 then FigName:='B'
else if fig=-1 then FigName:='R';
end;
procedure ResetField;
var i,j: integer;
begin
{ set init position }
Field[4,4].fig:=1;
Field[5,4].fig:=-1;
Field[4,5].fig:=-1;
Field[5,5].fig:=1;
end;
procedure CopyField;
begin
end;
procedure OnStart();
begin
//ClearField;
randomize;
ResetField;
end;
function sign(x:integer):integer;
begin
if x=0 then sign:=0
else if x>0 then sign:=1
else sign:=-1;
end;
function OnLine(fig,x1,y1,x2,y2:integer):boolean;
var dx,dy,c:integer;
px, py: integer;
begin
OnLine:=false;
if (Field[x1,y1].fig<>fig) or (Field[x2,y2].fig<>fig) then exit;
dx:=abs(x2-x1); dy:=abs(y2-y1);
if (dx=0) or (dy=0) or (dx=dy) then
begin
dx:=sign(x2-x1);
dy:=sign(y2-y1);
px:=x1+dx; py:=y1+dy;
OnLine:=true; c:=0;
while not ((px=x2) and (py=y2)) do
begin
if Field[px,py].fig<>-fig then
begin
OnLine:=false;
break;
end;
px:=px+dx;
py:=py+dy;
c:=c+1;
end;
if c=0 then OnLine:=false;
end;
end;
function Invert(fig:integer; x,y:integer):integer;
var i, j: integer;
px, py: integer;
dx, dy: integer;
begin
for i:=1 to 8 do
for j:=1 to 8 do
if (i<>y) or (j<>x) then
if OnLine(fig,x,y,j,i) then
begin
dx:=sign(j-x);
dy:=sign(i-y);
px:=x; py:=y;
while not ((px=j) and (py=i)) do
begin
if Field[px,py].fig=-fig then
Field[px,py].mark:=1;
px:=px+dx;
py:=py+dy;
end;
end;
for i:=1 to 8 do
for j:=1 to 8 do
if Field[j,i].mark=1 then
begin
Field[j,i].mark:=0;
Field[j,i].fig:=fig;
end;
end;
procedure SetFigure(x,y:integer; fig:integer);
begin
Field[x,y].fig:=fig;
Invert(fig,x,y);
end;
function OnField(x,y:integer):boolean;
begin
if (x>=1) and (x<=8) and (y>=1) and (y<=8) then
OnField:=true else OnField:=false;
end;
function PosPower(fig:integer; x,y:integer):integer;
var k:integer;
nx, ny: integer;
step_x, step_y: integer;
step_power, power: integer;
begin
power:=0;
for step_y:=-1 to 1 do
for step_x:=-1 to 1 do
begin
if (step_x=0) and (step_y=0) then continue;
step_power:=0;
nx:=x+step_x; ny:=y+step_y;
while OnField(nx,ny) do
begin
if Field[nx,ny].fig=-fig then inc(step_power);
if Field[nx,ny].fig=fig then break;
if Field[nx,ny].fig=0 then
begin
step_power:=0; break;
end;
nx:=nx+step_x; ny:=ny+step_y;
end;
if not OnField(nx,ny) then step_power:=0;
power:=power+step_power;
end;
PosPower:=power;
end;
procedure GetNewPos(fig: integer; var x,y:integer);
type
TPara = record
x,y:integer;
end;
var i,j,p:integer;
max_p: integer;
max_save: array[1..60] of TPara;
max_count: integer;
begin
max_count:=0;
max_p:=0;
for i:=1 to 8 do
for j:=1 to 8 do
if Field[j,i].fig=0 then
begin
p:=PosPower(fig,j,i);
if p>max_p then
begin
max_p := p;
inc(max_count);
max_save[max_count].x:=j;
max_save[max_count].y:=i;
end;
end;
p:=random(max_count)+1;
x:=max_save[p].x;
y:=max_save[p].y;
end;
function HasPos(fig:integer):boolean;
var i,j:integer;
r:boolean;
begin
r:=false;
for i:=1 to 8 do
for j:=1 to 8 do
if (Field[j,i].fig=0) and (PosPower(fig,j,i)>0) then
r:=r or true;
HasPos:=r;
end;
{ cut off }
procedure Show;
var i,j:integer;
begin
for i:=1 to 8 do
begin
for j:=1 to 8 do
write(FigName(Field[j,i].fig),' ');
writeln;
end;
writeln;
end;
procedure OnClick(X,Y:integer);
var nx,ny:integer;
wait:boolean;
begin
if PosPower(1,X,Y)>0 then
begin
SetFigure(X,Y,1);
Show;
//Pause;
//SetLock(true);
//CopyField;
wait:=false;
while HasPos(-1) do
begin
GetNewPos(-1, nx, ny);
SetFigure(nx,ny,-1);
if HasPos(1) then
begin
wait:=true;
break;
end;
end;
//SetLock(false);
//if not wait then TheEnd;
end;
end;
procedure PrintCounters;
var i,j:integer;
b,r:integer;
begin
b:=0; r:=0;
for i:=1 to 8 do
for j:=1 to 8 do
if Field[j,i].fig=1 then inc(b)
else if Field[j,i].fig=-1 then inc(r);
writeln('B=',b,', R=',r);
end;
var nx,ny:integer;
begin
OnStart;
while HasPos(1) do
begin
GetNewPos(1, nx, ny);
OnClick(nx,ny);
Show;
PrintCounters;
end;
end.
Справочник алгоритмов v0.05 © 2007-2025 Igor Salnikov aka SunDoctor