Игровая программа 'Судоку'
ФЕДЕРАЛЬНОЕ
АГЕНСТВО ПО ОБРАЗОВАНИЮ
Государственное
образовательное учреждение высшего профессионального образования Белгородский
государственный технологический университет им. В. Г. Шухова
Кафедра
программного обеспечения вычислительной техники и автоматизированных систем
Курсовой
проект по дисциплине
«Объектно-ориентированное
программирование»
Выполнил
Студент
группы ПВ-32
Артюх М.А.
Проверил
Ермоленко
Д.Н.
Белгород
2010г.
Введение
В данном курсовом проекте представлена актуальная на сегодняшний день
игра под названием судоку, реализованная в стиле объектно-ориентированного
программирования.
Что же это за игра и как в неё играть?
История судоку
Прообраз современного судоку, так называемые "магические
квадраты" знали еще в древнем Китае. В Европе вспоминается что-то подобное
в XVIII веке, когда слепой швейцарский математик Леонард Эйлер (Leonhard Euler)
выяснил, что в матрице размером 9х9 каждый ряд и каждую колонку можно заполнить
цифрами от 1 до 9 в определенном порядке и без повторения.
Впервые судоку в современном виде появилась в одном из американских
журналов кроссвордов в 1979 году. Автором головоломки был гражданин США, 74
летний архитектор на пенсии Howard Garns. Издатель - журнал „Math Puzzles and Logic Problems” дал пазлу имя „Number Place”. Настоящую популярность головоломка
завоевала в 2005, когда японский журнал Nikoli стал регулярно печатать ее на
своих страницах.
В 2004 Судоку начали печатать английские газеты, оттуда судоку-мания
нахлынула на Европу и в Австралию. Наконец, в 2005 эта головоломка триумфально
вернулась в США, завершив свой "кругосветный тур". В настоящее время
выдается множество специализированных журналов и сборников, книг и инструкций
по их решению, много газет печатают судоку вместе с кроссвордами и заданиями по
шахматам судоку - это невероятно увлекательная логическая игра. Не подумайте,
судоку это не новый кроссворд. Для того, чтобы играть в судоку не надо сидеть в
библиотеке и искать нужное слово в энциклопедии. В судоку вообще нет слов. В
судоку есть только цифры.
Судоку - это квадрат размером 9x9. Он разделен на 9 небольших квадратиков
3x3. В некоторых клетках в начале игры стоят числа от 1 до 9. Цель игры -
заполнить пустые клетки по специальному правилу. Это задача может быть и
простой и невозможно сложной, в зависимости от предложенного варианта. А
вариантов в судоку может быть много. Невообразимо много -
6,670,903,752,021,072,936,960!
В Судоку хорошо играть в транспорте по дороге на работу или домой. Для
судоку не нужен компьютер. В судоку можно играть, используя бумагу и ручку.
Поверьте, время в пути уменьшится в десятки раз!
Само слово «судоку» имеет японские корни. Как-то в пятидесятые годы
прошлого века в Японию попал американский журнал «Number Place», с опубликованными в нем необычными головоломками,
для решения которых требовалось всего лишь правильно расставить цифры по
позициям. Впоследствии благодаря данному словосочетанию, буквально
переведенному на японский язык («су» - число, цифра; «доку» - позиция, место),
возникло это новое сложное слово, которое много лет спустя, триумфально шествуя
по миру, добралось-таки до наших краев.
Правила игры
в судоку
Решение
судоку - процесс творческий, требующие способности к логическому мышлению и
определенных комбинаторных навыков. Со временем приходит опыт и каждый игрок
разрабатывает для себя собственную стратегию.
Правила игры судоку совершенно просты. Игровое поле судоку состоит из 81
клетки, находящихся в 9 столбцах, 9 строках и 9 малых квадратах. Это собственно
и есть магический квадрат судоку. В зависимости от уровня сложности некоторые
клетки уже содержат числа. Ваша задача - заполнить остальные клетки, используя
Ваши серые клеточки. Необходимо обратить внимание на следующее правило: В игре
участвую только числа с 1 до 9. Игровое поле (квадрат 9x9) должен быть заполнен
таким образом, что, каждое число (с 1 до 9) встречается в каждой строке, в
каждом столбце и в каждом малом квадрате (3x3) только один-единственный раз.
Цель головоломки - необходимо заполнить свободные ячейки цифрами от 1 до
9 так, чтобы в каждой строке, в каждом столбце и в каждом малом квадрате 3х3,
каждая цифра встречалась только один раз. Правильная головоломка имеет одно
решение.
В последнее время появились и другие - более сложные модификации, чем 9х9
ячеек кроссвордов. Существуют судоку с размерами 15х15 или даже 16х16,
предназначенные для опытных игроков. Для детей используются судоку меньших
размеров, например, 2х2.
Как начать играть?
Начните с единицы. "Осмотритесь" сначала на игровом поле, найдя
все клетки с цифрой 1. Проверьте каждый из малых квадратов (3x3), содержит ли
он уже единицу. Попытайтесь разыскать все клетки внутри этого малого квадрата,
в котором могла бы стоять единица. Не забывайте при этом о главном правиле:
каждое число может, стоят в каждой строке, в каждом столбце и каждом маленьком
квадрате только один раз. При этом нужно исключить все те клетки, в которых
единица не может находиться, потому что столбец или строка или квадрат уже
"заняты". Вполне вероятно, что в каком-либо из рассмотренных
квадратов останется как раз одна клетка, в которой может находиться единица.
Если Вы не уверены, что это число возможно только в этой клетке и нигде более,
лучше всего оставить этот квадрат и попробовать с другим. Что-нибудь подходящее
найдется непременно!
Проверьте, таким образом, все квадраты (3x3). Конечно, имеет смысл искать
только там, где единица уже не стоит! После того, как Вы пройдетесь по всем
квадратам с 1, повторите поиск с другим числом. Например, с двойкой. Потом с
тройкой и так далее. До тех пор, пока Вы не проверили все цифры от 1 до 9. Вы
увидите, что Вы заполнили уже очень много клеток. После чего, советуем
"провернуть" всю процедуру еще раз с начала - снова от 1 до 9. Вы
заметите, что дело идёт уже легче, потому что многие клетки Вы уже заполнили. И
вы заметите, что там, где Вы раньше сомневались, теперь Вы уверенно можете
ставить Ваше число.
Что представлено в курсовом проекте?
В курсовом проекте представлена игровая программа, способная составлять
судоку и решать его на любом этапе игрового процесса. Программа может сохранять
и загружать ранее сохраненную игру.
Также представлены все описания этапов анализа, разработки и отладки
программы.
Постановка задачи
Разработать и программно реализовать игру «Судоку» в объектно-ориентированном
стиле. В программе должны соблюдаться принципы информационной закрытости,
модульности и иерархической организации.
Игра должна иметь:
1. Алгоритм
решения произвольного игрового поля и уже заданной игры судоку.
2. Алгоритм
генерации случайного игрового поля судоку.
3. Windows-приложение для вывода игрового поля
на экран.
4. Возможность сохранения текущей игры и загрузки ранее сохраненной
игры.
Анализ предметной области
Объектная декомпозиция:
Разработка диаграммы классов
Данные классы находятся в следующих отношениях:
1. Ассоциация. Мощность: «один ко многим»
2. Наследование. Класс TGameSudoku наследует класс TSudoky.
. Агрегация. Класс Matrix
находится в отношении агрегации с классом TSudoky.
. Зависимость. Класс Matrix находится в отношении зависимости с классом TSudoky.
Описание программной реализации
Программа была реализована в среде разработки Delphi 2010 (VCL Form Application), включает в себя тир модуля: WorkWithMatrix, Sudoky, GameSudoky.
В Модуле WorkWithMatrix
реализован класс Matrix, который
имеет описание всех структур данных, необходимых для реализации программы, и
описание методов работы с этими структурами.
unit WorkWithMatrix;
Matrix=classn=9;
t_mas= array [1..n] of byte;_matr=array [1..n] of t_mas; // собственно само судоку_set=set of 1..n; // множество
t_mas_set=array [1..n] of t_set; //массив множеств для проверки на
повторы
t_mas_boolen=array [1..matrix.n] of boolean; //массив флагов_matr_boolean=array
[1..matrix.n] of t_mas_boolen; //матрица
флагов
Sdvig(var s:t_matr; i:Byte); //сдвиг 3 строк на 1 шаг вправоsdvig2(var s:t_matr;i:byte); //сдвиг одной строки
на 1 шаг вправоZeroBoolMatr(var
b:T_matr_boolean); //обнуление булевой
матрицыIfMatrHavNull(s:T_matr):boolean;//проверяет имеет ли матрица хотябы
один ноль
end;
В классе Matrix описаны
типы:
1. целочисленный массив из n элементов(t_mas);
2. целочисленная матрица размером NxN(t_matr);
. множество, которое может включать в себя элементы от 1 до n (t_set);
. массив множеств из n множеств(t_mas_set);
. массив типа Boolean
из n элементов (t_mas_boolen);
. матрица из элементов типа Boolean размером NxN(t_matr_boolean).
В классе Matrix описана
константа (const n=9), которая обозначает размер судоку.
В классе Matrix описаны
методы:
1. сдвиг 3-х строк в матрице s с позиции i на один шаг
вправо(Sdvig);
2. сдвиг строки i в
матрице s на один шаг вправо(Sdvig2);
. обнуление матрицы, элементы которой типа Boolean(ZeroBoolMatr);
. возвращает true если
в матрице s есть хотябы один ноль, иначе false;
Класс Мatrix отображает в себе те действия над
структурами, которые не имеют посредственного отношения к предметной области
задачи, но используются при реализации других классов.
В модуле Sudoky реализован
класс TSudoky. В этом классе реализованы поля и
медоды для работы с судоку, как с математической моделью.
windows,Classes,WorkWithMatrix;
TSudoky=class:Matrix.t_matr;:Matrix.t_matr;:array of
Matrix.t_matr; //массив ответов
из судоку
Mlen:integer;// количество решений в массиве Ans
Matr:matrix;
create();done();SudAddAns( s:matrix.t_matr);//добавляем судоку
в массив
ответовSudMod(var
s:matrix.t_matr;var p:Tpoint;v:integer):Matrix.t_matr;// замена в судоку s одного значения v на позиции PIsNextUnknown(
s:matrix.t_matr; var p:Tpoint):boolean; //находим
в судоку
пустую ячейку
и возвращаем позицию P,иначе False;SudInLine(s:matrix.t_matr;var
p:Tpoint;v:integer):boolean;//проверка по строкеSudInRow(
s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка по столбцуSudInSq( s:matrix.t_matr;var
p:Tpoint;v:integer):boolean; //проверка в квадратеSudInAny(
s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //общая проверка на постановку числаDoRec( S:Matrix.t_matr):boolean;//рекурсивное построение судоку
function SudOK(s:Matrix.t_matr):boolean;// проверка на правильность
построенного судокуgenerate(var s:matrix.t_matr); // генерирование судоку
быстрым методом c возможным повторением
procedure generate_matr(var s:matrix.t_matr);//генерирует матрицу
без повторенийRandom_generate( var s,b:matrix.t_matr); // генерация игрового судокуSetValInSud(var
s:matrix.t_matr;i,j:byte; v:byte); //установка значения
end;
В классе TSudoky описаны
поля:
1. Сгенерированное судоку(Sud);
2. Игровое судоку (GameSud);
. Массив ответов из судоку(Ans);
. Количество решений в массиве ответов из судоку(Mlen);
. Переменная для использования методов из класса Matrix(Matr);
В классе TSudoky описаны
методы:
1. инициализация полей класса(create);
2. удаление значений полей класса(done);
. добавляем судоку s в
массив Ans ответов(SudAddAns);
. замена в судоку s
одного значения v на позиции P (SudMod);
. возвращает true,
если в судоку s есть пустая ячейка, возвращение
позиции P,иначе False(IsNextUnknown);
. возвращает true,
если в судоку s строка имеет правильное построение,
иначе fase(SudInLine);
. возвращает true,
если в судоку s столбец имеет правильное построение,
иначе fase(SudInRow);
. возвращает true,
если в судоку s квадрат имеет правильное построение,
иначе fase(SudInSq);
. возвращает true,
если в судоку s квадрат, столбец и строка имеет
правильное построение, иначе fase(SudInAny);
. возвращает true,
если рекурсивное построение судоку закончено верно, массив ответов Ans пополнен, иначе false(DoRec);
. возвращает true,
если судоку построено верно, иначе false(SudOK);
. генерирование судоку быстрым методом c возможным
повторением(generate);
. генерирование судоку без повторений(generate_matr);
. установка в судоку s значения v на позицию [i,j]( SetValInSud);
В модуле GameSud реализован
класс TGameSud. В этом классе реализованы поля и
медоды для работы с судоку как с игрой.
unit GameSud;
Sudoky,WorkWithMatrix;
TGameSudoky=class(Tsudoky):string; //адресс куда будет сохранена игра
Viz: matrix.t_matr_boolean; // матрица флагов видимости числел на игровом
поле:matrix.t_matr_boolean; //матрица флагов введенных пользователем
значений:matrix. t_matr_boolean;//матрица флагов выделенных пользователем
клеток
publicCreate;Done;Save(s:matrix.t_matr); //сохранение игрыLoad(var s:matrix.t_matr;var u:matrix.t_matr_boolean); //загрузка игрыSudVizibleOnField(s:matrix.t_matr;var
b:matrix.t_matr_boolean);//заполняет матрицу флагов видимости в соответствии с матрицой SSudVizible(V:matrix.t_matr_boolean;i,j:byte):boolean;//Должно ли число отображаться на экранNulling(var
b:matrix.t_matr_boolean); //обнуление матрицы флагов введенных пользователем значенийSudIsFulling(s:matrix.t_matr):boolean;
// заполнена ли судоку до конца;
В классе TGameSudoky
описаны поля:
1. адрес, куда будет сохранена игра(Adres);
2. матрица флагов видимости чисел на игровом поле(Viz);
. матрица флагов введенных пользователем значений(User);
. матрица флагов выделенных пользователем клеток(UsersPointer);
В классе TGameSudoky
описаны методы:
1. сохранение судоку s и
матрицы флагов введенных пользователем значений User в текстовый файл по адресу Adres(Save);
2. загрузка судоку s и
матрицы флагов введенных пользователем значений User из текстового файла по адресу Adres(Save);
. заполняет матрицу флагов видимости User в соответствии с матрицей S (SudVizibleOnField);
. обнуление матрицы флагов введенных пользователем User значений (Nulling);
. возвращает true,
если судоку s заполнена до конца (SudIsFulling);
. возвращает true,
если число v должно отображаться на экран (SudVizible);
головоломка
судоку алгоритм модульность
Текст программы
unit Game;
, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,, StdCtrls, ExtCtrls,GameSud,WorkWithMatrix,Sudoky, Menus, ExtDlgs;
T=51;=25;= class(TForm): TImage;: TPanel;: TComboBox;:
TButton;: TButton;: TButton;: TButton;: TMainMenu;: TMenuItem;: TMenuItem;:
TMenuItem;: TMenuItem;: TSaveDialog;: TOpenDialog;FormCreate(Sender:
TObject);Image1MouseUp(Sender: TObject; Button: TMouseButton;: TShiftState; X,
Y: Integer);Button2Click(Sender: TObject);Button1Click(Sender:
TObject);Button3Click(Sender: TObject);Button4Click(Sender:
TObject);N4Click(Sender: TObject);N2Click(Sender: TObject);N3Click(Sender:
TObject); // возвращает позицию в матрице после нажптия мыши
{ Private declarations }
{ Public declarations };
: TForm2;:TGameSudoky;,j:Byte; //Координаты текущего эдемента в
матрице
implementation
{$R *.dfm}CreateFild(var cl:TColor);,J,k1,k2: Integer;:=0;
k2:=0;I := 1 to matrix.n do:=0;j := 1 to matrix.n
do.Image1.Canvas.Brush.Color:=cl;//clSkyBlue;.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);:=k1+T;j
mod 3=0 then k1:=k1+5;;:=k2+T;i mod 3=0 then k2:=k2+5;;;
WriteSud;k1,k2:integer;:Tcolor;:= clSkyBlue;(cl);:=0; k2:=0;I
:= 1 to matrix.n do:=0;j := 1 to matrix.n dos.GameSud[i,j]<>0
then.Image1.Canvas.Font.Style:=[fsBold];.Image1.Canvas.Font.Size:=12;.Image1.Canvas.Font.Color:=clBlue;.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));s.User[i,j]=true
then.Image1.Canvas.Font.Style:=[fsBold];.Image1.Canvas.Font.Size:=12;.Image1.Canvas.Font.Color:=clRed;.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));;;:=k1+T;j
mod 3 =0 then k1:=k1+5;;:=k2+T;i mod 3 =0 then k2:=k2+2;;;
TForm2.Button1Click(Sender:
TObject);z:byte;:=form2.ComboBox1.ItemIndex;z<>255
then.SetValInSud(s.GameSud,i,j,z);.DoRec(s.GameSud);.User[i,j]:=true;.UsersPointer[i,j]:=not
(s.UsersPointer[i,j]);z:=0;;;
TForm2.Button2Click(Sender:
TObject);cl:Tcolor;.Nulling(s.User);.Random_generate(s.Sud,s.GameSud);.SudVizibleOnField(s.GameSud,s.Viz);:=
clSkyBlue;(cl);;;
TForm2.Button3Click(Sender:
TObject);l:integer;:boolean;:=s.IsValidSudoky(s.GameSud);.Ans:=nil;.Mlen:=100;.DoRec(s.GameSud);:=
length(s.Ans);f=True thenl<>0 then('Вы на верном пути!! ;)'+'Возможных решений:'+inttostr(l))
else showmessage('Вы ошиблись!!!');showmessage('Вы
ошиблись!!!');
;
TForm2.Button4Click(Sender:
TObject);f:boolean;:=s.SudIsFulling(s.GameSud); f=false then showmessage('Поле не заполнено до конца!!!')
elses.SudOK(s.GameSud)=false then
Showmessage('Верно')Showmessage('Неверно');;
;
TForm2.FormCreate(Sender:
TObject);cl:TColor;:=TGameSudoky.Create;.Random_generate(s.Sud,s.GameSud);.Ans:=nil;.Mlen:=100;.DoRec(s.GameSud);.SudVizibleOnField(s.GameSud,s.Viz);:=
clSkyBlue;(cl);;
;
PaintRec( cl:Tcolor);k1,k2,i2,j2:integer;:=0; k2:=0;I2 := 1
to matrix.n do:=0;j2 := 1 to matrix.n do(i=i2)and(j=j2)and(s.Viz[i,j]=false)
then.UsersPointer[i,j]:=not (s.UsersPointer[i,j]);s.UsersPointer[i,j]=true
then:= clSkyBlue;.Image1.Canvas.Brush.Color:=cl;.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);.Image1.Canvas.Brush.Color:=cl;.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);;(s.User[i,j]=true)
then.Image1.Canvas.Font.Style:=[fsBold];.Image1.Canvas.Font.Size:=12;.Image1.Canvas.Font.Color:=clRed;.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));;;:=k1+T;j2
mod 3=0 then k1:=k1+5;;:=k2+T;i2 mod 3=0 then k2:=k2+5;;;
TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton;:
TShiftState; X, Y: Integer);x1,y1,x2,y2,k1,k2,i2,j2:integer;:Tcolor;:=0;x2:=T-1;j:=1;i:=1;
y1:=0;y2:=t;(j<=matrix.n)and not((x1<x)and(x<x2))
do:=x1+T;:=x2+T;:=j+1;j mod 3=0 then:=x1+5;:=x2+5;;;(i<=matrix.n)and
not((y1<y)and(y<y2)) do:=y1+T;:=y2+T;:=i+1;i mod 3=0 then:=y1+5;:=y2+5;;;
;
TForm2.N2Click(Sender: TObject);form2.SaveDialog1.Execute()
then.Adres:=form2.SaveDialog1.FileName;.Save(s.GameSud);;
;
TForm2.N3Click(Sender:
TObject);cl:TColor;form2.OpenDialog1.Execute
thenform2.OpenDialog1.FileName<>'' then.Adres:= form2.OpenDialog1.FileName;.Load(s.GameSud,s.User);:=
clSkyBlue;(cl);;;;;
TForm2.N4Click(Sender: TObject);.Close;;
.
Sudoky;
windows,Classes,WorkWithMatrix;
TSudoky=class:Matrix.t_matr;:Matrix.t_matr;:array of
Matrix.t_matr; //массив ответов
из судоку
Mlen:integer;// количество решений в массиве Ans
Matr:matrix;
create();done();SudAddAns( s:matrix.t_matr);//добавляем судоку
в массив
ответовSudMod(var
s:matrix.t_matr;var p:Tpoint;v:integer):Matrix.t_matr;// замена в судоку s одного значения v на позиции PIsNextUnknown(
s:matrix.t_matr; var p:Tpoint):boolean; //нахотим
в судоку
пустую ячейку
и возвращаем позицию P,иначе False;SudInLine(s:matrix.t_matr;var
p:Tpoint;v:integer):boolean;//проверка по строкеSudInRow(
s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка по столбцуSudInSq( s:matrix.t_matr;var
p:Tpoint;v:integer):boolean; //проверка в квадратеSudInAny(
s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //общая проверка на постановку числаDoRec( S:Matrix.t_matr):boolean;//рекурсивное построение судоку
function SudOK(s:Matrix.t_matr):boolean;// проверка на правильность
построенного судокуgenerate(var s:matrix.t_matr); // генерирование судоку
быстрым методом c возможным повторением
procedure generate_matr(var s:matrix.t_matr);//генерирует матрицу
без повторенийRandom_generate( var s,b:matrix.t_matr); // генерация игрового судокуSetValInSud(var
s:matrix.t_matr;i,j:byte; v:byte); //установка значенияIsValidSudoky(s:matrix.t_matr):boolean;
//проверка судоку
на правильность;
TSudoky.SetValInSud(var s: Matrix.t_matr; i: Byte; j: Byte;
v: Byte);[i,j]:=v;;TSudoky.sudInLine;:1..9;:=True;i:=1 to 9 dop.y<>i
thens[p.X,i]=v then Exit;:=False;;
TSudoky.sudInRow;:1..9;:=True;i:=1 to 9 dop.x<>i
thens[i,p.Y]=v then Exit;:=False;;
TSudoky.sudInSq;,iy:0..8;,ly:0..8;:=0; ly:=0;p.x in [1,2,3]
then lx:=1;p.x in [4,5,6] then lx:=4;p.x in [7,8,9] then lx:=7;:=lx-1;p.y in
[1,2,3] then ly:=1;p.y in [4,5,6] then ly:=4;p.y in [7,8,9] then
ly:=7;:=ly-1;:=True;ix:=1 to 3 doiy:=1 to 3 do(p.x<>lx+ix) and
(p.y<>ly+iy) thens[lx+ix,ly+iy]=v then
Exit;:=False;;TSudoky.sudInAny;:=sudInLine(s,p,v) or sudInRow(s,p,v) or
sudInSq(s,p,v);;
TSudoky.IsNextUnknown;,iy:1..9;:=False;ix:=1 to 9 doiy:=1 to
9 dos[ix,iy]=0 then begin:=True;.X:=ix;.Y:=iy;;; // if;
TSudoky.sudMod;:Matrix.t_matr;:=s;[p.x,p.y]:=v;:=st;;
TSudoky.sudAddAns;:integer;:=Length(ans);(ans,l+1);[l]:=s;;
TSudoky.DoRec;:integer;:TPoint;:=True;IsNextUnknown(s,p) then
begin // запуск рекурсийi:=1 to 9 donot sudInAny(s,p,i) thenDoRec(sudMod(s,p,i)) then
Exit;else begin // сохранение результата
sudAddAns(s);;Length(ans)<mlen then // не хватает результатов:=False;; // DoRec
Tsudoky.IsValidSudoky(s:matrix.t_matr):boolean;,iy:integer;:TPoint;ix:=1
to 9 doiy:=1 to 9 do begin.X:=ix;.Y:=iy;s[ix,iy] <> 0 thensudInAny(s,p,s[ix,iy])
then begin:=False;;; // if; // for:=True;;
Tsudoky.Create;i,j:integer;I := 1 to matrix.n doj := 1 to
matrix.n do sud[i,j]:=0;;
Tsudoky.Done;i,j:integer;I := 1 to matrix.n doj := 1 to
matrix.n do sud[i,j]:=0;;
Tsudoky.SudOK(s: matrix.t_matr):boolean;i,j,z1,z2,t:integer;:boolean;
:=false;:=1;:=1;(j<=matrix.n)and(flag = false)
do:=1;(i<=matrix.n)and(flag = false)
do:=i+1;:=j+1;:=s[i,j];(z1<=matrix.n)and(flag=false) dot=s[z1,j] then
flag:=true;:=z1+1;;(z2<=matrix.n)and(flag=false) dot=s[i,z2] then
flag:=true;:=z2+1;;:=i+1;;:=j+1;;:=flag;;tsudoky.generate(var s:
matrix.t_matr);i,j,k,z:byte;:matrix.t_set;:matrix.t_mas_set;:boolean;:matrix.t_matr;;:=[];:=1;
i:=1;j<=matrix.n do begin:=random (matrix.n)+1;not(k in m) then
begin[i,j]:=k;:=m+[k];[j]:=t[j]+[k];:=j+1;;;
i:=2 to 3 do matr.Sdvig(s,i);i:=2 to 3 doj:=1 to matrix.n do
t[j]:=t[j]+[s[i,j]];
:=4;.sdvig(s,i);
j:=1 to matrix.n do(s[i,j] in t[j]) then.sdvig2(s,i);;;
i:=5 to 6 do matr.sdvig(s,i);i:=5 to 6 doj:=1 to matrix.n do
t[j]:=t[j]+[s[i,j]];:=7;.sdvig(s,i);j:=1 to matrix.n do(s[i,j] in t[j])
then.sdvig2(s,i);;;i:=8 to 9 do matr.sdvig(s,i);;
tsudoky.generate_matr(var s:
matrix.t_matr);flag:boolean;(s);:=SudOK(s);;(flag=false);;tsudoky.Random_generate(
var s,b: matrix.t_matr);i,j,k:integer;:boolean;
//s:t_matr;;_matr(s);I := 1 to matrix.n doj := 1 to matrix.n
do:=random(2)+1;k=1 then[i,j]:=s[i,j];b[i,j]:=0;;;
.
GameSud;
Sudoky,WorkWithMatrix;
TGameSudoky=class(Tsudoky):string; //адресс
куда будет сохранена игра: matrix.t_matr_boolean; // матрица флагов видимости
числел на игровом поле:matrix.t_matr_boolean; //матрица флагов введенных
пользователем значений:matrix. t_matr_boolean;//матрица флагов выделенных
пользователем клеток
publicCreate;Done;Save(s:matrix.t_matr); //сохранение игрыLoad(var s:matrix.t_matr;var u:matrix.t_matr_boolean); //загрузка игрыSudVizibleOnField(s:matrix.t_matr;var
b:matrix.t_matr_boolean);//заполняет матрицу флагов видимости в соответствии с матрицой
SSudVizible(V:matrix.t_matr_boolean;i,j:byte):boolean;//Должно ли число отображаться на экранNulling(var
b:matrix.t_matr_boolean); //обнуление матрицы флагов введенных пользователем значенийSudIsFulling(s:matrix.t_matr):boolean;
// заполнена ли судоку до конца;
TGameSudoky.Create;i,j:byte;create;I := 1 to matrix.n doj :=
1 to matrix.n do[i,j]:=false;;
TGameSudoky.SudIsFulling(s:
Matrix.t_matr):boolean;matr:matrix;:= matr.IfMatrHavNull(s);;
Tgamesudoky.Nulling(var b:
Matrix.t_matr_boolean);Matr:matrix;.ZeroBoolMatr(b);;
TGameSudoky.Done;i,j:byte;Done;:='';I := 1 to matrix.n doj :=
1 to matrix.n do[i,j]:=false;;
TGameSudoky.SudVizibleOnField(s: matrix.t_matr; var b:
matrix.t_matr_boolean);i,j:byte;I := 1 to matrix.n doj := 1 to matrix.n
dos[i,j]=0 then b[i,j]:=falseb[i,j]:=true;;;
TGameSudoky.SudVizible;:= (v[i,j]=true);;
TGameSudoky.Save(s:
matrix.t_matr);f:text;,j:byte;(f,adres);(f);I := 1 to matrix.n doj := 1 to
matrix.n do(f,s[i,j]);
I := 1 to matrix.n doj := 1 to matrix.n douser[i,j]=true then
write(f,1) else write(f,0);(f);
;
TGameSudoky.Load;f:text;,j:byte;:char;(f,adres);(f);
I := 1 to matrix.n doj := 1 to matrix.n
do(f,c);[i,j]:=ord(c)-ord('0');;
I := 1 to matrix.n doj := 1 to matrix.n
do(f,c);(ord(c)-ord('0'))=1 then u[i,j]:=true else u[i,j]:=false;;
(f);;
.
WorkWithMatrix;
Matrix=classn=9;
t_mas= array [1..n] of byte;_matr=array [1..n] of t_mas; // собственно само судоку_set=set of 1..n; // множество
t_mas_set=array [1..n] of t_set; //массив множеств для проверки на
повторы
t_mas_boolen=array [1..matrix.n] of boolean; //массив флагов_matr_boolean=array
[1..matrix.n] of t_mas_boolen; //матрица
флагов
Sdvig(var s:t_matr; i:Byte); //сдвиг 3 строк на 1 шагsdvig2(var
s:t_matr;i:byte); //сдвиг одной строки на 1 шагZeroBoolMatr(var b:T_matr_boolean);
//обнуление булевой
матрицыIfMatrHavNull(s:T_matr):boolean;//проверяет имеет ли матрица хотябы
один ноль
;
matrix.IfMatrHavNull(s:
Matrix.t_matr):boolean;i,j:byte;:boolean;:=true;i:=1;j:=1;(i<=n)and(f=true)
do:=1;(j<=n)and(f=true) dos[i,j]=0 then f:=false;:=j+1;;:=i+1;;:=f;;
Matrix.ZeroBoolMatr(var b: Matrix.t_matr_boolean);i,j:byte;I
:= 1 to n doj := 1 to n
do[i,j]:=false;;Matrix.Sdvig;b:T_matr;[i,1]:=s[i-1,4];[i,2]:=s[i-1,5];[i,3]:=s[i-1,6];
[i,1]:=s[i-1,7];[i,2]:=s[i-1,8];[i,3]:=s[i-1,9];[i,4]:=s[i-1,1];[i,5]:=s[i-1,2];[i,6]:=s[i-1,3];
[i,7]:=b[i,1];[i,8]:=b[i,2];[i,9]:=b[i,3];;
Matrix.sdvig2(var s: t_matr; i: Byte);j,z:byte;:=s[i,1];j:=2
to n do[i,j-1]:=s[i,j];;[i,n]:=z;;.
Project1;
{$APPTYPE CONSOLE}
,in 'Sudoky.pas',in 'GameSud.pas',in
'WorkWithMatrix.pas';WriteSud(var s:matrix.t_matr);i,j:byte;i := 1 to matrix.n
do;j := 1 to matrix.n do(' ');(s[i,j]);;;;
WriteMatrBool(var v:t_matr_boolean);i,j:byte;i := 1 to
matrix.n do;;j := 1 to matrix.n do(' ');(v[i,j]);;;;
S:Tsudoky;:TGameSudoky;:matrix.t_matr;,j,l:integer;:boolean;
('Generate
sudoky:');.Random_generate(s1.Sud,s1.GameSud);(s1.Sud);;;
('Generate game sudoky:');(s1.GameSud);;;
.DoRec(s1.GameSud);:=length(s1.Ans);('Count of ansver:','
',l);;;
('Save in file');.Save(s1.GameSud);;;('Load from
file');.Load(b);(b);;;
('Matrix of
vizible:');.SudVizibleOnField(s1.GameSud,s1.Viz);(s1.Viz);
;;
end.
Как пользоваться приложением
Программа для игры в судоку имеет графический интерфейс.
В приложении реализована возможность ввода значения и его удаление. Для
этого нужно выделить нужный квадрат (он отметится другим цветом), выбрать из
списка значений нужное число и нажать кнопку «Ввод значения». После нажатия
выбранное значение установится на выделенной клетке и будет красного цвета.
Также в программе имеется возможность проверки на любом этапе игрового
процесса. Для этого имеется две кнопки: «Подсказка» и «Полная проверка». Кнопка
«Подсказка» выводит на экран сообщение, которое содержит информацию: игрок
правильно установил значение и количество возможных решений при заданном
значении, или значение установлено неверно. Кнопка «Полная проверка» проверяет
на правильность полностью заполненное поле. Если поле заполнено полностью, то
появляется сообщение: выиграл пользователь или допустил ошибку. Если поле
заполнено не до конца, то появляется сообщение «Поле не заполнено до конца!!!».
В реализации имеется также возможность сохранять текущую игру и загружать
ранее сохраненную игру. Соответствующие кнопки для данных действий можно найти
в меню: Файл ->Сохранить или Файл ->Загрузить.
В курсовом проекте был представлен принцип модульности: каждый класс
описан в отдельном модуле. Это дает возможность использовать реализованные
классы в других приложениях.
Также в курсовом проекте была реализована тестовая программа для
визуальной проверки правильности описанных в классах алгоритмов. Тестовая
программа использует те же модули, что и основная программа.
Заключение
В ходе выполнения курсовой работы были полностью реализованы поставленные
цели и задачи, а именно:
1. Анализ предметной области задачи
2. Построение диаграммы объектов и диаграммы классов
. Реализация программы в объектно-ориентированном стиле по принципам
модульности, иерархичности, ограничения доступа.
Игра имеет:
1. Алгоритм решения произвольного игрового поля и уже заданной игры
судоку.
2. Алгоритм генерации случайного игрового поля судоку.
3. Windows-приложение для вывода игрового поля на экран.
. Возможность сохранения текущей игры и загрузки ранее сохраненной
игры.
Список использованных источников
1. Лекции
по дисциплине «Объектно-ориентированное программирование»
2. А.В.
Серов - «Технологии Delphi»
. С.А.
Немнюгин -«Turbo Pascal»