Существует много способов обойти доску конем, задача представленная здесь использует правило Варнсдорфа которое гласит что "На каждом ходу надо ставить коня на такое поле, из которого можно совершить наименьшее число ходов на еще не пройденные поля. Если таких полей несколько, разрешается выбирать любое из них." Подробнее о методе смотрите здесь. unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; PaintBox1: TPaintBox; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { private declarations } public { public declarations } end; var i,j,k,l,s,z :integer; var A_x,A_y,A_nx,A_ny,A_kol :integer; //А - начальная позиция коня var B_x,B_y,B_nx,B_ny,B_kol :integer; //В - возможная позиция коня (с помощью В мы будим делать всевозможные ходы из А и проверять их на количество возможных ходов из них, позиция из которой будит минимальное количество ходов станет позицией А то есть мы перейдем на эту позицию и занесем её в массив посещенных клеток) var R_x,R_y :integer; var str :String; var mov1: Array[1..8] of integer;//- // |-D алгоритм mov2: Array[1..8] of integer;//- mov3: Array[0..1000,0..1000] of integer; //массив для уже пройденных ходов Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin //---------------Отрисовка доски----------------------------------- for i:=1 to 4 do begin for j:=1 to 4 do begin PaintBox1.Canvas.Brush.Color:=clBlack; PaintBox1.Canvas.Rectangle(0+l,0+k,80+l,80+k); l:=l+80; PaintBox1.Canvas.Brush.Color:=clWhite; PaintBox1.Canvas.Rectangle(0+l,0+k,80+l,80+k); l:=l+80; end; l:=0; k:=k+80; for j:=1 to 4 do begin PaintBox1.Canvas.Brush.Color:=clWhite; PaintBox1.Canvas.Rectangle(0+l,0+k,80+l,80+k); l:=l+80; PaintBox1.Canvas.Brush.Color:=clBlack; PaintBox1.Canvas.Rectangle(0+l,0+k,80+l,80+k); l:=l+80; end; l:=0; k:=k+80; end; //------------------------------D алгоритм -------В него заносятся всевозможные ходы коня из клетки их всего 8 но в определенном порядке При наличии нескольких допустимых(одинаковых) ходов условимся выбирать тот из них, который сформирован с помощью самого левого столбца D для разрешения массив 1 это координаты по Х массив 2 по Y---------------------------- mov1[1]:=2; mov1[2]:=1; mov1[3]:=2; mov1[4]:=-2; mov1[5]:=-1; mov1[6]:=-1; mov1[7]:=1; mov1[8]:=-2 mov2[1]:=-1; mov2[2]:=-2; mov2[3]:=1; mov2[4]:=1; mov2[5]:=-2; mov2[6]:=2; mov2[7]:=2; mov2[8]:=-1; //--------------------------------------------------------------------------- l:=0;k:=1;i:=0;j:=1; //переобозначение после отрисовки доски (чтобы не вводить новые переменные) A_kol:=8; B_kol:=8;//количество возможных ходов в начале обозначается максимальным числом ходов коня из клетки то есть 8 A_x:=40; A_y:=40; // координаты начальной клетки mov3[A_x][A_y]:=1; //заносим начальное положение коня кок посещенное //--------------------------Обозначение положения коня на доске и пройденные им клетки-------------------------------------------------- PaintBox1.Canvas.Brush.Color:=clred; PaintBox1.Canvas.Ellipse(A_x-4,A_y-4,A_x+4,A_y+4); str:= IntToStr(k); PaintBox1.Canvas.TextOut(A_x+6,A_y+6,str); PaintBox1.Canvas.Brush.Color:=clwhite; //---------------------------------------------------------------------------- Timer1.Enabled:=True end; procedure TForm1.Timer1Timer(Sender: TObject); begin k:=k+1; for i:=1 to 63 do //цикл определяющий общее количество необходимых ходов для обхода доски 8*8=64 всего 64 но -1(начальное положение) всего 63 begin for s:=1 to 8 do //цикл проверяющий на возможный ход коня из А begin if (A_x+mov1[s]*80>= 40)and(A_y+mov2[s]*80 >= 40)and(A_x+mov1[s]*80 <= 600)and(A_y+mov2[s]*80 <= 600)and(mov3[A_x+mov1[s]*80][A_y+mov2[s]*80]=0) //число не должно выходить за рамки доски и присутствовать в массиве посещенных ходов. then begin A_kol:= 0; A_nx := A_x + mov1[s]*80; A_ny := A_y + mov2[s]*80; for z:=1 to 8 do //цикл подсчитывающий количество возможных ходов из предполагаемого хода begin if (A_nx+mov1[z]*80>=40)and(A_ny+mov2[z]*80>=40)and(A_nx+mov1[z]*80<=600)and(A_ny+mov2[z]*80<=600)and(mov3[A_nx+mov1[z]*80][A_ny+mov2[z]*80]=0) then A_kol:=A_kol+1; end; end; if B_kol>A_kol then begin B_x:=A_nx; B_y:=A_ny; B_kol:=A_kol; end; end; { PaintBox1.Canvas.pen.Color:=clred; PaintBox1.Canvas.Pen.Width:=5; PaintBox1.Canvas.MoveTo(A_x,A_y); PaintBox1.Canvas.LineTo(B_x,B_y); PaintBox1.Canvas.Brush.Color:=clwhite; } A_x:=B_x; A_y:=B_y; A_nx:=0; A_ny:=0; A_kol:=8; B_kol:=8; mov3[A_x][A_y]:=1; //--------------------------Обозначение положения коня на доске и пройденные им клетки-------------------------------------------------- PaintBox1.Canvas.Brush.Color:=clred; PaintBox1.Canvas.Ellipse(A_x-4,A_y-4,A_x+4,A_y+4); str:= IntToStr(k); PaintBox1.Canvas.TextOut(A_x+6,A_y+6,str); PaintBox1.Canvas.Brush.Color:=clwhite; end; j:=j+1; if j=64 then begin Timer1.Enabled:=False; end; end; end.
Ключевые слова:
Конь, шахматная доска, Delphi
|
|||||||