Игровая программа "Судоку"

История судоку, правила игры и цель головоломки. Разработка диаграммы классов. Реализация программы в объектно-ориентированном стиле по принципам модульности, иерархичности, ограничения доступа. Алгоритм генерации случайного игрового поля судоку.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 01.02.2013
Размер файла 315,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

ФЕДЕРАЛЬНОЕ АГЕНСТВО ПО ОБРАЗОВАНИЮ

Государственное образовательное учреждение высшего профессионального образования Белгородский государственный технологический университет им. В. Г. Шухова

Кафедра программного обеспечения вычислительной техники и автоматизированных систем

Курсовой проект по дисциплине

«Объектно-ориентированное программирование»

Выполнил

Студент группы ПВ-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. Возможность сохранения текущей игры и загрузки ранее сохраненной игры.

Анализ предметной области

Объектная декомпозиция:

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Разработка диаграммы классов

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Данные классы находятся в следующих отношениях:

1. Ассоциация. Мощность: «один ко многим»

2. Наследование. Класс TGameSudoku наследует класс TSudoky.

3. Агрегация. Класс Matrix находится в отношении агрегации с классом TSudoky.

4. Зависимость. Класс Matrix находится в отношении зависимости с классом TSudoky.

Описание программной реализации

Программа была реализована в среде разработки Delphi 2010 (VCL Form Application), включает в себя тир модуля: WorkWithMatrix, Sudoky, GameSudoky.

В Модуле WorkWithMatrix реализован класс Matrix, который имеет описание всех структур данных, необходимых для реализации программы, и описание методов работы с этими структурами.

unit WorkWithMatrix;

interface

type Matrix=class

public

const n=9;

type t_mas= array [1..n] of byte;

t_matr=array [1..n] of t_mas; // собственно само судоку

t_set=set of 1..n; // множество

t_mas_set=array [1..n] of t_set; //массив множеств для проверки на повторы

t_mas_boolen=array [1..matrix.n] of boolean; //массив флагов

t_matr_boolean=array [1..matrix.n] of t_mas_boolen; //матрица флагов

public

procedure Sdvig(var s:t_matr; i:Byte); //сдвиг 3 строк на 1 шаг вправо

procedure sdvig2(var s:t_matr;i:byte); //сдвиг одной строки на 1 шаг вправо

procedure ZeroBoolMatr(var b:T_matr_boolean); //обнуление булевой матрицы

function IfMatrHavNull(s:T_matr):boolean;//проверяет имеет ли матрица хотябы один ноль

end;

В классе Matrix описаны типы:

1. целочисленный массив из n элементов(t_mas);

2. целочисленная матрица размером NxN(t_matr);

3. множество, которое может включать в себя элементы от 1 до n (t_set);

4. массив множеств из n множеств(t_mas_set);

5. массив типа Boolean из n элементов (t_mas_boolen);

6. матрица из элементов типа Boolean размером NxN(t_matr_boolean).

В классе Matrix описана константа (const n=9), которая обозначает размер судоку.

В классе Matrix описаны методы:

1. сдвиг 3-х строк в матрице s с позиции i на один шаг вправо(Sdvig);

2. сдвиг строки i в матрице s на один шаг вправо(Sdvig2);

3. обнуление матрицы, элементы которой типа Boolean(ZeroBoolMatr);

4. возвращает true если в матрице s есть хотябы один ноль, иначе false;

Класс Мatrix отображает в себе те действия над структурами, которые не имеют посредственного отношения к предметной области задачи, но используются при реализации других классов.

В модуле Sudoky реализован класс TSudoky. В этом классе реализованы поля и медоды для работы с судоку, как с математической моделью.

unit Sudoky;

interface

Uses windows,Classes,WorkWithMatrix;

type TSudoky=class

Sud:Matrix.t_matr;

GameSud:Matrix.t_matr;

Ans:array of Matrix.t_matr; //массив ответов из судоку

Mlen:integer;// количество решений в массиве Ans

Matr:matrix;

Public

constructor create();

destructor done();

procedure SudAddAns( s:matrix.t_matr);//добавляем судоку в массив ответов

function SudMod(var s:matrix.t_matr;var p:Tpoint;v:integer):Matrix.t_matr;// замена в судоку s одного значения v на позиции P

