diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..412eeda
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b9d6bd9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,215 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
diff --git a/PipesSolver.sln b/PipesSolver.sln
new file mode 100644
index 0000000..912cab9
--- /dev/null
+++ b/PipesSolver.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PipesSolver", "PipesSolver\PipesSolver.csproj", "{6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}.Debug|x86.ActiveCfg = Debug|x86
+ {6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}.Debug|x86.Build.0 = Debug|x86
+ {6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}.Release|x86.ActiveCfg = Release|x86
+ {6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/PipesSolver/Brainteaser.cs b/PipesSolver/Brainteaser.cs
new file mode 100644
index 0000000..3bbd35a
--- /dev/null
+++ b/PipesSolver/Brainteaser.cs
@@ -0,0 +1,225 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+
+namespace PipesSolver
+{
+ ///
+ /// Класс головоломки
+ ///
+ class Brainteaser
+ {
+ ///
+ /// Количнство колонок поля
+ ///
+ private int _ColCount;
+ ///
+ /// Количество строк поля
+ ///
+ private int _RowCount;
+ ///
+ /// Точка входа
+ ///
+ private Point _Enter;
+ ///
+ /// Точка выхода
+ ///
+ private Point _Exit;
+ ///
+ /// Поле
+ ///
+ private Pipe[,] _Field;
+
+ ///
+ /// Конструктор класса
+ ///
+ /// Поле
+ /// количество колонок
+ /// количество строк
+ /// точка входа
+ /// точка выхода
+ public Brainteaser(Pipe[,] parField, int parColCount, int parRowCount, Point parEnter, Point parExit)
+ {
+ _ColCount = parColCount;
+ _RowCount = parRowCount;
+ _Enter = parEnter;
+ _Exit = parExit;
+
+ _Field = parField;
+ }
+
+ ///
+ /// Поиск в глубину
+ ///
+ ///
+ public bool DepthSolve()
+ {
+ //создаем дерево решения
+ SolutionThree solutionThree = new SolutionThree(null, null, _Enter, 0);
+ //назначаем текущей точкой точку входа
+ Point currentPoint = _Enter;
+ // помечаем, что задача еще не решена
+ bool complete = false;
+
+ //создаем начальное направление движения
+ Orientation direction = Orientation.Up;
+ if (_Enter.X == 0)
+ {
+ direction = Orientation.Right;
+ }
+ else if (_Enter.X == _ColCount + 1)
+ {
+ direction = Orientation.Left;
+ }
+ else if (_Enter.Y == 0)
+ {
+ direction = Orientation.Down;
+ }
+ else if (_Enter.Y == _RowCount + 1)
+ {
+ direction = Orientation.Up;
+ }
+
+ //рекурсивный вызов метода поиска в глубину
+ complete = DepthSolve(currentPoint, direction, solutionThree);
+
+ return complete;
+ }
+
+
+
+ private bool DepthSolve(Point parCurrentPoint, Orientation parDirection, SolutionThree parSolutionNode)
+ {
+ //решение еще не найдено
+ bool complete = false;
+ //добавляем узел в дерево решений
+ SolutionThree solutionThree = parSolutionNode;
+ //назначаем текущую точку
+ Point currentPoint = parCurrentPoint;
+ //назначаем направление движения
+ Orientation direction = parDirection;
+ //исходя из текущего положения и направления движения вычисляем следующую точку
+ Point nextPoint = new Point(currentPoint.X + direction.X, currentPoint.Y + direction.Y);
+ //Если следующая точка является точкой выхода,
+ if (nextPoint == _Exit)
+ {
+ //то решение найдено, алгоритм завершен
+ complete = true;
+ }
+ //если текущая труба вывела нас за границы поля
+ else if ((nextPoint.X < 1) || (nextPoint.X > _ColCount) || (nextPoint.Y < 1) || (nextPoint.Y > _RowCount))
+ {
+ //тупик
+ complete = false;
+
+ }
+ else
+ {
+ //если в следующей точки нету трубы
+ if ((object) _Field[nextPoint.X, nextPoint.Y] == null)
+ {
+ //тупик
+ complete = false;
+ }
+ //если в ледующей точке есть труба, то смотрим ее
+ else
+ {
+ //если следующая труба уже задействована в текущем рассматриваемом пути,
+ if (_Field[nextPoint.X, nextPoint.Y].PartOfPath == true)
+ {
+ //тупик
+ complete = false;
+ }
+ //если следующая труба еще не задействована
+ else
+ {
+ //получаем следующую трубу
+ Pipe nextPipe = _Field[nextPoint.X, nextPoint.Y];
+ //разворачиваем ее так, какой-то из ее входов выходил на текущую точку
+ nextPipe.RotateTo(currentPoint);
+ //добавляем в дерево решений новую ветку рассмотрения
+ solutionThree.AddChildNode(nextPipe.Clone(), currentPoint);
+ //получаем новое направление движение (куда смотрит второй вход следующей трубы)
+ Orientation nextDirection = direction;
+ if (direction == -nextPipe.FirstHole)
+ {
+ nextDirection = nextPipe.SecondHole.Clone();
+ }
+ else
+ {
+ nextDirection = nextPipe.FirstHole.Clone();
+ }
+ //помечаем, что труба занята в решении
+ nextPipe.PartOfPath = true;
+ //вызываем рекурсивный методи рассматриваем все со следующей точки со следующим направлением
+ complete = DepthSolve(nextPoint, nextDirection, solutionThree.ChildNodes[0]);
+ //если поиск в глубину завершился неудачей и поворачивать еще можно
+ //(т.е. следующая труба не прямая, ведь ее разворот приведет к томуже результату)
+ if ((complete == false) && (nextPipe.FirstHole != -nextPipe.SecondHole))
+ {
+ //удаляем текущую ветвь дерева решений
+ solutionThree.ChildNodes.RemoveAt(0);
+ //поворачиваем трубу второй раз, другим входом к текущей точке
+ nextPipe.RotateTo(currentPoint);
+ //добавляем в дерево решений новую ветвь
+ solutionThree.AddChildNode(nextPipe, currentPoint);
+ //вычисляем новое направление движения
+ if (direction == -nextPipe.FirstHole)
+ {
+ nextDirection = nextPipe.SecondHole;
+ }
+ else
+ {
+ nextDirection = nextPipe.FirstHole;
+ }
+ //и вызываем поиск в глубину в новом направлении (это уже второй вызов)
+ complete = DepthSolve(nextPoint, nextDirection, solutionThree.ChildNodes[0]);
+ //если и в эту сторону решение не находится
+ if (complete == false)
+ {
+ //то следующая труба - безперспективна
+ nextPipe.PartOfPath = false;
+ }
+ }
+ }
+ }
+ }
+
+ return complete;
+ }
+
+ ///
+ /// Метод добавления отдельной трубы на поле
+ ///
+ /// добавляемая труба
+ public void AddPipe(Pipe parNewPipe)
+ {
+ _Field[parNewPipe.Position.X, parNewPipe.Position.Y] = parNewPipe;
+ }
+
+ ///
+ /// Количество столбцов поля
+ ///
+ public int ColCount
+ {
+ get { return _ColCount;}
+ }
+ ///
+ /// Количество строк поля
+ ///
+ public int RowCount
+ {
+ get { return _RowCount; }
+ }
+
+ ///
+ /// Поле
+ ///
+ public Pipe[,] Field
+ {
+ get { return _Field; }
+ }
+ }
+}
diff --git a/PipesSolver/FormPipeSolver.Designer.cs b/PipesSolver/FormPipeSolver.Designer.cs
new file mode 100644
index 0000000..6f99f5e
--- /dev/null
+++ b/PipesSolver/FormPipeSolver.Designer.cs
@@ -0,0 +1,323 @@
+namespace PipesSolver
+{
+ partial class FormPipeSolver
+ {
+ ///
+ /// Требуется переменная конструктора.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Освободить все используемые ресурсы.
+ ///
+ /// истинно, если управляемый ресурс должен быть удален; иначе ложно.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Код, автоматически созданный конструктором форм Windows
+
+ ///
+ /// Обязательный метод для поддержки конструктора - не изменяйте
+ /// содержимое данного метода при помощи редактора кода.
+ ///
+ private void InitializeComponent()
+ {
+ this.buttonApplyDim = new System.Windows.Forms.Button();
+ this.textBoxColCount = new System.Windows.Forms.TextBox();
+ this.textBoxRowCount = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.dataGridViewField = new System.Windows.Forms.DataGridView();
+ this.buttonMarkEnter = new System.Windows.Forms.Button();
+ this.buttonMarkExit = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.dataGridViewTemplate = new System.Windows.Forms.DataGridView();
+ this.Column1 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.Column2 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.Column3 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.Column4 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.Column5 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.Column6 = new System.Windows.Forms.DataGridViewImageColumn();
+ this.buttonDepthSolve = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.button3 = new System.Windows.Forms.Button();
+ this.button4 = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridViewField)).BeginInit();
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridViewTemplate)).BeginInit();
+ this.SuspendLayout();
+ //
+ // buttonApplyDim
+ //
+ this.buttonApplyDim.Location = new System.Drawing.Point(162, 36);
+ this.buttonApplyDim.Name = "buttonApplyDim";
+ this.buttonApplyDim.Size = new System.Drawing.Size(119, 23);
+ this.buttonApplyDim.TabIndex = 0;
+ this.buttonApplyDim.Text = "Применить";
+ this.buttonApplyDim.UseVisualStyleBackColor = true;
+ this.buttonApplyDim.Click += new System.EventHandler(this.buttonApplyDim_Click);
+ //
+ // textBoxColCount
+ //
+ this.textBoxColCount.Location = new System.Drawing.Point(19, 36);
+ this.textBoxColCount.Name = "textBoxColCount";
+ this.textBoxColCount.Size = new System.Drawing.Size(41, 22);
+ this.textBoxColCount.TabIndex = 2;
+ this.textBoxColCount.Text = "3";
+ //
+ // textBoxRowCount
+ //
+ this.textBoxRowCount.Location = new System.Drawing.Point(97, 36);
+ this.textBoxRowCount.Name = "textBoxRowCount";
+ this.textBoxRowCount.Size = new System.Drawing.Size(41, 22);
+ this.textBoxRowCount.TabIndex = 3;
+ this.textBoxRowCount.Text = "3";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(70, 38);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(17, 17);
+ this.label1.TabIndex = 4;
+ this.label1.Text = "X";
+ //
+ // dataGridViewField
+ //
+ this.dataGridViewField.AllowUserToAddRows = false;
+ this.dataGridViewField.AllowUserToDeleteRows = false;
+ this.dataGridViewField.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.dataGridViewField.Location = new System.Drawing.Point(321, 12);
+ this.dataGridViewField.Name = "dataGridViewField";
+ this.dataGridViewField.ReadOnly = true;
+ this.dataGridViewField.RowTemplate.Height = 24;
+ this.dataGridViewField.Size = new System.Drawing.Size(623, 550);
+ this.dataGridViewField.TabIndex = 6;
+ this.dataGridViewField.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridViewField_CellContentClick);
+ this.dataGridViewField.CellContentDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridViewField_CellContentDoubleClick);
+ this.dataGridViewField.MouseClick += new System.Windows.Forms.MouseEventHandler(this.dataGridViewField_MouseClick);
+ //
+ // buttonMarkEnter
+ //
+ this.buttonMarkEnter.Location = new System.Drawing.Point(12, 96);
+ this.buttonMarkEnter.Name = "buttonMarkEnter";
+ this.buttonMarkEnter.Size = new System.Drawing.Size(156, 23);
+ this.buttonMarkEnter.TabIndex = 7;
+ this.buttonMarkEnter.Text = "Отметить вход";
+ this.buttonMarkEnter.UseVisualStyleBackColor = true;
+ this.buttonMarkEnter.Click += new System.EventHandler(this.buttonMarkEnter_Click);
+ //
+ // buttonMarkExit
+ //
+ this.buttonMarkExit.Location = new System.Drawing.Point(174, 96);
+ this.buttonMarkExit.Name = "buttonMarkExit";
+ this.buttonMarkExit.Size = new System.Drawing.Size(141, 23);
+ this.buttonMarkExit.TabIndex = 8;
+ this.buttonMarkExit.Text = "Отметить выход";
+ this.buttonMarkExit.UseVisualStyleBackColor = true;
+ this.buttonMarkExit.Click += new System.EventHandler(this.buttonMarkExit_Click);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.textBoxColCount);
+ this.groupBox1.Controls.Add(this.buttonApplyDim);
+ this.groupBox1.Controls.Add(this.textBoxRowCount);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Location = new System.Drawing.Point(12, 13);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(303, 77);
+ this.groupBox1.TabIndex = 9;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Размерность";
+ //
+ // groupBox2
+ //
+ this.groupBox2.Controls.Add(this.dataGridViewTemplate);
+ this.groupBox2.Location = new System.Drawing.Point(12, 191);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Size = new System.Drawing.Size(303, 91);
+ this.groupBox2.TabIndex = 10;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Трубы";
+ //
+ // dataGridViewTemplate
+ //
+ this.dataGridViewTemplate.AllowUserToAddRows = false;
+ this.dataGridViewTemplate.AllowUserToDeleteRows = false;
+ this.dataGridViewTemplate.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Sunken;
+ this.dataGridViewTemplate.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.dataGridViewTemplate.ColumnHeadersVisible = false;
+ this.dataGridViewTemplate.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+ this.Column1,
+ this.Column2,
+ this.Column3,
+ this.Column4,
+ this.Column5,
+ this.Column6});
+ this.dataGridViewTemplate.EnableHeadersVisualStyles = false;
+ this.dataGridViewTemplate.Location = new System.Drawing.Point(37, 30);
+ this.dataGridViewTemplate.Name = "dataGridViewTemplate";
+ this.dataGridViewTemplate.ReadOnly = true;
+ this.dataGridViewTemplate.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
+ this.dataGridViewTemplate.RowHeadersVisible = false;
+ this.dataGridViewTemplate.RowTemplate.Height = 24;
+ this.dataGridViewTemplate.Size = new System.Drawing.Size(244, 43);
+ this.dataGridViewTemplate.TabIndex = 0;
+ this.dataGridViewTemplate.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridViewTemplate_CellContentClick);
+ //
+ // Column1
+ //
+ this.Column1.HeaderText = "Column1";
+ this.Column1.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column1.Name = "Column1";
+ this.Column1.ReadOnly = true;
+ this.Column1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.Column1.Width = 40;
+ //
+ // Column2
+ //
+ this.Column2.HeaderText = "Column2";
+ this.Column2.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column2.Name = "Column2";
+ this.Column2.ReadOnly = true;
+ this.Column2.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.Column2.Width = 40;
+ //
+ // Column3
+ //
+ this.Column3.HeaderText = "Column3";
+ this.Column3.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column3.Name = "Column3";
+ this.Column3.ReadOnly = true;
+ this.Column3.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.Column3.Width = 40;
+ //
+ // Column4
+ //
+ this.Column4.HeaderText = "Column4";
+ this.Column4.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column4.Name = "Column4";
+ this.Column4.ReadOnly = true;
+ this.Column4.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.Column4.Width = 40;
+ //
+ // Column5
+ //
+ this.Column5.HeaderText = "Column5";
+ this.Column5.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column5.Name = "Column5";
+ this.Column5.ReadOnly = true;
+ this.Column5.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.Column5.Width = 40;
+ //
+ // Column6
+ //
+ this.Column6.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
+ this.Column6.HeaderText = "Column6";
+ this.Column6.ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Stretch;
+ this.Column6.Name = "Column6";
+ this.Column6.ReadOnly = true;
+ this.Column6.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.Column6.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ //
+ // buttonDepthSolve
+ //
+ this.buttonDepthSolve.Location = new System.Drawing.Point(12, 343);
+ this.buttonDepthSolve.Name = "buttonDepthSolve";
+ this.buttonDepthSolve.Size = new System.Drawing.Size(156, 23);
+ this.buttonDepthSolve.TabIndex = 11;
+ this.buttonDepthSolve.Text = "Поиск в глубину";
+ this.buttonDepthSolve.UseVisualStyleBackColor = true;
+ this.buttonDepthSolve.Click += new System.EventHandler(this.button1_Click);
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(12, 395);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(156, 23);
+ this.button2.TabIndex = 12;
+ this.button2.Text = "button2";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
+ //
+ // button3
+ //
+ this.button3.Location = new System.Drawing.Point(12, 449);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(156, 23);
+ this.button3.TabIndex = 13;
+ this.button3.Text = "button3";
+ this.button3.UseVisualStyleBackColor = true;
+ //
+ // button4
+ //
+ this.button4.Location = new System.Drawing.Point(12, 507);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(156, 23);
+ this.button4.TabIndex = 14;
+ this.button4.Text = "button4";
+ this.button4.UseVisualStyleBackColor = true;
+ //
+ // FormPipeSolver
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(956, 574);
+ this.Controls.Add(this.button4);
+ this.Controls.Add(this.button3);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.buttonDepthSolve);
+ this.Controls.Add(this.groupBox2);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.buttonMarkExit);
+ this.Controls.Add(this.buttonMarkEnter);
+ this.Controls.Add(this.dataGridViewField);
+ this.Name = "FormPipeSolver";
+ this.Text = "Решатель труб";
+ this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridViewField)).EndInit();
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.groupBox2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridViewTemplate)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button buttonApplyDim;
+ private System.Windows.Forms.TextBox textBoxColCount;
+ private System.Windows.Forms.TextBox textBoxRowCount;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.DataGridView dataGridViewField;
+ private System.Windows.Forms.Button buttonMarkEnter;
+ private System.Windows.Forms.Button buttonMarkExit;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.DataGridView dataGridViewTemplate;
+ private System.Windows.Forms.DataGridViewImageColumn Column1;
+ private System.Windows.Forms.DataGridViewImageColumn Column2;
+ private System.Windows.Forms.DataGridViewImageColumn Column3;
+ private System.Windows.Forms.DataGridViewImageColumn Column4;
+ private System.Windows.Forms.DataGridViewImageColumn Column5;
+ private System.Windows.Forms.DataGridViewImageColumn Column6;
+ private System.Windows.Forms.Button buttonDepthSolve;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.Button button4;
+ }
+}
+
diff --git a/PipesSolver/FormPipeSolver.cs b/PipesSolver/FormPipeSolver.cs
new file mode 100644
index 0000000..c8c42ce
--- /dev/null
+++ b/PipesSolver/FormPipeSolver.cs
@@ -0,0 +1,468 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Runtime.InteropServices;
+
+namespace PipesSolver
+{
+ ///
+ /// Класс главной формы
+ ///
+ public partial class FormPipeSolver : Form
+ {
+ ///
+ /// структура, хранящая параметры изображения
+ ///
+ public struct IconInfo
+ {
+ public bool fIcon;
+ public int xHotspot;
+ public int yHotspot;
+ public IntPtr hbmMask;
+ public IntPtr hbmColor;
+ }
+
+ ///
+ /// Множество возможных действий
+ ///
+ private enum Actions
+ {
+ MarkEnter,
+ MarkExit,
+ AdditionPipe,
+ None
+ }
+
+ ///
+ /// Ширина ячейки поля
+ ///
+ const int FIELD_CELL_WIDTH = 40;
+ ///
+ /// Высота ячейки поля
+ ///
+ const int FIELD_CELL_HEIGTH = 40;
+
+ ///
+ /// Точка входа
+ ///
+ private Point _Enter;
+ ///
+ /// Точка выхода
+ ///
+ private Point _Exit;
+ ///
+ /// Количество колонок поля
+ ///
+ private int _ColCount;
+ ///
+ /// Количество строк поля
+ ///
+ private int _RowCount;
+ ///
+ /// Добавляемая на поле труба
+ ///
+ private Pipe _AddedPipe;
+
+ ///
+ /// Массив труб расположенные на поле
+ ///
+ private Pipe[,] _PipesOnField;
+
+ ///
+ /// Текущее действие
+ ///
+ Actions _Action;
+
+ ///
+ /// Конструктор формы
+ ///
+ public FormPipeSolver()
+ {
+ InitializeComponent();
+
+ //инициализируем точку входа и выхода
+ _Enter = _Exit = new Point(0, 0);
+ //Инициализируем текущее действие
+ _Action = Actions.None;
+ //Инициализируем поле
+ _PipesOnField = new Pipe[0,0];
+ //создаем табличку с шаблонами труб
+ CreatePipeTemplate();
+ }
+
+
+
+ ///
+ /// Создание таблицы шаблонов труб
+ ///
+ public void CreatePipeTemplate()
+ {
+ dataGridViewTemplate.RowTemplate.Height = FIELD_CELL_HEIGTH;
+ dataGridViewTemplate.Rows.Add();
+ dataGridViewTemplate.Rows[0].Cells[0].Value = Properties.Resources.angle1;
+ dataGridViewTemplate.Rows[0].Cells[1].Value = Properties.Resources.angle2;
+ dataGridViewTemplate.Rows[0].Cells[2].Value = Properties.Resources.angle3;
+ dataGridViewTemplate.Rows[0].Cells[3].Value = Properties.Resources.angle4;
+ dataGridViewTemplate.Rows[0].Cells[4].Value = Properties.Resources.direct1;
+ dataGridViewTemplate.Rows[0].Cells[5].Value = Properties.Resources.direct2;
+
+ }
+
+
+ //Магия...
+ [DllImport("user32.dll")]
+ public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
+ //задание курсора в виде выбранной трубы
+ public static System.Windows.Forms.Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
+ {
+ IconInfo tmp = new IconInfo();
+ GetIconInfo(bmp.GetHicon(), ref tmp);
+ tmp.xHotspot = xHotSpot;
+ tmp.yHotspot = yHotSpot;
+ tmp.fIcon = false;
+ return new System.Windows.Forms.Cursor(CreateIconIndirect(ref tmp));
+ }
+
+ ///
+ /// Установить курсор по умолчанию
+ ///
+ public void SetDefaultCuror()
+ {
+ Cursor = Cursors.Default;
+ dataGridViewField.Cursor = Cursors.Default;
+ }
+
+ ///
+ /// Нажатие на кнопку применить
+ ///
+ ///
+ ///
+ private void buttonApplyDim_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ //Получаем введенное количество строк и столбцов поля
+ _ColCount = Convert.ToInt32(textBoxColCount.Text);
+ _RowCount = Convert.ToInt32(textBoxRowCount.Text);
+
+ //создаем массив труб на поле
+ _PipesOnField = new Pipe[_ColCount + 2, _RowCount + 2];
+ //если п олях введены значения больше 0
+ if ((_ColCount != 0) && (_RowCount != 0))
+ {
+ //очищаем поле
+ dataGridViewField.Columns.Clear();
+ //опять же обнуляем точку входа и выхода
+ _Enter = _Exit = new Point(0, 0);
+ //действие - ничего
+ _Action = Actions.None;
+ //создаем поле
+ CreateTaskField();
+ }
+ // если чтото случилось не так, выбрасываем исключение
+ else throw new Exception();
+ }
+ catch
+ {
+ //перехватываем исключения здесь
+ MessageBox.Show("Введите корректно значения размеров поля");
+ }
+ }
+ ///
+ /// Создание поля задачи
+ ///
+ public void CreateTaskField()
+ {
+ DataGridViewImageColumn col = new DataGridViewImageColumn();
+ col.Image = Properties.Resources.border;
+ col.Width = FIELD_CELL_WIDTH / 2;
+ col.ImageLayout = DataGridViewImageCellLayout.Stretch;
+ dataGridViewField.Columns.Add(col);
+ for (int i = 0; i < _ColCount; i++)
+ {
+ col = new DataGridViewImageColumn();
+ col.Width = FIELD_CELL_WIDTH;
+ col.Image = Properties.Resources.fieldsegment;
+ col.ImageLayout = DataGridViewImageCellLayout.Stretch;
+ dataGridViewField.Columns.Add(col);
+ }
+ col = new DataGridViewImageColumn();
+ col.Width = FIELD_CELL_WIDTH / 2;
+ col.Image = Properties.Resources.border;
+ col.ImageLayout = DataGridViewImageCellLayout.Stretch;
+ dataGridViewField.Columns.Add(col);
+
+
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH / 2;
+ dataGridViewField.RowCount += 1;
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH;
+ dataGridViewField.RowCount += _RowCount;
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH / 2;
+ dataGridViewField.RowCount += 1;
+
+ for (int i = 0; i <= _ColCount + 1; i++)
+ {
+ dataGridViewField.Rows[0].Cells[i].Value = Properties.Resources.border;
+ dataGridViewField.Rows[_RowCount + 1].Cells[i].Value = Properties.Resources.border;
+ }
+ }
+
+ ///
+ /// Создание поля решения
+ ///
+ private void CreateSolveField()
+ {
+ dataGridViewField.RowCount= _RowCount + 2;
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH / 2;
+ dataGridViewField.RowCount += 1;
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH;
+ dataGridViewField.RowCount += _RowCount;
+ dataGridViewField.RowTemplate.Height = FIELD_CELL_HEIGTH / 2;
+ dataGridViewField.RowCount += 1;
+
+ for (int i = 0; i <= _ColCount; i++)
+ {
+ dataGridViewField.Rows[_RowCount+2].Cells[i].Value = Properties.Resources.border;
+ dataGridViewField.Rows[_RowCount * 2 + 3].Cells[i].Value = Properties.Resources.border;
+ }
+ }
+ ///
+ /// Нажатие кнопки "Отметить вход"
+ ///
+ ///
+ ///
+ private void buttonMarkEnter_Click(object sender, EventArgs e)
+ {
+ //Действие задаем - указание точки входа
+ _Action = Actions.MarkEnter;
+ //отключаем кнопу "Отметить вход"
+ buttonMarkEnter.Enabled = false;
+ //курсор меняем на вид руки
+ Cursor = Cursors.Hand;
+ dataGridViewField.Cursor = Cursors.Hand;
+ //включаем кнопу "Отметить выход"
+ buttonMarkExit.Enabled = true;
+ }
+ ///
+ /// Нажатие на кнопку "Отметить выход"
+ ///
+ ///
+ ///
+ private void buttonMarkExit_Click(object sender, EventArgs e)
+ {
+ //Действие задаем - указание точки выхода
+ _Action = Actions.MarkExit;
+ //отключаем кнопу "Отметить выход"
+ buttonMarkExit.Enabled = false;
+ //курсор меняем на вид руки
+ Cursor = Cursors.Hand;
+ dataGridViewField.Cursor = Cursors.Hand;
+ //включаем кнопу "Отметить вход"
+ buttonMarkEnter.Enabled = true;
+ }
+
+ ///
+ /// Нажате по ячейке таблицы шаблонов труб
+ ///
+ ///
+ ///
+ private void dataGridViewTemplate_CellContentClick(object sender, DataGridViewCellEventArgs e)
+ {
+ //Действие задаем -добавление трубы на поле
+ _Action = Actions.AdditionPipe;
+ //Создаем новую трубу по образу и подобию той, на которую нажали в табличке шаблонов
+ _AddedPipe = Pipe.TemplatePipes[e.ColumnIndex].Clone();
+ //видоизменяем курсор...немного магии
+ Bitmap img = new Bitmap(_AddedPipe.Image, new Size(FIELD_CELL_WIDTH, FIELD_CELL_HEIGTH));
+ Cursor = CreateCursor(img, 2, 2);
+ dataGridViewField.Cursor = CreateCursor(img, 2, 2);
+
+ //на всякий случай активируем кнопки "Отметить вход" и "Отметиь выход"
+ buttonMarkEnter.Enabled = true;
+ buttonMarkExit.Enabled = true;
+ }
+
+ ///
+ /// Нажате на ячейку в поле с трубами
+ ///
+ ///
+ ///
+ private void dataGridViewField_CellContentClick(object sender, DataGridViewCellEventArgs e)
+ {
+ //если нажали на бордюр поля
+ if (((e.ColumnIndex == 0) || (e.ColumnIndex == dataGridViewField.ColumnCount - 1) ||
+ (e.RowIndex == 0) || (e.RowIndex == dataGridViewField.RowCount - 1))&&(e.ColumnIndex != e.RowIndex))
+ {
+ //если в данный момент действие - указание выхода,
+ if ((_Action == Actions.MarkEnter) && ((_Exit.X != e.ColumnIndex) || (_Exit.Y != e.RowIndex)))
+ {
+ //на всякий случай закрашиваем старую точку входа (если она уже была отмечена ранее) в цвет бордюра
+ dataGridViewField.Rows[_Enter.Y].Cells[_Enter.X].Value = Properties.Resources.border;
+ //задаем новую точку входа
+ _Enter = new Point(e.ColumnIndex, e.RowIndex);
+ //и окрашиваем бордюр в нажатой точке цветом точки входа
+ dataGridViewField.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Properties.Resources.enter;
+ //Действие задаем - никакое
+ _Action = Actions.None;
+ //Включаем кнопку "отметить вход"
+ buttonMarkEnter.Enabled = true;
+ //задаем курсор по умолчанию
+ SetDefaultCuror();
+ }
+ //если дейстиве - указание выхода, то делаем все тоже самое что и со входом
+ if ((_Action == Actions.MarkExit) && ((_Enter.X != e.ColumnIndex) || (_Enter.Y != e.RowIndex)))
+ {
+ dataGridViewField.Rows[_Exit.Y].Cells[_Exit.X].Value = Properties.Resources.border;
+ _Exit = new Point(e.ColumnIndex, e.RowIndex);
+ dataGridViewField.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Properties.Resources.exit;
+
+ _Action = Actions.None;
+ buttonMarkExit.Enabled = true;
+ SetDefaultCuror();
+ }
+ }
+ //если мы нажали по ячейке "игровой" области
+ else
+ {
+ try
+ {
+ //если текущее действие - добавление трубы, то
+ if (_Action == Actions.AdditionPipe)
+ {
+ //задаем добавляемой трубе положение соответственно тому, по какой ячейке поля мы нажали
+ _AddedPipe.Position = new Point(e.ColumnIndex, e.RowIndex);
+ //задаем картинку в ячейке на поле соответсвующую добавляемой трубе
+ dataGridViewField.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = _AddedPipe.Image;
+ //добавляем новую трубу в массив труб на поле
+ _PipesOnField[e.ColumnIndex, e.RowIndex] = _AddedPipe;
+ //ну и удаляем из памяти добавляемую трубу
+ _AddedPipe = null;
+ //действие задаем - ни какое
+ _Action = Actions.None;
+ //устанавливаем курсор по умолчанию
+ SetDefaultCuror();
+ }
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ ///
+ /// Клик по форме
+ ///
+ ///
+ ///
+ private void Form1_MouseClick(object sender, MouseEventArgs e)
+ {
+ //Если нажата правая кнопки мыши этот момент мы добавляли трубу
+ if ((e.Button == System.Windows.Forms.MouseButtons.Right) && (_Action == Actions.AdditionPipe))
+ {
+ //отменяем действие
+ _Action = Actions.None;
+ SetDefaultCuror();
+ }
+ }
+ ///
+ /// Клик по таблице
+ ///
+ ///
+ ///
+ private void dataGridViewField_MouseClick(object sender, MouseEventArgs e)
+ {
+ //Если нажата правая кнопки мыши этот момент мы добавляли трубу
+ if ((e.Button == System.Windows.Forms.MouseButtons.Right) && (_Action == Actions.AdditionPipe))
+ {
+ _Action = Actions.None;
+ Cursor = Cursors.Default;
+ dataGridViewField.Cursor = Cursors.Default;
+ }
+ }
+
+ ///
+ /// Двойной клик по ячейке таблицы
+ ///
+ ///
+ ///
+ private void dataGridViewField_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
+ {
+ //Если мы нечего не делали и в клетке, по которой был клик, есть труба,
+ if ((_Action == Actions.None)&&((object)_PipesOnField[e.ColumnIndex,e.RowIndex] != null))
+ {
+ //удаляем ту трубу
+ _PipesOnField[e.ColumnIndex, e.RowIndex] = null;
+ dataGridViewField.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Properties.Resources.fieldsegment;
+ }
+ }
+
+ private void buttonDepthSolve_Click(object sender, EventArgs e)
+ {
+ Pipe[,] testField = GetCopeField();
+
+ Brainteaser br = new Brainteaser(testField, _ColCount, _RowCount, _Enter, _Exit);
+ bool complete = br.DepthSolve();
+ OutputSolve(br);
+
+ if (complete)
+ {
+ MessageBox.Show("Решено");
+ }
+ else
+ {
+ MessageBox.Show("Не решено");
+ }
+ }
+
+ private void OutputSolve(Brainteaser parTask)
+ {
+ CreateSolveField();
+
+ for (int j = 0; j < _RowCount + 2; j++)
+ {
+
+ for (int i = 0; i < _ColCount + 2; i++)
+ {
+ if ((object)parTask.Field[i, j] != null)
+ {
+ dataGridViewField.Rows[j+_RowCount + 2].Cells[i].Value = parTask.Field[i, j].Image;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Получить копию поля
+ ///
+ ///
+ public Pipe[,] GetCopeField()
+ {
+ Pipe[,] field = new Pipe[_ColCount + 2, _RowCount + 2];
+ for (int i = 0; i < _ColCount + 2; i++)
+ for (int j = 0; j < _RowCount + 2; j++)
+ {
+ if ((object)_PipesOnField[i, j] != null)
+ {
+ field[i, j] = _PipesOnField[i, j].Clone();
+ }
+ }
+
+ return field;
+ }
+
+ private void button2_Click(object sender, EventArgs e)
+ {
+ CreateSolveField();
+ }
+
+
+ }
+}
diff --git a/PipesSolver/FormPipeSolver.resx b/PipesSolver/FormPipeSolver.resx
new file mode 100644
index 0000000..b851021
--- /dev/null
+++ b/PipesSolver/FormPipeSolver.resx
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
\ No newline at end of file
diff --git a/PipesSolver/Orientation.cs b/PipesSolver/Orientation.cs
new file mode 100644
index 0000000..297d040
--- /dev/null
+++ b/PipesSolver/Orientation.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+
+namespace PipesSolver
+{
+ ///
+ /// Класс вектора направления
+ ///
+ public class Orientation
+ {
+ ///
+ /// Направление вверх
+ ///
+ public static Orientation Up
+ { get { return new Orientation(new Point(0, -1)); } }
+ ///
+ /// Направление вниз
+ ///
+ public static Orientation Down
+ { get { return new Orientation(new Point(0, 1)); } }
+ ///
+ /// Направление влево
+ ///
+ public static Orientation Left
+ { get { return new Orientation(new Point(-1, 0)); } }
+ ///
+ /// Направление вправо
+ ///
+ public static Orientation Right
+ { get { return new Orientation(new Point(1, 0)); } }
+
+ ///
+ /// Горизонтальная составляющая вектора направления
+ ///
+ private int _X;
+ ///
+ /// Вертикальная составляющая вектора направления
+ ///
+ private int _Y;
+
+ ///
+ /// Массив направлений по умолчанию(вверх, вниз, влево, вправо. Используются для поворота вектора
+ ///
+ private List _Orientations = new List();
+
+ ///
+ /// Конструктор класса
+ ///
+ private Orientation()
+ {
+ _Orientations.Add(new Point(1, 0));
+ _Orientations.Add(new Point(0, 1));
+ _Orientations.Add(new Point(-1, 0));
+ _Orientations.Add(new Point(0, -1));
+
+ _X = _Orientations[0].X;
+ _Y = _Orientations[0].Y;
+ }
+ ///
+ /// Конструктор класса
+ ///
+ /// Горизонтальная составляющая вектора направления
+ /// Вертикальная составляющая вектора направления
+ private Orientation(int parX, int parY)
+ {
+ _Orientations.Add(new Point(1, 0));
+ _Orientations.Add(new Point(0, 1));
+ _Orientations.Add(new Point(-1, 0));
+ _Orientations.Add(new Point(0, -1));
+
+ _X = parX;
+ _Y = parY;
+ }
+
+ ///
+ /// Конструктор формы
+ ///
+ /// вектор направления
+ private Orientation(Point parVector)
+ {
+ _Orientations.Add(new Point(1, 0));
+ _Orientations.Add(new Point(0, 1));
+ _Orientations.Add(new Point(-1, 0));
+ _Orientations.Add(new Point(0, -1));
+ _X = parVector.X;
+ _Y = parVector.Y;
+ }
+ ///
+ /// Повернуть вектор направления
+ ///
+ ///
+ public void Rotate(bool parClockwise)
+ {
+
+ int i = 0;
+ //Если поворачиваем по часовой стрелке
+ if (parClockwise)
+ {
+ //Перебираем шаблонные векторы в прямую сторону
+ for (i = 0; i < _Orientations.Count; i++)
+ {
+ //Как только нашли тот, что соответствует текущему
+ //выходим из цикла и запоминаем индекс шаблонного вектора
+ if ((_Orientations[i].X == _X) && (_Orientations[i].Y == _Y))
+ break;
+ }
+ //если индекс оказался последним в массиве шаблонов, то следующим будет тот, что в начале массива шаблонов
+ if (i == _Orientations.Count - 1)
+ i = 0;
+ //иначе просто увеличиваем индекс, получая следующего по часовой стрелке вектора
+ else
+ i++;
+
+ }
+ //аналогичным образом просматриваем если поворот против часовой
+ else
+ {
+ //индексы смотрим в обратном порядке
+ for (i = 0; i < _Orientations.Count; i--)
+ {
+ if ((_Orientations[i].X == _X) && (_Orientations[i].Y == _Y))
+ break;
+ }
+ if (i == 0)
+ i = _Orientations.Count - 1;
+ else
+ i--;
+ }
+
+ _X = _Orientations[i].X;
+ _Y = _Orientations[i].Y;
+ }
+
+ ///
+ /// создаем копию текущего объекта
+ ///
+ ///
+ public Orientation Clone()
+ {
+ return new Orientation(_X, _Y);
+ }
+ ///
+ /// перегруженный оператор минус
+ ///
+ ///
+ ///
+ public static Orientation operator -(Orientation parOrientation)
+ {
+ return new Orientation(new Point(-parOrientation.X, -parOrientation.Y));
+ }
+ ///
+ /// перегруженный оператор равно
+ ///
+ ///
+ ///
+ ///
+ public static bool operator ==(Orientation parFirstOrientation, Orientation parSecondOrientation)
+ {
+ if ((parFirstOrientation.X == parSecondOrientation.X) && (parFirstOrientation.Y == parSecondOrientation.Y))
+ return true;
+ else
+ return false;
+ }
+ ///
+ /// перегруженный оператор не равно
+ ///
+ ///
+ ///
+ ///
+ public static bool operator !=(Orientation parFirstOrientation, Orientation parSecondOrientation)
+ {
+ if (!((parFirstOrientation.X == parSecondOrientation.X) && (parFirstOrientation.Y == parSecondOrientation.Y)))
+ return true;
+ else
+ return false;
+ }
+
+
+ ///
+ /// Горизонтальная составляющая вектора направления
+ ///
+ public int X
+ { get { return _X; } }
+ ///
+ /// Вертикальная составляющая вектора направления
+ ///
+ public int Y
+ { get { return _Y; } }
+
+ }
+}
diff --git a/PipesSolver/Pipe.cs b/PipesSolver/Pipe.cs
new file mode 100644
index 0000000..e10b46d
--- /dev/null
+++ b/PipesSolver/Pipe.cs
@@ -0,0 +1,206 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+
+namespace PipesSolver
+{
+ ///
+ /// Класс трубы
+ ///
+ public class Pipe
+ {
+ ///
+ /// Массив шаблонов труб
+ ///
+ public static List TemplatePipes = new List {
+ new Pipe(new Point(0, 0), Orientation.Up, Orientation.Right, Properties.Resources.angle1),
+ new Pipe(new Point(0, 0), Orientation.Right, Orientation.Down, Properties.Resources.angle2),
+ new Pipe(new Point(0, 0), Orientation.Down, Orientation.Left, Properties.Resources.angle3),
+ new Pipe(new Point(0, 0), Orientation.Left, Orientation.Up, Properties.Resources.angle4),
+ new Pipe(new Point(0, 0), Orientation.Up, Orientation.Down, Properties.Resources.direct1),
+ new Pipe(new Point(0, 0), Orientation.Left, Orientation.Right, Properties.Resources.direct2)
+ };
+
+ ///
+ /// Первое отверстие трубы
+ ///
+ private Orientation _FirstHole;
+ ///
+ /// Второе отверстие трубы
+ ///
+ private Orientation _SecondHole;
+ ///
+ /// Положение трубы на поле
+ ///
+ private Point _Position;
+ ///
+ /// Изображение трубы
+ ///
+ private Bitmap _Image;
+ ///
+ /// Является ли частью рассматриваемого пути
+ ///
+ private bool _PartOfPath;
+
+ ///
+ /// Конструктор класса
+ ///
+ /// Положение на поле
+ /// Первое отверстие
+ /// Второе отверстие
+ /// Изображение трубы
+ public Pipe(Point parPosition, Orientation parFirstHole, Orientation parSecondHole, Bitmap parImage)
+ {
+ _Position = parPosition;
+ _FirstHole = parFirstHole;
+ _SecondHole = parSecondHole;
+ _Image = parImage;
+ _PartOfPath = false;
+ }
+
+ ///
+ /// Создание копии текущего объекта
+ ///
+ ///
+ public Pipe Clone()
+ {
+ return new Pipe(new Point(_Position.X, _Position.Y), _FirstHole.Clone(), _SecondHole.Clone(), _Image);
+ }
+
+ ///
+ /// Поворот трубы
+ ///
+ /// по часовой(true) или против часовой(false)
+ public void Rotate(bool parClockwise)
+ {
+ //поворачиваем первое и второе отверстие
+ _FirstHole.Rotate(parClockwise);
+ _SecondHole.Rotate(parClockwise);
+
+ //просматриваем список шаблонов труб
+ for (int i = 0; i < TemplatePipes.Count; i++)
+ {
+ //как только среди шаблонов находим с отверстиями, ориентированными также как у текущего объекта(трубы)
+ if (((_FirstHole == TemplatePipes[i].FirstHole)&&(_SecondHole == TemplatePipes[i].SecondHole))
+ ||((_FirstHole == TemplatePipes[i].SecondHole)&&(_SecondHole == TemplatePipes[i].FirstHole)))
+ {
+ //меняем картинку текущего объекта(трубы) на картинку найденного шаблона
+ _Image = TemplatePipes[i].Image;
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Перегруженный оператор сравнения
+ ///
+ ///
+ ///
+ ///
+ public static bool operator == (Pipe parFirstPipe, Pipe parSecondPipe)
+ {
+ if ((parFirstPipe.FirstHole.X == parSecondPipe.FirstHole.X) && (parFirstPipe.FirstHole.Y == parSecondPipe.FirstHole.Y) &&
+ (parFirstPipe.SecondHole.X == parSecondPipe.SecondHole.X) && (parFirstPipe.SecondHole.X == parSecondPipe.SecondHole.X))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Перегруженный оператор сравнения
+ ///
+ ///
+ ///
+ ///
+ public static bool operator != (Pipe parFirstPipe, Pipe parSecondPipe)
+ {
+ if ((object)parSecondPipe == null)
+ if ((object)parFirstPipe == null)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ else
+ if (!(parFirstPipe.FirstHole.X == parSecondPipe.FirstHole.X) && (parFirstPipe.FirstHole.Y == parSecondPipe.FirstHole.Y) &&
+ (parFirstPipe.SecondHole.X == parSecondPipe.SecondHole.X) && (parFirstPipe.SecondHole.X == parSecondPipe.SecondHole.X))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Поворот трубы ближайшим отверстием по направлению к заданной точке
+ ///
+ ///
+ public void RotateTo(Point parEnterPoint)
+ {
+ //поворачиваем трубу, не долго думая
+ Rotate(true);
+ //пока
+ while (true)
+ {
+ //первое или второе отверстие не станут смотреть в сторону заданной точки
+ if (((parEnterPoint.X == _Position.X + _FirstHole.X) && (parEnterPoint.Y == _Position.Y + _FirstHole.Y)) ||
+ ((parEnterPoint.X == _Position.X + _SecondHole.X) && (parEnterPoint.Y == _Position.Y + _SecondHole.Y)))
+ {
+ //если повернули как надо, выходим из цикла
+ break;
+ }
+ //иначе
+ else
+ {
+ //продолжаем поворачивать
+ Rotate(true);
+ }
+ }
+ }
+
+ ///
+ /// Первое отверстие трубы
+ ///
+ public Orientation FirstHole
+ { get { return _FirstHole; } }
+ ///
+ /// Второе отверстие трубы
+ ///
+ public Orientation SecondHole
+ { get { return _SecondHole; } }
+ ///
+ /// Положение трубы на поле
+ ///
+ public Point Position
+ {
+ get { return _Position; }
+ set { _Position = value; }
+ }
+ ///
+ /// Изображение трубы
+ ///
+ public Bitmap Image
+ {
+ get { return _Image; }
+ set { _Image = value; }
+ }
+ ///
+ /// Является ли труба частью
+ ///
+ public bool PartOfPath
+ {
+ get { return _PartOfPath; }
+ set { _PartOfPath = value; }
+ }
+ }
+}
diff --git a/PipesSolver/PipeListCircle.cs b/PipesSolver/PipeListCircle.cs
new file mode 100644
index 0000000..50744b3
--- /dev/null
+++ b/PipesSolver/PipeListCircle.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PipesSolver
+{
+ class PipeListCircle
+ {
+ private List _Pipes;
+ private int _Pointer;
+
+ public PipeListCircle()
+ {
+ _Pipes = new List();
+ _Pointer = 0;
+
+ }
+
+ public void Add(Pipe parNewPipe)
+ {
+ _Pipes.Add(parNewPipe);
+ }
+
+ public Pipe Next()
+ {
+ Pipe resPipe = _Pipes[_Pointer];
+ _Pointer++;
+
+ if (_Pointer >= _Pipes.Count)
+ _Pointer = 0;
+
+ return resPipe;
+ }
+
+ }
+}
diff --git a/PipesSolver/PipesSolver.csproj b/PipesSolver/PipesSolver.csproj
new file mode 100644
index 0000000..85a49d6
--- /dev/null
+++ b/PipesSolver/PipesSolver.csproj
@@ -0,0 +1,130 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {6AF1A9B0-979C-47E3-A8E1-45C6F3DFF969}
+ WinExe
+ Properties
+ PipesSolver
+ PipesSolver
+ v4.0
+ Client
+ 512
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ FormPipeSolver.cs
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ FormPipeSolver.cs
+
+
+ ResXFileCodeGenerator
+ Designer
+ Resources.Designer.cs
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PipesSolver/Program.cs b/PipesSolver/Program.cs
new file mode 100644
index 0000000..5a08a29
--- /dev/null
+++ b/PipesSolver/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace PipesSolver
+{
+ static class Program
+ {
+ ///
+ /// Главная точка входа для приложения.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new FormPipeSolver());
+ }
+ }
+}
diff --git a/PipesSolver/Properties/AssemblyInfo.cs b/PipesSolver/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0fc5721
--- /dev/null
+++ b/PipesSolver/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("PipesSolver")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PipesSolver")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
+// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("152d4195-dc0b-40d5-bffa-623c9cf14c2e")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер построения
+// Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию,
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PipesSolver/Properties/Resources.Designer.cs b/PipesSolver/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..faca552
--- /dev/null
+++ b/PipesSolver/Properties/Resources.Designer.cs
@@ -0,0 +1,163 @@
+//------------------------------------------------------------------------------
+//
+// Этот код создан программой.
+// Исполняемая версия:4.0.30319.18051
+//
+// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
+// повторной генерации кода.
+//
+//------------------------------------------------------------------------------
+
+namespace PipesSolver.Properties {
+ using System;
+
+
+ ///
+ /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
+ ///
+ // Этот класс создан автоматически классом StronglyTypedResourceBuilder
+ // с помощью такого средства, как ResGen или Visual Studio.
+ // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
+ // с параметром /str или перестройте свой проект VS.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PipesSolver.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Перезаписывает свойство CurrentUICulture текущего потока для всех
+ /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap angle1 {
+ get {
+ object obj = ResourceManager.GetObject("angle1", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap angle2 {
+ get {
+ object obj = ResourceManager.GetObject("angle2", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap angle3 {
+ get {
+ object obj = ResourceManager.GetObject("angle3", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap angle4 {
+ get {
+ object obj = ResourceManager.GetObject("angle4", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap border {
+ get {
+ object obj = ResourceManager.GetObject("border", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap direct1 {
+ get {
+ object obj = ResourceManager.GetObject("direct1", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap direct2 {
+ get {
+ object obj = ResourceManager.GetObject("direct2", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap enter {
+ get {
+ object obj = ResourceManager.GetObject("enter", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap exit {
+ get {
+ object obj = ResourceManager.GetObject("exit", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Поиск локализованного ресурса типа System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap fieldsegment {
+ get {
+ object obj = ResourceManager.GetObject("fieldsegment", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/PipesSolver/Properties/Resources.resx b/PipesSolver/Properties/Resources.resx
new file mode 100644
index 0000000..2b11e58
--- /dev/null
+++ b/PipesSolver/Properties/Resources.resx
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\angle1.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\angle2.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\angle3.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\angle4.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\border.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\direct1.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\direct2.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\enter.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\output.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\fieldsegment.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/PipesSolver/Properties/Settings.Designer.cs b/PipesSolver/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..90e94d8
--- /dev/null
+++ b/PipesSolver/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18051
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PipesSolver.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/PipesSolver/Properties/Settings.settings b/PipesSolver/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/PipesSolver/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/PipesSolver/Resources/angle1.gif b/PipesSolver/Resources/angle1.gif
new file mode 100644
index 0000000..8f71675
Binary files /dev/null and b/PipesSolver/Resources/angle1.gif differ
diff --git a/PipesSolver/Resources/angle2.gif b/PipesSolver/Resources/angle2.gif
new file mode 100644
index 0000000..37fcb1e
Binary files /dev/null and b/PipesSolver/Resources/angle2.gif differ
diff --git a/PipesSolver/Resources/angle3.gif b/PipesSolver/Resources/angle3.gif
new file mode 100644
index 0000000..ca46615
Binary files /dev/null and b/PipesSolver/Resources/angle3.gif differ
diff --git a/PipesSolver/Resources/angle4.gif b/PipesSolver/Resources/angle4.gif
new file mode 100644
index 0000000..8ade947
Binary files /dev/null and b/PipesSolver/Resources/angle4.gif differ
diff --git a/PipesSolver/Resources/border.gif b/PipesSolver/Resources/border.gif
new file mode 100644
index 0000000..98e65ba
Binary files /dev/null and b/PipesSolver/Resources/border.gif differ
diff --git a/PipesSolver/Resources/direct1.gif b/PipesSolver/Resources/direct1.gif
new file mode 100644
index 0000000..8925a27
Binary files /dev/null and b/PipesSolver/Resources/direct1.gif differ
diff --git a/PipesSolver/Resources/direct2.gif b/PipesSolver/Resources/direct2.gif
new file mode 100644
index 0000000..270f1e6
Binary files /dev/null and b/PipesSolver/Resources/direct2.gif differ
diff --git a/PipesSolver/Resources/enter.gif b/PipesSolver/Resources/enter.gif
new file mode 100644
index 0000000..7d259ac
Binary files /dev/null and b/PipesSolver/Resources/enter.gif differ
diff --git a/PipesSolver/Resources/fieldsegment.gif b/PipesSolver/Resources/fieldsegment.gif
new file mode 100644
index 0000000..a39cc36
Binary files /dev/null and b/PipesSolver/Resources/fieldsegment.gif differ
diff --git a/PipesSolver/Resources/input.gif b/PipesSolver/Resources/input.gif
new file mode 100644
index 0000000..7d259ac
Binary files /dev/null and b/PipesSolver/Resources/input.gif differ
diff --git a/PipesSolver/Resources/output.gif b/PipesSolver/Resources/output.gif
new file mode 100644
index 0000000..08770e4
Binary files /dev/null and b/PipesSolver/Resources/output.gif differ
diff --git a/PipesSolver/Resources/testimage.gif b/PipesSolver/Resources/testimage.gif
new file mode 100644
index 0000000..920e859
Binary files /dev/null and b/PipesSolver/Resources/testimage.gif differ
diff --git a/PipesSolver/SolutionNode.cs b/PipesSolver/SolutionNode.cs
new file mode 100644
index 0000000..649e639
--- /dev/null
+++ b/PipesSolver/SolutionNode.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PipesSolver
+{
+ class SolutionNode
+ {
+ }
+}
diff --git a/PipesSolver/SolutionThree.cs b/PipesSolver/SolutionThree.cs
new file mode 100644
index 0000000..a09231e
--- /dev/null
+++ b/PipesSolver/SolutionThree.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+
+
+namespace PipesSolver
+{
+ ///
+ /// Класс дерева решений
+ ///
+ class SolutionThree
+ {
+ ///
+ /// Дочерние узлы дерева
+ ///
+ private List _ChildNodes;
+ ///
+ /// Родительский узел
+ ///
+ private SolutionThree _Root;
+ ///
+ /// Уровень узла
+ ///
+ private int _Level;
+ ///
+ /// Труба,выбранная для хода и уже повернутая в нужном направлении
+ ///
+ private Pipe _Pipe;
+ ///
+ /// Точка входа
+ ///
+ private Point _Enter;
+
+ ///
+ /// Конструктор
+ ///
+ /// Родиельский узел
+ /// Уровень
+ public SolutionThree(Pipe parCurrentPipe, SolutionThree parRoot, Point parEnter, int parLevel)
+ {
+ _Root = parRoot;
+ _Level = parLevel;
+ _Enter = parEnter;
+ _ChildNodes = new List();
+ }
+
+ ///
+ /// Добавить дочерний узел в дерево
+ ///
+ ///
+ ///
+ public void AddChildNode(Pipe parCurrentPipe, Point parEneter)
+ {
+ _ChildNodes.Add(new SolutionThree(parCurrentPipe, this, parEneter, _Level++));
+ }
+
+ ///
+ /// Удалить дочерний узел с указанным индексом
+ ///
+ /// Индекс удаляемого дочернего узла
+ public void DeleteChildNode(int parChildIndex)
+ {
+ _ChildNodes.RemoveAt(parChildIndex);
+ }
+
+
+ ///
+ /// Дочерние узлы дерева
+ ///
+ public List ChildNodes
+ {
+ get { return _ChildNodes; }
+ }
+ ///
+ /// Родительский узел
+ ///
+ private SolutionThree Root
+ {
+ get { return _Root; }
+ }
+ ///
+ /// Уровень узла
+ ///
+ private int Level
+ {
+ get { return _Level; }
+ }
+ ///
+ /// Труба,выбранная для хода и уже повернутая в нужном направлении
+ ///
+ private Pipe Pipe
+ {
+ get { return _Pipe; }
+ }
+ ///
+ /// Точка входа
+ ///
+ private Point Enter
+ {
+ get { return _Enter; }
+ }
+
+ }
+}