Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
пояснит записка сане.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
101.13 Кб
Скачать

Глава 2. Описание и функциональные возможности программы

2.1 Особенности построения и работы алгоритма

В разрабатываемом программном приложении мы использовали:

  1. Класс TForm — это важнейший компонент Delphi, на котором основана вся работа этой системы по проектированию и разработке приложений. Форма (Класс TForm) содержит обширный набор свойств, методов и событий, позволяющих легко настраивать и организовывать самые сложные алгоритмы ее функционирования. Все свойства описаны в инспекторе объектов.

  2. TGroupBox – группа элементов. Этот компонент используется для группировки нескольких связанных по смыслу компонентов.

  3. TCheckBox - независимый переключатель. Щелчок мышью на этом компоненте в работающей программе изменяет его логическое свойство Checked.

  4. TComboBox – комбинированный список. Комбинированный, или раскрывающийся, список TComboBox представляет собой комбинацию списка TListBox и текстового поля TEdit, и поэтому большая часть его свойств и методов заимствованы у этих компонентов.

  5. TRadioGroup - группа зависимых переключателей. Содержит специальные свойства для обслуживания нескольких связанных зависимых переключателей.

  6. TButton – кнопка. Компоненты TButton широко используются для управления программами

После запуска программы перед пользователем появляется основная форма с семью кнопками «новая игра», «решить», «сохранить», «загрузить», «применить», «выход» и «уровень», реализованные с помощью TButton.

При запуске программы появляется форма, изображенная на (Рис.3).

Рис.3 Основная форма

В качестве основных алгоритмов рассмотрим следующие примеры.

Формирование «sudoku 9x9»

procedure TForm1.Button5Click(Sender: TObject);

var ix,iy,s:integer;

level:Textfile;

masfile:string;

begin

assignfile(level,'lev1.txt'); {чтение значений ячеек из файла (в данном примере для уровня 1)}

reset(level);

for iy := 1 to 9 do {формирование строки}

begin

readln(level,masfile);

for ix:=1 to 9 do {формирование столбца}

if masfile[ix]='#' then CEdits[ix,iy].Text:='' else CEdits[ix,iy].Text:=masfile[ix];

