Постановка задачи. Реализуйте известную игру «Пятнадцать», используя двумерный массив. Изначально числа расположены на 15 кнопках случайно. Результат работы после необходимых перестановок приведен на рис. 29. Надо учесть, что в данной игре не при всяком случайном расположении чисел возможен выигрыш.
Реализация. Опишем массив кнопок типа TButton и массив целых чисел. Глобальные данные:
const
n=4;
h=40; // Размер кнопки
x0=10; // Координаты левого верхнего угла поля
y0=10;
var a : array [1..n,1..n] of integer;
bt : array [1..n,1..n] of TButton;
i0, k0:integer; // Координаты пустого места
Рис. 29. Выигрыш в игре «Пятнадцать»
Процедура zapolnenie заполняет массив числами от 1 до 15, располагая их в случайные клетки поля.
procedure zapolnenie;
var i,j,k,m:integer;
zap:boolean;
begin
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
for i:=1 to n*n-1 do
begin
zap:=false;
repeat
k:=random(n)+1;
m:=random(n)+1;
if a[k,m]=0 then
begin
a[k,m]:=i;
zap:=true;
end;
until zap;
end;
end;
Процедура swap() меняет значения двух переменных.
procedure swap(var a,b:integer);
var r:integer;
begin
r:=b;
b:=a;
a:=r;
end;
Метод FMD нажатия на кнопку находит координаты нажатой кнопки, проверяет, свободно ли рядом, и если свободно, то меняет число с пустой кнопкой. В процедуре FMD числа i0, k0 – это координаты пустой кнопки.
if ((abs(i-i0)=1)and(k=k0))or((abs(k-k0)=1)and(i=i0))then
begin // Рядом свободно
swap(a[i,k],a[i0,k0]);
bt[i,k].Caption:=' ';
bt[i0,k0].Caption:=inttostr(a[i0,k0]);
i0:=i;
k0:=k;
end;
end;
Наконец, обработчик TForm1.FormCreate заполняет массив чисел от 1 до 15 в случайном порядке, создает массив кнопок, задает размеры кнопок, устанавливает свойства шрифта, размещает кнопки на форме в виде таблицы.
procedure TForm1.FormCreate(Sender: TObject);
var i,j:integer;
begin
randomize;
zapolnenie;
// Создадим массив кнопок
for i:=1 to n do
for j:=1 to n do
begin
bt[i,j]:=TButton.Create(Form1);
bt[i,j].Parent:=Form1;
bt[i,j].Width:=h;
bt[i,j].Height:=h;
bt[i,j].Left:=x0+(j-1)*h;
bt[i,j].Top:=y0+(i-1)*h;
bt[i,j].Font.Size:=18;
bt[i,j].Font.Style:=[fsBold];
if a[i,j]<>0 then
bt[i,j].Caption:=inttostr(a[i,j])
else
begin // Запомним кнопку, где пусто
i0:=i;
k0:=j;
end;
bt[i,j].Visible:=True;
bt[i,j].OnMouseDown:=FMD;
end;
end;
Задание. Организуйте проверку, получилось ли выигрышное расположение. Также для удобства положите на форму кнопку «Начать заново» и напишите соответствующий код.