From bbc5f6642040571a0d0714ab9a1e2693f4d36511 Mon Sep 17 00:00:00 2001 From: packpacka Date: Wed, 30 Oct 2013 22:25:15 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81?= =?UTF-8?q?=20=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=87=D0=B8=D0=B9=20=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=B2=20=D0=B3=D0=BB=D1=83=D0=B1=D0=B8=D0=BD=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 22 + .gitignore | 215 +++++++++ PipesSolver.sln | 20 + PipesSolver/Brainteaser.cs | 225 +++++++++ PipesSolver/FormPipeSolver.Designer.cs | 323 +++++++++++++ PipesSolver/FormPipeSolver.cs | 468 +++++++++++++++++++ PipesSolver/FormPipeSolver.resx | 138 ++++++ PipesSolver/Orientation.cs | 194 ++++++++ PipesSolver/Pipe.cs | 206 ++++++++ PipesSolver/PipeListCircle.cs | 37 ++ PipesSolver/PipesSolver.csproj | 130 ++++++ PipesSolver/Program.cs | 21 + PipesSolver/Properties/AssemblyInfo.cs | 36 ++ PipesSolver/Properties/Resources.Designer.cs | 163 +++++++ PipesSolver/Properties/Resources.resx | 151 ++++++ PipesSolver/Properties/Settings.Designer.cs | 30 ++ PipesSolver/Properties/Settings.settings | 7 + PipesSolver/Resources/angle1.gif | Bin 0 -> 1043 bytes PipesSolver/Resources/angle2.gif | Bin 0 -> 1019 bytes PipesSolver/Resources/angle3.gif | Bin 0 -> 1030 bytes PipesSolver/Resources/angle4.gif | Bin 0 -> 1042 bytes PipesSolver/Resources/border.gif | Bin 0 -> 1886 bytes PipesSolver/Resources/direct1.gif | Bin 0 -> 1065 bytes PipesSolver/Resources/direct2.gif | Bin 0 -> 1034 bytes PipesSolver/Resources/enter.gif | Bin 0 -> 2105 bytes PipesSolver/Resources/fieldsegment.gif | Bin 0 -> 942 bytes PipesSolver/Resources/input.gif | Bin 0 -> 2105 bytes PipesSolver/Resources/output.gif | Bin 0 -> 2260 bytes PipesSolver/Resources/testimage.gif | Bin 0 -> 1190 bytes PipesSolver/SolutionNode.cs | 11 + PipesSolver/SolutionThree.cs | 106 +++++ 31 files changed, 2503 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 PipesSolver.sln create mode 100644 PipesSolver/Brainteaser.cs create mode 100644 PipesSolver/FormPipeSolver.Designer.cs create mode 100644 PipesSolver/FormPipeSolver.cs create mode 100644 PipesSolver/FormPipeSolver.resx create mode 100644 PipesSolver/Orientation.cs create mode 100644 PipesSolver/Pipe.cs create mode 100644 PipesSolver/PipeListCircle.cs create mode 100644 PipesSolver/PipesSolver.csproj create mode 100644 PipesSolver/Program.cs create mode 100644 PipesSolver/Properties/AssemblyInfo.cs create mode 100644 PipesSolver/Properties/Resources.Designer.cs create mode 100644 PipesSolver/Properties/Resources.resx create mode 100644 PipesSolver/Properties/Settings.Designer.cs create mode 100644 PipesSolver/Properties/Settings.settings create mode 100644 PipesSolver/Resources/angle1.gif create mode 100644 PipesSolver/Resources/angle2.gif create mode 100644 PipesSolver/Resources/angle3.gif create mode 100644 PipesSolver/Resources/angle4.gif create mode 100644 PipesSolver/Resources/border.gif create mode 100644 PipesSolver/Resources/direct1.gif create mode 100644 PipesSolver/Resources/direct2.gif create mode 100644 PipesSolver/Resources/enter.gif create mode 100644 PipesSolver/Resources/fieldsegment.gif create mode 100644 PipesSolver/Resources/input.gif create mode 100644 PipesSolver/Resources/output.gif create mode 100644 PipesSolver/Resources/testimage.gif create mode 100644 PipesSolver/SolutionNode.cs create mode 100644 PipesSolver/SolutionThree.cs 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 0000000000000000000000000000000000000000..8f716757ca126660353bbd33e376ceca8e046425 GIT binary patch literal 1043 zcmW-fU5F4w6opUVgB7M!L_uU>zdJry7s3eX*ZkStC~K+*LH3~=1lqEdNl;7}^-v2z zAsoo1G)jgLD@t>POk@$dYE}bNRC9LKoT;L4cU>29LPceilI0PQ36G%Ks8iH zC2F7w4QPhuXhaJ%^}iv593m7@zjSRgxPgY~HA}E$mfR98g(X>rWwY#-X*n#*3apqF zw?ZpnMOI$6hyHo9)(dNilQQ_MfIqR8c`Ju(JY!r zW3-5-5JDF65JM5tToAe&9ZB!27kd;EluXH$s1!<4hO#NUGL=JFDo`;MSD{L%NENE4 z>Z()?RjEPE)Le~fp*APhgVx>d$ot&q#m}ey{5Jnj{Bz;etM|P3^((k^VEvIjBZsyw zTC(=t`6u3A`Nrk;^bcD;nLadr?R{6AS-tLqHE&(NVq*Q8Tc2FDZCToX_{z_2Jj6>j z&K~9?PYq8jcS>in@`;% ze#7+C!0CH8pWSlX@WE|^Ymc29vzc!O?|NZs>HeF3|88u>&Q0~j&wu`Y_lC*s!;@c} tI=S!JKYlqnx%c$12e)3l_`w7F{+d4WcG__4z?Xl|e7kdS@imKZ=l?Lm`5XWM literal 0 HcmV?d00001 diff --git a/PipesSolver/Resources/angle2.gif b/PipesSolver/Resources/angle2.gif new file mode 100644 index 0000000000000000000000000000000000000000..37fcb1e9fdc45089c6a508fcb5c95590bbbe9192 GIT binary patch literal 1019 zcmW-fPlymi6vn@(g9$}YLdOlzyJpVARr_l8ImIf5|M-qWJ7l3Kqj(KfMO_)5-3CwDo_p8 zQ3I8zLIawiIa;6*P5p1kAcq1X)GuAz3~mSmd(9FonI*RrmS{ z*oj0!B#Y#cA`&AhG9p`Kj~tO1Sy2$hqIi^u!YGQ0s20_uMpQ;sG(@v#9xb9VnnDO! z$U_lgsMGIe8{tF{>}D{5$(Woen8+k%FdMTo2Q!()0v2O&mS7=^Six$n&Kj&_6&u)$ z&DnyDY@$FJ1f$Mn}^7>ct*~1SL~)rBI@hl%Z_Ot{lo#mI_o%#Z^LuDpG~2 zsk&;YQdMeDGc{KWHL5L&^`LdPJMupFlK4{Um$qfs@z=i_Q2{F>(<$GA6*%LY{%T8p_z}bP7J*M z`_0*zsrhm2UA}Vo{K@Yp2jAa5GI#!yh2tBJ3?E+p=fmyP=E?0p&uvaWoym{vUAf^} z+A{6)dp4fBKi&9z%jpaM|1!k42Hzh0eqMxpnc%Z=a2S@#Bf74$O?qKmN?c`|i57XXnC^O=B-TeelhfIkj!-!>52!eJuw1^rbGr@{Wh{=isQ4tf8LJ~bh z#x?E7ZBr%$-OY!Htc>vQZcD@{(T_p9FZIw{Aw{Rzorhs&F3h?2J7;9ZRf%P1PpK>03iX1NQUG{fh1%g6WNd*Igo_{6rvc4qXddjfl5?E zb<{u=8qkPlXpRVHFo400%-e(BmIjBp})jR{O-GA3sVCNYDV%*O1@!7LWAki}S> zC0N7?RbGBd;1&WkWP6gHb=ws7h1~)`+%MvWnl38*~VM&%@nU>A6 zTMo;z0xPs)R@_QhkyTiwRkP|=!>X*o8m*Z%w-(l9f{7+GxhYH?K_^a!IouJQh$ncW zC-dZl?Q*o70kt$TF zYO1aps#1d*)lALRLTy2;2d%r^k@vY5#TQe*xGnt+e_uQ_diedXwlBS6`TCQGKlpm* z<=5T6cl5~qZ+2bDO+TGHGI8RKYwmq*Xl&}kQ*Yk*a9w|DYVyq6w>))v@7VN5Gw-b0 z_U)1{rw`1&chB}qhU?aY-%X6ZIJoBYC(C9hADFo6)#XQjf3U8desX5rbLrf{4PUIh zG_73r!_>&^{_FQ_J@m-YEw3DZ{f})o|9s%tKljXheEUu3k8Qs7qQBDfm?z?k-)44+r9os$p h&)nu8kFNRU?7q+Dww(Wb?7zXQUz!`=F))C;{s-n^^A!L9 literal 0 HcmV?d00001 diff --git a/PipesSolver/Resources/angle4.gif b/PipesSolver/Resources/angle4.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ade9472008c8fd7b5ccc97ea1bf948e85daf6a6 GIT binary patch literal 1042 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 RpI<#ZGS>I<`yUtF`VW!(`V0U7 literal 0 HcmV?d00001 diff --git a/PipesSolver/Resources/direct2.gif b/PipesSolver/Resources/direct2.gif new file mode 100644 index 0000000000000000000000000000000000000000..270f1e6a8b6dbcd420b1256ae1590f6d666de71c GIT binary patch literal 1034 zcmW+!O^6Ug7=6|TT0uck9X2Yu$d1V7cTv0)qU%bEw9dhBgA%^O9zxh!>JUr`3Wjy? z5U&<9x2$Fp*I&Y*KM8gHwuNd~sGuN%LZn*}1g}}=@G&#rFzo+|6Bu20g zctm&X*t~0O(-S*4uUk8O>xvcq>feE0|HB&ewfyYh@&*PtKp+4i0m+aYiAaGYWFQ-| zBNI80g#r{qaTKBiico=SsE$h1KouI$49(Gq7HH~!Lk2lSD4>4m*k*784bgj+V96}G zC0YtgvJA^+*)7v@Se6x7F)MC`R>F#`!m3$ytF#(cWewKMnp>l_uqG2sW^xlvVd^~k z*yeBt9noodf+zFjp6Dq&$um5gXZK9c;aOhb#k{x|dI>M`3a{qXz0zxVl{a`ZZ|;rW z!kb)hnaf>tg{w=@6*s~O644c50+TU06PbcZ%wRTVXC`wniv=vk;w)qd7O{fWSe=!u z!74Ve8Jn|_E!aeXGRi4ZL3Q=J*%t5s1JTWhgh&?2BQa7$Qe;H7$R3%IBeJ3(ibe4# zj1o~46;Um!M`hHAs%VI2(L5TXMKpyFvXF-uijbCr(B0^gbY8vLqmZCvO0GnuP?9o~ zP1%*H9LiFGimA8?RYFCoP&HLorD~{34Qi(5YE%ogWw0K!?sk{F&wUg8X6kR2l|SI0 zRfAjSj(xR%EPXuZkyhE`uI1mKVTC-UpYN<`OSwn9U2@x^ZwN%tH=l36t e%|5em@%;6rxxLqpZvX7Ujh{Z9y#LOX*!VwL*zk}5 literal 0 HcmV?d00001 diff --git a/PipesSolver/Resources/enter.gif b/PipesSolver/Resources/enter.gif new file mode 100644 index 0000000000000000000000000000000000000000..7d259ac5a78d2094181d7f6326f0ce6d4a14714b GIT binary patch literal 2105 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 b`o&y!2s-_;J*IHk&V2kyZ*G%@1}ykL#h5Ob literal 0 HcmV?d00001 diff --git a/PipesSolver/Resources/testimage.gif b/PipesSolver/Resources/testimage.gif new file mode 100644 index 0000000000000000000000000000000000000000..920e859b44ac407f7e904747a372b6df770b01b3 GIT binary patch literal 1190 zcmXYweQ4KJ6vm&-bStRo%ol9p@Fn&3;yS}L`=brf-@?ej?uc6DFpiccAz5UwZVXnr ze2cUWQ&=+AyjX1rQ4*1>eub7$Oh}kr4$^5e*4Q zgv3aKq)3*%4I>!C1g5a;00I%1AOy{7REkCkl!y{j5=u(R$UsJ9OeSPXmg&gGCI&Nvp_wdpU`Onjov>4O#vbg6 zJ+l|~%HBAD194yu!a+G0M{p#L%uzThN8pU?VnW6EH&%#(RGFXq*} zS%3wyz!t=US}=>SNEX?mSX7H<36{tbTM|oZX}nn$w9M@cc{caI&HvARwv}I*cmr?^ zca2|-{|OWs#)|LAb+?~rE-GEpaI*V@uiq${_wd17&*5)dXVP>1C-=>*xDnO)lV^Gg zU#+dEjtxhC>8Lrd^oiqz_ZM@n(rw&UxAQ_=HrUFpDMS6;kWEl-th-F2bwPJg_3v~NMt{qt*D zc8uM8v8}#w{fYb9CX5t+*1i7A-DPtIR?aH#Ikn+@e(#%?E1tn?<$qpoC^>fGFmmth z{^HWMTs}@dwrtCeEziH+)%e}&wyT4iS{GGqKKl3Qr)PhhvH6oTch}DP{^#ixGxijh zHFn;`X@iW;HRb)e+-=d)z$SkjaFTqd58~Qxc+Tg|s_l!K<+?75Ye0gf;{=t^Hz27v{l^@8> zSyz^?9NK!z>9N_ZOY@6{->&T2G`ws1xvt^e5B@bWyyu}wiwk>KO@FqqFSqbW;hiZr IO~lH70JxGkk^lez literal 0 HcmV?d00001 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; } + } + + } +}