function IsNextUnknown( s:matrix.t_matr; var p:Tpoint):boolean; //находим в судоку пустую ячейку и возвращаем позицию P,иначе False;

function SudInLine(s:matrix.t_matr;var p:Tpoint;v:integer):boolean;//проверка по строке

function SudInRow( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка по столбцу

function SudInSq( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка в квадрате

function SudInAny( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //общая проверка на постановку числа

function DoRec( S:Matrix.t_matr):boolean;//рекурсивное построение судоку

function SudOK(s:Matrix.t_matr):boolean;// проверка на правильность построенного судоку

procedure generate(var s:matrix.t_matr); // генерирование судоку быстрым методом c возможным повторением

procedure generate_matr(var s:matrix.t_matr);//генерирует матрицу без повторений

procedure Random_generate( var s,b:matrix.t_matr); // генерация игрового судоку

procedure SetValInSud(var s:matrix.t_matr;i,j:byte; v:byte); //установка значения

end;

В классе TSudoky описаны поля:

1. Сгенерированное судоку(Sud);

2. Игровое судоку (GameSud);

3. Массив ответов из судоку(Ans);

4. Количество решений в массиве ответов из судоку(Mlen);

5. Переменная для использования методов из класса Matrix(Matr);

В классе TSudoky описаны методы:

1. инициализация полей класса(create);

2. удаление значений полей класса(done);

3. добавляем судоку s в массив Ans ответов(SudAddAns);

4. замена в судоку s одного значения v на позиции P (SudMod);

5. возвращает true, если в судоку s есть пустая ячейка, возвращение позиции P,иначе False(IsNextUnknown);

6. возвращает true, если в судоку s строка имеет правильное построение, иначе fase(SudInLine);

7. возвращает true, если в судоку s столбец имеет правильное построение, иначе fase(SudInRow);

8. возвращает true, если в судоку s квадрат имеет правильное построение, иначе fase(SudInSq);

9. возвращает true, если в судоку s квадрат, столбец и строка имеет правильное построение, иначе fase(SudInAny);

10. возвращает true, если рекурсивное построение судоку закончено верно, массив ответов Ans пополнен, иначе false(DoRec);

11. возвращает true, если судоку построено верно, иначе false(SudOK);

12. генерирование судоку быстрым методом c возможным повторением(generate);

13. генерирование судоку без повторений(generate_matr);

14. установка в судоку s значения v на позицию [i,j]( SetValInSud);

В модуле GameSud реализован класс TGameSud. В этом классе реализованы поля и медоды для работы с судоку как с игрой.

unit GameSud;

interface

Uses Sudoky,WorkWithMatrix;

type TGameSudoky=class(Tsudoky)

Adres:string; //адресс куда будет сохранена игра

Viz: matrix.t_matr_boolean; // матрица флагов видимости числел на игровом поле

User:matrix.t_matr_boolean; //матрица флагов введенных пользователем значений

UsersPointer:matrix. t_matr_boolean;//матрица флагов выделенных пользователем клеток

public

constructor Create;

destructor Done;

procedure Save(s:matrix.t_matr); //сохранение игры

procedure Load(var s:matrix.t_matr;var u:matrix.t_matr_boolean); //загрузка игры

procedure SudVizibleOnField(s:matrix.t_matr;var b:matrix.t_matr_boolean);//заполняет матрицу флагов видимости в соответствии с матрицой S

function SudVizible(V:matrix.t_matr_boolean;i,j:byte):boolean;//Должно ли число отображаться на экран

procedure Nulling(var b:matrix.t_matr_boolean); //обнуление матрицы флагов введенных пользователем значений

function SudIsFulling(s:matrix.t_matr):boolean; // заполнена ли судоку до конца

end;

В классе TGameSudoky описаны поля:

1. адрес, куда будет сохранена игра(Adres);

2. матрица флагов видимости чисел на игровом поле(Viz);

3. матрица флагов введенных пользователем значений(User);

4. матрица флагов выделенных пользователем клеток(UsersPointer);

В классе TGameSudoky описаны методы:

1. сохранение судоку s и матрицы флагов введенных пользователем значений User в текстовый файл по адресу Adres(Save);

2. загрузка судоку s и матрицы флагов введенных пользователем значений User из текстового файла по адресу Adres(Save);

3. заполняет матрицу флагов видимости User в соответствии с матрицей S (SudVizibleOnField);

4. обнуление матрицы флагов введенных пользователем User значений (Nulling);

5. возвращает true, если судоку s заполнена до конца (SudIsFulling);

6. возвращает true, если число v должно отображаться на экран (SudVizible);

головоломка судоку алгоритм модульность

Текст программы

unit Game;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls,GameSud,WorkWithMatrix,Sudoky, Menus, ExtDlgs;

const T=51;

L=25;

type

TForm2 = class(TForm)

Image1: TImage;

Panel1: TPanel;

ComboBox1: TComboBox;

Button1: TButton;

Button2: TButton;

Button3: TButton;

Button4: TButton;

MainMenu1: TMainMenu;

N1: TMenuItem;

N2: TMenuItem;

N3: TMenuItem;

N4: TMenuItem;

SaveDialog1: TSaveDialog;

OpenDialog1: TOpenDialog;

procedure FormCreate(Sender: TObject);

procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Button2Click(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

procedure Button4Click(Sender: TObject);

procedure N4Click(Sender: TObject);

procedure N2Click(Sender: TObject);

procedure N3Click(Sender: TObject); // возвращает позицию в матрице после нажптия мыши

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

S:TGameSudoky;

i,j:Byte; //Координаты текущего эдемента в матрице

implementation

{$R *.dfm}

procedure CreateFild(var cl:TColor);

var

I,J,k1,k2: Integer;

begin

k1:=0; k2:=0;

for I := 1 to matrix.n do

begin

k1:=0;

for j := 1 to matrix.n do

begin

form2.Image1.Canvas.Brush.Color:=cl;//clSkyBlue;

form2.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);

k1:=k1+T;

if j mod 3=0 then k1:=k1+5;

end;

k2:=k2+T;

if i mod 3=0 then k2:=k2+5;

end;

end;

procedure WriteSud;

var k1,k2:integer;

cl:Tcolor;

begin

cl:= clSkyBlue;

createFild(cl);

k1:=0; k2:=0;

for I := 1 to matrix.n do

begin

k1:=0;

for j := 1 to matrix.n do

begin

if s.GameSud[i,j]<>0 then

begin

form2.Image1.Canvas.Font.Style:=[fsBold];

form2.Image1.Canvas.Font.Size:=12;

form2.Image1.Canvas.Font.Color:=clBlue;

form2.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));

if s.User[i,j]=true then

begin

form2.Image1.Canvas.Font.Style:=[fsBold];

form2.Image1.Canvas.Font.Size:=12;

form2.Image1.Canvas.Font.Color:=clRed;

form2.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));

