
- •Глава 1. Проектирование программы
- •1.1 Разработка внутренних структур данных и определение пользовательского интерфейса программного приложения
- •1.2 Выбор технологии, языка и среды программирования
- •1.3 Проектирование структуры программы и взаимодействия модулей
- •Глава 2. Описание и функциональные возможности программы
- •2.1 Особенности построения и работы алгоритма
- •Глава 3. Тестирование
- •3.1 Выбор стратегии тестирования и разработка тестов
- •5. Требования к программной документации
- •6. Технико-экономические показатели
- •7. Стадии и этапы разработки
- •8. Порядок контроля и приемки
Глава 2. Описание и функциональные возможности программы
2.1 Особенности построения и работы алгоритма
В разрабатываемом программном приложении мы использовали:
Класс TForm — это важнейший компонент Delphi, на котором основана вся работа этой системы по проектированию и разработке приложений. Форма (Класс TForm) содержит обширный набор свойств, методов и событий, позволяющих легко настраивать и организовывать самые сложные алгоритмы ее функционирования. Все свойства описаны в инспекторе объектов.
TGroupBox – группа элементов. Этот компонент используется для группировки нескольких связанных по смыслу компонентов.
TCheckBox - независимый переключатель. Щелчок мышью на этом компоненте в работающей программе изменяет его логическое свойство Checked.
TComboBox – комбинированный список. Комбинированный, или раскрывающийся, список TComboBox представляет собой комбинацию списка TListBox и текстового поля TEdit, и поэтому большая часть его свойств и методов заимствованы у этих компонентов.
TRadioGroup - группа зависимых переключателей. Содержит специальные свойства для обслуживания нескольких связанных зависимых переключателей.
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 Окно игры