Проверка на наличие пяти меток в ряд. Сразу обозначим "пять" - понятием "выигрышное количество" (ВК). Нам нужно проверить наличие ВК меток в ряд по горизонтали, по вертикали, по диагонали, наклоненной влево, и по диагонали, наклоненной вправо. Допустим игровое поле у нас задается массивом целых чисел:
a: Array [1..10,1..10] of Byte;
Допустимые значения элементов этого массива: 0 - поле пусто, 1 - на поле "крестик", 2 - на поле "нолик". (Значения могут быть и другие - это не принципиально, важно то, что они, естественно, должны быть различными ) Наша функция будет возвращать true если ход игрока принесет ему победу и будет описываться так:
Function won(X,Y,P: Byte): Boolean;
где X - номер столбца массива в котором находится ячейка, куда игрок собирается поставить свою метку, Y - строка... , а P - значение поля, соответствующее метке игрока, совершающего ход (т.е. если P = 1, то в нашем случае это "крестик"). Рассмотрим случай по горизонтали.
Function won(x,y,p: Byte): Boolean; Const VK = 5; var i,j: Byte; begin i:=x; j:=x; while (a[y,i-1] = p) do Dec(i); while (a[y,j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end; won:=false end;
i,j - границы горизонтального интервала, который полностью заполнен метками P, и который содержит поле проверяемое функцией. Изначально эти границы совпадают. Рассматриваем метки слева от нашего поля: если слева от левой границы интервала стоит метка P, то подвигаем левую границу влево. Так же мы поступаем и с правой границей: если справа от правой границы интервала стоит метка P, то подвигаем правую границу вправо. Примечание: так как игра изначально начинается с пустого поля, то размер интервалов при проверке не будет превышать 2*ВК-1, поэтому не стОит делать проверку на превышение размером интервала ВК - оно все равно почти не повлияет на время выполнения. Теперь мы "расширяем" нашу функцию для проверок остальных направлений. Думаю, разобраться в этом "расширении", а также связать массив A с игровым полем не должно вызвать сложностей. Вот полный код функции:
Function won(x,y,p: Byte): Boolean; Const VK = 5; var i,j: Byte; begin i:=x; j:=x; while (a[y,i-1] = p) do Dec(i); while (a[y,j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=y; j:=y; while (a[i-1,x] = p) do Dec(i); while (a[j+1,x] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=x; j:=x; while (a[y-(x-i+1),i-1] = p) do Dec(i); while (a[y+(j-x+1),j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=x; j:=x; while (a[y+(x-i+1),i-1] = p) do Dec(i); while (a[y-(j-x+1),j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
won:=false end;
P.S.
Цитата
Подскажите как сделать, чтобы поле увеличивалось вместе с окном.
ЧТО должно изменяться - размер ячеек или их количество?
Все просто. width, height - ширина и высота поля, отводимого под ячейки (в самом простом случае это сама форма). m, n - кол-во ячеек на поле по горизонтали и вертикали соответственно. a, b - соответственно ширина и высота одной ячейки. При каждом изменении размеров игрового поля нужно делать следующее:
Я использую такуб процедуру, но получается не очень:
procedure TForm7.FormResize(Sender: TObject); var I, J: integer; begin I:=Form7.ClientHeight; J:=Form7.ClientWidth; Pole.Height:=I; Pole.Width:=J; Pole.RowCount:=I div 15; Pole.ColCount:=J div 15; Form7.Caption:='Крестики - Нолики '+IntToStr(Pole.RowCount)+'x'+IntToStr(Pole.ColCount); end;
Не работает твой код пяти в ряд. Вот процедура и функция, немного измененная:
procedure TForm8.poleSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if pole.Cells[ACol, ARow]='' then begin if fig.ItemIndex=0 then begin Pole.Cells[ACol, ARow]:=' x'; if won(ACol, ARow, ' x')=true then ShowMessage('Крестики выграли'); end; if fig.ItemIndex=1 then begin Pole.Cells[ACol, ARow]:=' o'; if won(ACol, ARow, ' o')=true then ShowMessage('Нолики выграли'); end; fig.ItemIndex:=fig.ItemIndex-1; if fig.ItemIndex<0 then fig.ItemIndex:=1; end; end;
function TForm8.won(x,y: Byte; p:string): Boolean; Const VK = 5; var i,j: Byte; begin i:=x; j:=x; while (Form8.pole.Cells[y,i-1] = p) do Dec(i); while (Form8.pole.Cells[y,j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=y; j:=y; while (Form8.pole.Cells[i-1,x] = p) do Dec(i); while (Form8.pole.Cells[j+1,x] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=x; j:=x; while (Form8.pole.Cells[y-(x-i+1),i-1] = p) do Dec(i); while (Form8.pole.Cells[y+(j-x+1),j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;
i:=x; j:=x; while (Form8.pole.Cells[y+(x-i+1),i-1] = p) do Dec(i); while (Form8.pole.Cells[y-(j-x+1),j+1] = p) do Inc(j); if j-i >= VK-1 then begin won:=true; exit end;