end;

end;

k1:=k1+T;

if j mod 3 =0 then k1:=k1+5;

end;

k2:=k2+T;

if i mod 3 =0 then k2:=k2+2;

end;

end;

procedure TForm2.Button1Click(Sender: TObject);

var z:byte;

begin

z:=form2.ComboBox1.ItemIndex;

if z<>255 then

begin

s.SetValInSud(s.GameSud,i,j,z);

s.DoRec(s.GameSud);

s.User[i,j]:=true;

s.UsersPointer[i,j]:=not (s.UsersPointer[i,j]);

end

else z:=0;

writesud;

end;

procedure TForm2.Button2Click(Sender: TObject);

var cl:Tcolor;

begin

s.Nulling(s.User);

s.Random_generate(s.Sud,s.GameSud);

s.SudVizibleOnField(s.GameSud,s.Viz);

cl:= clSkyBlue;

CreateFild(cl);

writesud;

end;

procedure TForm2.Button3Click(Sender: TObject);

var l:integer;

f:boolean;

begin

f:=s.IsValidSudoky(s.GameSud);

s.Ans:=nil;

s.Mlen:=100;

s.DoRec(s.GameSud);

l:= length(s.Ans);

if f=True then

begin

if l<>0 then

showmessage('Вы на верном пути!! ;)'+'Возможных решений:'+inttostr(l))

else showmessage('Вы ошиблись!!!');

end

else showmessage('Вы ошиблись!!!');

end;

procedure TForm2.Button4Click(Sender: TObject);

var f:boolean;

begin

f:=s.SudIsFulling(s.GameSud);

if f=false then showmessage('Поле не заполнено до конца!!!')

else

begin

if s.SudOK(s.GameSud)=false then Showmessage('Верно')

else Showmessage('Неверно');

end;

end;