{проверка в файле если встречается символ «#» то ячейка заполняется как пустая}

end;

closefile(level);

Form3.Close;{закрывает форму выбора уровня}

newgame:=1;

end;

Проверка подстановки чисел в ячейки

function sudInLine(s:TSudoku;p:TPoint;v:integer):boolean;//проверяем можно ли цифру подставить на данное место

var

i:1..9;

begin

Result:=True;

for i:=1 to 9 do

if p.y<>i then //есть ли данное значение в строке

if s[p.X,i]=v then Exit;

Result:=False;

end;

function sudInRow(s:TSudoku;p:TPoint;v:integer):boolean;

var

i:1..9;

begin

Result:=True;

for i:=1 to 9 do

if p.x<>i then //есть ли данное значение в столбце

if s[i,p.Y]=v then Exit;

Result:=False;

end;

function sudInSq(s:TSudoku;p:TPoint;v:integer):boolean;

var

ix,iy:0..8;

lx,ly:0..8;

begin

lx:=0; ly:=0;

if p.x in [1,2,3] then lx:=1; //есть ли данное значение в квадрате

if p.x in [4,5,6] then lx:=4;

if p.x in [7,8,9] then lx:=7;

lx:=lx-1;

if p.y in [1,2,3] then ly:=1;

if p.y in [4,5,6] then ly:=4;

if p.y in [7,8,9] then ly:=7;

ly:=ly-1;

Result:=True;

for ix:=1 to 3 do

for iy:=1 to 3 do

if (p.x<>lx+ix) and (p.y<>ly+iy) then

if s[lx+ix,ly+iy]=v then Exit;

Result:=False;

end;

function sudInAny(s:TSudoku;p:TPoint;v:integer):boolean; //если цифра есть в линии, столбце или квадрате то мы ее исключаем

begin

Result:=sudInLine(s,p,v) or sudInRow(s,p,v) or sudInSq(s,p,v);

end;

Поиск пустой ячейки

function IsNextUnknown(s:TSudoku;var p:TPoint):boolean;//ищем пустую ячейку

var

ix,iy:1..9;

begin

Result:=False;

for ix:=1 to 9 do //идем по всем клеткам

for iy:=1 to 9 do

if s[ix,iy]=0 then begin //если значение равно нулю

Result:=True; //то возвращаем координату и выходим с положительный исходом, иначе функция возвращает false

p.X:=ix;

p.Y:=iy;

Exit;

end;

end;

Передача функции судоку координаты указывающей на место где необходимо заменить цифру и значение

function sudMod(s:TSudoku;p:TPoint;v:integer):TSudoku;//передаем функции судоку координату указывающую на место где нужно заменить цифру и значение

var

st:TSudoku;

begin

st:=s;

st[p.x,p.y]:=v;

Result:=st;

end;

Процедура добавления ответа

procedure sudAddAns(s:TSudoku); //добавление ответа

var

l:integer;

begin

l:=Length(ans); //удлинняем массив ответов на один и добавляем судоку из параметра

SetLength(ans,l+1);

ans[l]:=s;

end;

Рекурсия

function DoRec(s:TSudoku):boolean; //рекурсия

var

i:integer;

p:TPoint;

begin

Result:=True;

if IsNextUnknown(s,p) then begin // запуск рекурсий

for i:=1 to 9 do

if not sudInAny(s,p,i) then

if DoRec(sudMod(s,p,i)) then

Exit;

end else begin // сохранение результата

sudAddAns(s);

end;

if Length(ans)<mlen then // не хватает результатов

Result:=False;

end;

Процедура ввода значений в массив

procedure TForm1.ReadInSud; //ввод в массив

var

ix,iy:integer;

CEdit:TEdit;

begin

for iy:=1 to 9 do

for ix:=1 to 9 do begin

CEdit:=CEdits[ix,iy];

if CEdit.Text = '' then

Sud[ix,iy]:= 0

else

Sud[ix,iy]:=StrToInt(CEdit.Text);

end;

end;

Проверка судоку на правильность

function IsValidSudoku(s:TSudoku):boolean; //проверяем судоку на правильность, используем только для введенного пользователем

var

ix,iy:integer;

p:TPoint;

begin

for ix:=1 to 9 do

for iy:=1 to 9 do begin

p.X:=ix;

p.Y:=iy;

if s[ix,iy] <> 0 then

if sudInAny(s,p,s[ix,iy]) then begin

Result:=False;

Exit;

end;

end;

Result:=True;

end;

Автоматическое решение судоку

procedure TForm1.Button1Click(Sender: TObject);//решаем судоку автоматически

var

i:integer;

l:integer;

begin

ans:=nil;//обнуляем массив решений

ReadInSud; //читаем что ввел пользователь

if not IsValidSudoku(sud) then begin //если это не подходит(присутствует повтор) то сообщаем об этом и выходим

ShowMessage('Повторение в исходном');

Exit;

end;

if grpAns.ItemIndex = 0 then //задаем количество нужных решений, беря значение из grpAns и записывая в mlen

mlen:=1

else

mlen:=1000;

DoRec(sud); //вызываем рекурсивную функцию

l:=length(ans);

showmessage('Решений: '+IntToStr(l)); //сообщаем о количестве решений

cmbMode.Clear;

cmbMode.Items.Add('Исходное');

for i:=1 to l do

cmbMode.Items.Add('Решение '+IntToStr(i)); //добавляем варианты решений в список

cmbMode.ItemIndex:=0;

end;

procedure TForm1.sudFill(s:TSudoku); //вывод массива на поле

var

ix,iy,a:integer;

begin

for iy:=1 to 9 do

for ix:=1 to 9 do

CEdits[ix,iy].Text:=IntToStr(S[ix,iy]);

end;

Загрузка сохраненной игры

procedure TForm1.Button4Click(Sender: TObject);//загружаем игру

var ix,iy:integer;

save:TextFile;

masfile:string;

begin

assignfile(save,'save.txt');//чтение из файла

reset(save);

for iy := 1 to 9 do

begin

readln(save,masfile);

for ix:=1 to 9 do

if masfile[ix]='#' then CEdits[ix,iy].Text:='' else CEdits[ix,iy].Text:=masfile[ix];{загрузка цифр из файла, если # то он загружает пустую ячейку}

end;

closefile(save);

end;

Сохранение игры

procedure TForm1.Button3Click(Sender: TObject); //сохраняем игру

var

save: TextFile;

ix,iy: integer;

begin

AssignFile(save,'save.txt');//открываем файл для записи

Rewrite(save);

for iy:=1 to 9 do

for ix:=1 to 9 do

begin

if CEdits[ix,iy].Text='' then write(save,'#') // если значение ячейки пустое то записываем его в файл как #

else write(save,'',CEdits[ix,iy].Text);

if ix=9 then writeln(save);

end;

CloseFile(save);

showMessage('Игра сохранена!');//выводим сообщение

end;

Реализация функции «Новая игра»

procedure TForm1.Button9Click(Sender: TObject);

var ix,iy:integer;

begin

if newgame=0 then //переменная возвращающая значение уровня

begin

for iy := 1 to 9 do

for ix := 1 to 9 do

CEdits[ix,iy].Text:='';

end;

if newgame=1 then Button5.Click; //если уровень первый, то заново загружаем первый уровень

if newgame=2 then Button7.Click; //если уровень второй, то заново загружаем второй уровень

if newgame=3 then Button8.Click; //если уровень третий, то заново загружаем третий уровень

end;

Реализация функции очистки поля игры

procedure TForm1.Button11Click(Sender: TObject);

var ix,iy:integer;

begin

for iy:=1 to 9 do

for ix:=1 to 9 do

CEdits[ix,iy].Text:='';

newgame:=0;//обнуление уровня

end;

Реализация функции проверки решения

procedure TForm1.Button12Click(Sender: TObject);

begin

ReadInSud; //читаем что ввел пользователь

if not IsValidSudoku(sud) then begin //если это не подходит(присутствует повтор) то сообщаем об этом и выходим ShowMessage('Решено не верно(Повторение в исходном)');

Exit;

end else showmessage('Решено верно');

end;

После нажатия на кнопку «уровень» появляется форма выбора уровня (Рис.4).

Рис.4 Окно выбора уровня игры

После выбора уровня сложности появляется панель, изображенная на (Рис.5)

Рис.5 Окно игры