procedure TForm2.FormCreate(Sender: TObject);

var cl:TColor;

begin

S:=TGameSudoky.Create;

s.Random_generate(s.Sud,s.GameSud);

s.Ans:=nil;

s.Mlen:=100;

s.DoRec(s.GameSud);

s.SudVizibleOnField(s.GameSud,s.Viz);

cl:= clSkyBlue;

CreateFild(cl);

writesud;

end;

procedure PaintRec( cl:Tcolor);

var k1,k2,i2,j2:integer;

begin

k1:=0; k2:=0;

for I2 := 1 to matrix.n do

begin

k1:=0;

for j2 := 1 to matrix.n do

begin

if (i=i2)and(j=j2)and(s.Viz[i,j]=false) then

begin

s.UsersPointer[i,j]:=not (s.UsersPointer[i,j]);

if s.UsersPointer[i,j]=true then

begin

cl:= clSkyBlue;

form2.Image1.Canvas.Brush.Color:=cl;

form2.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);

end

else

begin

form2.Image1.Canvas.Brush.Color:=cl;

form2.image1.Canvas.Rectangle(0+k1,0+k2,50+k1,50+k2);

end;

if (s.User[i,j]=true) then

begin

form2.Image1.Canvas.Font.Style:=[fsBold];

form2.Image1.Canvas.Font.Size:=12;

form2.Image1.Canvas.Font.Color:=clRed;

form2.image1.Canvas.TextOut(l+k1,l+k2,IntTostr(s.GameSud[i,j]));

end;

end;

k1:=k1+T;

if j2 mod 3=0 then k1:=k1+5;

end;

k2:=k2+T;

if i2 mod 3=0 then k2:=k2+5;

end;

end;

procedure TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

Var x1,y1,x2,y2,k1,k2,i2,j2:integer;

cl:Tcolor;

begin

x1:=0;x2:=T-1;j:=1;i:=1; y1:=0;y2:=t;

while (j<=matrix.n)and not((x1<x)and(x<x2)) do

begin

x1:=x1+T;

x2:=x2+T;

j:=j+1;

if j mod 3=0 then

begin

x1:=x1+5;

x2:=x2+5;

end;

end;

while (i<=matrix.n)and not((y1<y)and(y<y2)) do

begin

y1:=y1+T;

y2:=y2+T;

i:=i+1;

if i mod 3=0 then

begin

y1:=y1+5;

y2:=y2+5;

end;

end;

cl:=clgraytext;

PaintRec(cl);

end;

procedure TForm2.N2Click(Sender: TObject);

begin

if form2.SaveDialog1.Execute() then

begin

s.Adres:=form2.SaveDialog1.FileName;

s.Save(s.GameSud);

end;

end;

procedure TForm2.N3Click(Sender: TObject);

var cl:TColor;

begin

if form2.OpenDialog1.Execute then

begin

if form2.OpenDialog1.FileName<>'' then

begin

s.Adres:= form2.OpenDialog1.FileName;

s.Load(s.GameSud,s.User);

cl:= clSkyBlue;

CreateFild(cl);

writesud;

end;

end;

end;

procedure TForm2.N4Click(Sender: TObject);

begin

form2.Close;

end;

end.

unit Sudoky;

interface

Uses windows,Classes,WorkWithMatrix;

type TSudoky=class

Sud:Matrix.t_matr;

GameSud:Matrix.t_matr;

Ans:array of Matrix.t_matr; //массив ответов из судоку

Mlen:integer;// количество решений в массиве Ans

Matr:matrix;

Public

constructor create();

destructor done();

procedure SudAddAns( s:matrix.t_matr);//добавляем судоку в массив ответов

function SudMod(var s:matrix.t_matr;var p:Tpoint;v:integer):Matrix.t_matr;// замена в судоку s одного значения v на позиции P

function IsNextUnknown( s:matrix.t_matr; var p:Tpoint):boolean; //нахотим в судоку пустую ячейку и возвращаем позицию P,иначе False;

function SudInLine(s:matrix.t_matr;var p:Tpoint;v:integer):boolean;//проверка по строке

function SudInRow( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка по столбцу

function SudInSq( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //проверка в квадрате

function SudInAny( s:matrix.t_matr;var p:Tpoint;v:integer):boolean; //общая проверка на постановку числа

function DoRec( S:Matrix.t_matr):boolean;//рекурсивное построение судоку

function SudOK(s:Matrix.t_matr):boolean;// проверка на правильность построенного судоку

procedure generate(var s:matrix.t_matr); // генерирование судоку быстрым методом c возможным повторением

procedure generate_matr(var s:matrix.t_matr);//генерирует матрицу без повторений

procedure Random_generate( var s,b:matrix.t_matr); // генерация игрового судоку

procedure SetValInSud(var s:matrix.t_matr;i,j:byte; v:byte); //установка значения

Function IsValidSudoky(s:matrix.t_matr):boolean; //проверка судоку на правильность

end;

implementation

procedure TSudoky.SetValInSud(var s: Matrix.t_matr; i: Byte; j: Byte; v: Byte);

begin

s[i,j]:=v;

end;

function TSudoky.sudInLine;

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 TSudoky.sudInRow;

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 TSudoky.sudInSq;

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 TSudoky.sudInAny;

begin

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

end;

function TSudoky.IsNextUnknown;

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;

p.X:=ix;

p.Y:=iy;

Exit;

end; // if

end;

function TSudoky.sudMod;

var

st:Matrix.t_matr;

begin

st:=s;

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

Result:=st;

end;

procedure TSudoky.sudAddAns;

var

l:integer;

begin

l:=Length(ans);

SetLength(ans,l+1);

ans[l]:=s;

end;

function TSudoky.DoRec;

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; // DoRec

function Tsudoky.IsValidSudoky(s:matrix.t_matr):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; // if

end; // for

Result:=True;

end;

constructor Tsudoky.Create;

var i,j:integer;

begin

for I := 1 to matrix.n do

for j := 1 to matrix.n do sud[i,j]:=0;

end;

destructor Tsudoky.Done;

var i,j:integer;

begin

for I := 1 to matrix.n do

for j := 1 to matrix.n do sud[i,j]:=0;

end;

function Tsudoky.SudOK(s: matrix.t_matr):boolean;

var i,j,z1,z2,t:integer;

flag:boolean;

begin

flag:=false;

i:=1;

j:=1;

while (j<=matrix.n)and(flag = false) do

begin

i:=1;

while (i<=matrix.n)and(flag = false) do

begin

z1:=i+1;

z2:=j+1;

t:=s[i,j];

while (z1<=matrix.n)and(flag=false) do

begin

if t=s[z1,j] then flag:=true;

z1:=z1+1;

end;

while (z2<=matrix.n)and(flag=false) do

begin

if t=s[i,z2] then flag:=true;

z2:=z2+1;

end;

i:=i+1;

end;

j:=j+1;

end;

result:=flag;

end;

procedure tsudoky.generate(var s: matrix.t_matr);

var i,j,k,z:byte;

m:matrix.t_set;

t:matrix.t_mas_set;

flag:boolean;

b:matrix.t_matr;

begin

randomize;

m:=[];

j:=1; i:=1;

while j<=matrix.n do begin

k:=random (matrix.n)+1;

if not(k in m) then begin

s[i,j]:=k;

m:=m+[k];

t[j]:=t[j]+[k];

j:=j+1;

end;

end;

for i:=2 to 3 do matr.Sdvig(s,i);

for i:=2 to 3 do

for j:=1 to matrix.n do t[j]:=t[j]+[s[i,j]];

i:=4;

matr.sdvig(s,i);

for j:=1 to matrix.n do

begin

begin

if (s[i,j] in t[j]) then

matr.sdvig2(s,i);

end;

end;

for i:=5 to 6 do matr.sdvig(s,i);

for i:=5 to 6 do

for j:=1 to matrix.n do t[j]:=t[j]+[s[i,j]];

i:=7;

matr.sdvig(s,i);

for j:=1 to matrix.n do

begin

begin

if (s[i,j] in t[j]) then

matr.sdvig2(s,i);

end;

end;

for i:=8 to 9 do matr.sdvig(s,i);

end;

procedure tsudoky.generate_matr(var s: matrix.t_matr);

var flag:boolean;

begin

repeat

begin

generate(s);

flag:=SudOK(s);

end;

until(flag=false);

end;

procedure tsudoky.Random_generate( var s,b: matrix.t_matr);

var i,j,k:integer;

f:boolean;

//s:t_matr;

begin

randomize;

generate_matr(s);

for I := 1 to matrix.n do

for j := 1 to matrix.n do

begin

k:=random(2)+1;

if k=1 then

begin

b[i,j]:=s[i,j];

end

else b[i,j]:=0;

end;

end;

end.

unit GameSud;

interface

Uses Sudoky,WorkWithMatrix;

type TGameSudoky=class(Tsudoky)

Adres:string; //адресс куда будет сохранена игра

Viz: matrix.t_matr_boolean; // матрица флагов видимости числел на игровом поле

User:matrix.t_matr_boolean; //матрица флагов введенных пользователем значений

UsersPointer:matrix. t_matr_boolean;//матрица флагов выделенных пользователем клеток

public

constructor Create;

destructor Done;

procedure Save(s:matrix.t_matr); //сохранение игры

procedure Load(var s:matrix.t_matr;var u:matrix.t_matr_boolean); //загрузка игры

procedure SudVizibleOnField(s:matrix.t_matr;var b:matrix.t_matr_boolean);//заполняет матрицу флагов видимости в соответствии с матрицой S

function SudVizible(V:matrix.t_matr_boolean;i,j:byte):boolean;//Должно ли число отображаться на экран

procedure Nulling(var b:matrix.t_matr_boolean); //обнуление матрицы флагов введенных пользователем значений

function SudIsFulling(s:matrix.t_matr):boolean; // заполнена ли судоку до конца

end;

implementation

constructor TGameSudoky.Create;

var i,j:byte;

begin

inherited create;

for I := 1 to matrix.n do

for j := 1 to matrix.n do

UsersPointer[i,j]:=false;

end;

function TGameSudoky.SudIsFulling(s: Matrix.t_matr):boolean;

var matr:matrix;

begin

result:= matr.IfMatrHavNull(s);

end;

procedure Tgamesudoky.Nulling(var b: Matrix.t_matr_boolean);

var Matr:matrix;

begin

matr.ZeroBoolMatr(b);

end;

destructor TGameSudoky.Done;

var i,j:byte;

begin

inherited Done;

Adres:='';

for I := 1 to matrix.n do

for j := 1 to matrix.n do

UsersPointer[i,j]:=false;

end;

procedure TGameSudoky.SudVizibleOnField(s: matrix.t_matr; var b: matrix.t_matr_boolean);

var i,j:byte;

begin

for I := 1 to matrix.n do

for j := 1 to matrix.n do

begin

if s[i,j]=0 then b[i,j]:=false

else b[i,j]:=true;

end;

end;

function TGameSudoky.SudVizible;

begin

result:= (v[i,j]=true);

end;

procedure TGameSudoky.Save(s: matrix.t_matr);

var f:text;

i,j:byte;

begin

assignfile(f,adres);

rewrite(f);

for I := 1 to matrix.n do

for j := 1 to matrix.n do

write(f,s[i,j]);

for I := 1 to matrix.n do

for j := 1 to matrix.n do

if user[i,j]=true then write(f,1) else write(f,0);

close(f);

end;

procedure TGameSudoky.Load;

var f:text;

i,j:byte;

c:char;

begin

assignfile(f,adres);

reset(f);

for I := 1 to matrix.n do

for j := 1 to matrix.n do

begin

read(f,c);

s[i,j]:=ord(c)-ord('0');

end;

for I := 1 to matrix.n do

for j := 1 to matrix.n do

begin

read(f,c);

if (ord(c)-ord('0'))=1 then u[i,j]:=true else u[i,j]:=false;

end;

close(f);

end;

end.

unit WorkWithMatrix;

interface

type Matrix=class

public

const n=9;

type t_mas= array [1..n] of byte;

t_matr=array [1..n] of t_mas; // собственно само судоку

t_set=set of 1..n; // множество

t_mas_set=array [1..n] of t_set; //массив множеств для проверки на повторы

t_mas_boolen=array [1..matrix.n] of boolean; //массив флагов

t_matr_boolean=array [1..matrix.n] of t_mas_boolen; //матрица флагов

public

procedure Sdvig(var s:t_matr; i:Byte); //сдвиг 3 строк на 1 шаг

procedure sdvig2(var s:t_matr;i:byte); //сдвиг одной строки на 1 шаг

procedure ZeroBoolMatr(var b:T_matr_boolean); //обнуление булевой матрицы

function IfMatrHavNull(s:T_matr):boolean;//проверяет имеет ли матрица хотябы один ноль

end;

implementation

function matrix.IfMatrHavNull(s: Matrix.t_matr):boolean;

var i,j:byte;

f:boolean;

begin

f:=true;i:=1;j:=1;

while (i<=n)and(f=true) do

begin

j:=1;

while(j<=n)and(f=true) do

begin

if s[i,j]=0 then f:=false;

j:=j+1;

end;

i:=i+1;

end;

result:=f;

end;

procedure Matrix.ZeroBoolMatr(var b: Matrix.t_matr_boolean);

var i,j:byte;

begin

for I := 1 to n do

for j := 1 to n do

b[i,j]:=false;

end;

procedure Matrix.Sdvig;

var b:T_matr;

begin

b[i,1]:=s[i-1,4];

b[i,2]:=s[i-1,5];

b[i,3]:=s[i-1,6];

s[i,1]:=s[i-1,7];

s[i,2]:=s[i-1,8];

s[i,3]:=s[i-1,9];

s[i,4]:=s[i-1,1];

s[i,5]:=s[i-1,2];

s[i,6]:=s[i-1,3];

s[i,7]:=b[i,1];

s[i,8]:=b[i,2];

s[i,9]:=b[i,3];

end;

procedure Matrix.sdvig2(var s: t_matr; i: Byte);

var j,z:byte;

begin

z:=s[i,1];

for j:=2 to n do

begin

s[i,j-1]:=s[i,j];

end;

s[i,n]:=z;

end;

end.

program Project1;

{$APPTYPE CONSOLE}

uses

SysUtils,

Sudoky in 'Sudoky.pas',

GameSud in 'GameSud.pas',

WorkWithMatrix in 'WorkWithMatrix.pas';

procedure WriteSud(var s:matrix.t_matr);

var i,j:byte;

begin

for i := 1 to matrix.n do

begin

writeln;

for j := 1 to matrix.n do

begin

write(' ');

write (s[i,j]);

end;

end;

end;

procedure WriteMatrBool(var v:t_matr_boolean);

var i,j:byte;

begin

for i := 1 to matrix.n do

begin

writeln;

writeln;

for j := 1 to matrix.n do

begin

write(' ');

write (v[i,j]);

end;

end;

end;

var S:Tsudoky;

s1:TGameSudoky;

b:matrix.t_matr;

i,j,l:integer;

flag:boolean;

begin

s1:=TGameSudoky.Create;

s1.Adres:= 'C:\Users\91980\Desktop\Курсовой проект по ООП\Save.txt';

s1.Ans:=nil;

s1.Mlen:=100;

writeln('Generate sudoky:');

s1.Random_generate(s1.Sud,s1.GameSud);

writesud(s1.Sud);

writeln;

writeln;

writeln('Generate game sudoky:');

writesud(s1.GameSud);

writeln;

writeln;

s1.DoRec(s1.GameSud);

l:=length(s1.Ans);

writeln('Count of ansver:',' ',l);

writeln;

writeln;

writeln('Save in file');

s1.Save(s1.GameSud);

writeln;

writeln;

writeln('Load from file');

s1.Load(b);

writesud(b);

writeln;

writeln;

writeln('Matrix of vizible:');

s1.SudVizibleOnField(s1.GameSud,s1.Viz);

WriteMatrBool(s1.Viz);

readln;

readln;

end.

Как пользоваться приложением

Программа для игры в судоку имеет графический интерфейс.

В приложении реализована возможность ввода значения и его удаление. Для этого нужно выделить нужный квадрат (он отметится другим цветом), выбрать из списка значений нужное число и нажать кнопку «Ввод значения». После нажатия выбранное значение установится на выделенной клетке и будет красного цвета.

Также в программе имеется возможность проверки на любом этапе игрового процесса. Для этого имеется две кнопки: «Подсказка» и «Полная проверка». Кнопка «Подсказка» выводит на экран сообщение, которое содержит информацию: игрок правильно установил значение и количество возможных решений при заданном значении, или значение установлено неверно. Кнопка «Полная проверка» проверяет на правильность полностью заполненное поле. Если поле заполнено полностью, то появляется сообщение: выиграл пользователь или допустил ошибку. Если поле заполнено не до конца, то появляется сообщение «Поле не заполнено до конца!!!».

В реализации имеется также возможность сохранять текущую игру и загружать ранее сохраненную игру. Соответствующие кнопки для данных действий можно найти в меню: Файл ->Сохранить или Файл ->Загрузить.

В курсовом проекте был представлен принцип модульности: каждый класс описан в отдельном модуле. Это дает возможность использовать реализованные классы в других приложениях.

Также в курсовом проекте была реализована тестовая программа для визуальной проверки правильности описанных в классах алгоритмов. Тестовая программа использует те же модули, что и основная программа.

Заключение

В ходе выполнения курсовой работы были полностью реализованы поставленные цели и задачи, а именно:

1. Анализ предметной области задачи

2. Построение диаграммы объектов и диаграммы классов

3. Реализация программы в объектно-ориентированном стиле по принципам модульности, иерархичности, ограничения доступа.

Игра имеет:

1. Алгоритм решения произвольного игрового поля и уже заданной игры судоку.

2. Алгоритм генерации случайного игрового поля судоку.

3. Windows-приложение для вывода игрового поля на экран.

4. Возможность сохранения текущей игры и загрузки ранее сохраненной игры.

Список использованных источников

1. Лекции по дисциплине «Объектно-ориентированное программирование»

2. А.В. Серов - «Технологии Delphi»

3. С.А. Немнюгин -«Turbo Pascal»

Размещено на Allbest.ru


Подобные документы

  • История распространения "Судоку". Механизм решения и различия по уровню сложности в зависимости от размера квадрата данной головоломки. Освоение процесса создания программного продукта на Microsoft .NET Framework на языке C# на примере игры "Судоку".

    курсовая работа [398,8 K], добавлен 21.10.2011

  • Разработка программного продукта на языке Delphi, предназначенного для решения японской головоломки "Судоку": ознакомление с правилами игры, выбор необходимых компонент, написание алгоритмов реализации задачи; описание пользовательского интерфейса.

    курсовая работа [3,5 M], добавлен 25.06.2011

  • Написание игры "Lines" на языке Object Pascal в среде Delphi. Алгоритм работы программы. Описание метода генерации поля. Используемые константы и переменные. Форма приложения после старта игрового процесса. Основные элементы формы и обработки событий.

    курсовая работа [225,0 K], добавлен 12.04.2012

  • История создания игры "Тетрис", смысл и правила данной головоломки. Разработка поля игры и фигур тетрамино. Процедуры и функции, используемые для реализации движения фигур, их поворота и складывания в ряды, удаления и подсчета количества целых рядов.

    курсовая работа [87,0 K], добавлен 02.02.2013

  • Приемы программирования в Delphi. Алгоритм поиска альфа-бета отсечения, преимущества. Описание программного средства. Разработка программы, реализующая алгоритм игры "реверси". Руководство пользователя. Листинг программы. Навыки реализации алгоритмов.

    курсовая работа [357,1 K], добавлен 28.02.2011

  • Разработка программы логической игры в "крестики-нолики" пять в ряд на поле размера 15х15 клеток с применением графики на языке Pascal с использованием объектно-ориентированного программирования. Структура алгоритма программы и описание ее работы.

    курсовая работа [821,5 K], добавлен 13.02.2012

  • Создание игровой системы "Тетрис": количество игр, режимы сложности, интерфейс пользователя, игровая статистика, обработка исключений. Структура входных и выходных данных. Диаграммы и описание классов. Блок-схема алгоритма программы, результаты ее работы.

    курсовая работа [1,9 M], добавлен 13.06.2012

  • Игровая программа "шашки" для игры между человеком и компьютером. Разработка алгоритмов, историческая линия развития задач. Различные подходы к построению систем. Сокращенный листинг программы и описание алгоритма. Компоненты искусственного интеллекта.

    курсовая работа [196,2 K], добавлен 26.03.2009

  • Принципы построения информационной системы и ее реализация. Разработка программы доступа к данным автомобильного предприятия города на объектно-ориентированном языке программирования C Sharp. Расчет эффективности разрабатываемого програмного продукта.

    дипломная работа [4,3 M], добавлен 15.05.2012

  • Розробка програми GameBox, яка включає в себе дві гри, судоку та пятнашки. Опис структури даних та вимоги до них, процедур і функцій користувача, стандартних процедур і функцій, які використовувались в програмі, та файлів. Результати роботи програми.

    курсовая работа [5,3 M], добавлен 12.11.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.