// Sudoku problem solver
// programmer : mostafa vatanpoor 
// email : mostafa_vtp@yahoo.com
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace sudoku
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		DataGridCell[] history=new DataGridCell[81];
		int position=-1;
		bool findFirst;
		Thread calcThread;
		//DataGrid dataGrid2=new DataGrid();
		//-----------------------------------------------------------------------
		private System.Windows.Forms.DataGrid dataGrid1;
		private System.Windows.Forms.Button Find;
		private System.Windows.Forms.Button Next;
		private System.Windows.Forms.Button Save;
		private System.Windows.Forms.Button btnLoad;
		private System.Windows.Forms.TextBox textBox1;
		private System.Windows.Forms.Button BtnReset;
		private System.Windows.Forms.Button btnStop;
		private System.ComponentModel.IContainer components;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.Next = new System.Windows.Forms.Button();
			this.dataGrid1 = new System.Windows.Forms.DataGrid();
			this.Find = new System.Windows.Forms.Button();
			this.Save = new System.Windows.Forms.Button();
			this.btnLoad = new System.Windows.Forms.Button();
			this.textBox1 = new System.Windows.Forms.TextBox();
			this.BtnReset = new System.Windows.Forms.Button();
			this.btnStop = new System.Windows.Forms.Button();
			((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
			this.SuspendLayout();
			// 
			// Next
			// 
			this.Next.Location = new System.Drawing.Point(176, 16);
			this.Next.Name = "Next";
			this.Next.TabIndex = 1;
			this.Next.Text = "Next";
			this.Next.Click += new System.EventHandler(this.Next_Click);
			// 
			// dataGrid1
			// 
			this.dataGrid1.BackgroundColor = System.Drawing.Color.DarkGray;
			this.dataGrid1.CaptionVisible = false;
			this.dataGrid1.DataMember = "";
			this.dataGrid1.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(178)));
			this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
			this.dataGrid1.Location = new System.Drawing.Point(32, 64);
			this.dataGrid1.Name = "dataGrid1";
			this.dataGrid1.PreferredColumnWidth = 30;
			this.dataGrid1.PreferredRowHeight = 30;
			this.dataGrid1.Size = new System.Drawing.Size(328, 304);
			this.dataGrid1.TabIndex = 2;
			// 
			// Find
			// 
			this.Find.Location = new System.Drawing.Point(40, 16);
			this.Find.Name = "Find";
			this.Find.TabIndex = 3;
			this.Find.Text = "Find First";
			this.Find.Click += new System.EventHandler(this.Find_Click);
			// 
			// Save
			// 
			this.Save.Location = new System.Drawing.Point(40, 384);
			this.Save.Name = "Save";
			this.Save.TabIndex = 4;
			this.Save.Text = "Save";
			this.Save.Click += new System.EventHandler(this.Save_Click);
			// 
			// btnLoad
			// 
			this.btnLoad.Location = new System.Drawing.Point(256, 384);
			this.btnLoad.Name = "btnLoad";
			this.btnLoad.TabIndex = 5;
			this.btnLoad.Text = "Load";
			this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
			// 
			// textBox1
			// 
			this.textBox1.Location = new System.Drawing.Point(136, 384);
			this.textBox1.Name = "textBox1";
			this.textBox1.TabIndex = 6;
			this.textBox1.Text = "temp.xml";
			// 
			// BtnReset
			// 
			this.BtnReset.Location = new System.Drawing.Point(312, 16);
			this.BtnReset.Name = "BtnReset";
			this.BtnReset.TabIndex = 7;
			this.BtnReset.Text = "Reset";
			this.BtnReset.Click += new System.EventHandler(this.BtnReset_Click);
			// 
			// btnStop
			// 
			this.btnStop.Location = new System.Drawing.Point(376, 96);
			this.btnStop.Name = "btnStop";
			this.btnStop.TabIndex = 8;
			this.btnStop.Text = "Stop";
			this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
			this.ClientSize = new System.Drawing.Size(472, 429);
			this.Controls.Add(this.btnStop);
			this.Controls.Add(this.BtnReset);
			this.Controls.Add(this.textBox1);
			this.Controls.Add(this.btnLoad);
			this.Controls.Add(this.Save);
			this.Controls.Add(this.Find);
			this.Controls.Add(this.dataGrid1);
			this.Controls.Add(this.Next);
			this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(178)));
			this.Name = "Form1";
			this.Text = "Sudoku";
			this.Load += new System.EventHandler(this.Form1_Load);
			((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		void find()
		{
			if(findFirst)
			{
				for(int i=0;i<=position;i++)
				{
					dataGrid1[history[i]]="";
				}
				bool found=false;
				for(int i=0;i<9;i++)
				{
					for(int j=0;j<9;j++)
					{
						if((string)dataGrid1[i,j]=="")
						{
							history[0]=new DataGridCell(i,j);
							dataGrid1[history[0]]="0";
							position=0;
							found=true;
							break;
						}
					}
					if(found) break;
				}
			}
			while(position>=0)
			{
				while(strToInt(dataGrid1[history[position]])<9)
				{
					dataGrid1[history[position]]=strToInt(dataGrid1[history[position]])+1;
					if(checkCell(history[position]))
					{
						bool found=false;
						for(int i=0;i<9;i++)
						{
							for(int j=0;j<9;j++)
							{
								if((string)dataGrid1[i,j]=="")
								{
									position++;
									history[position]=new DataGridCell(i,j);
									dataGrid1[history[position]]="0";
									found=true;
									break;
								}
							}
							if(found) break;
						}
						if(!found) return;
					}
				}
				dataGrid1[history[position]]="";
				position--;
			}
		}

		bool checkCell(DataGridCell cell)
		{
			//check horizontal
			for(int i=0;i<9;i++)
			{
				if(i!=cell.ColumnNumber && (string)dataGrid1[cell.RowNumber,i]==(string)dataGrid1[cell])
				{
					return false;
				}
			}
			//check vertical
			for(int i=0;i<9;i++)
			{
				if(i!=cell.RowNumber && (string)dataGrid1[i,cell.ColumnNumber]==(string)dataGrid1[cell])
				{
					return false;
				}
			}
			//check small square
			for(int i=(int)(Math.Floor(cell.RowNumber/3)*3);i<Math.Floor(cell.RowNumber/3)*3+3;i++)
			{
				for(int j=(int)(Math.Floor(cell.ColumnNumber/3)*3);j<Math.Floor(cell.ColumnNumber/3)*3+3;j++)
				{
					if(!(i==cell.RowNumber && j==cell.ColumnNumber) && (string)dataGrid1[i,j]==(string)dataGrid1[cell])
					{
						return false;
					}
				}
			}
			return true;
		}

		int strToInt(object o1)
		{
			if(o1 as string == null)return 0;
			string str=(string)o1;
			try
			{
				return int.Parse(str);
			}
			catch
			{
				return 0;
			}
		}
		//---------------------------------------------------------------------------------
		//---------------------------------------------------------------------------------
		//---------------------------------------------------------------------------------

		private void Form1_Load(object sender, System.EventArgs e)
		{
			DataTable t1=new DataTable();
			for(int i=1;i<=9;i++)
			{
				t1.Columns.Add("c"+i,typeof(string));
			}
			for(int i=1;i<=9;i++)
			{
				DataRow r1=t1.NewRow();
				for(int j=1;j<=9;j++)
				{
					r1[j-1]="";
				}
				t1.Rows.Add(r1);
			}
			t1.DefaultView.AllowNew=false;
			t1.DefaultView.AllowDelete=false;
			dataGrid1.DataSource=t1;
		}

		private void Find_Click(object sender, System.EventArgs e)
		{
			findFirst=true;
			if(calcThread==null || !calcThread.IsAlive)
			{
				calcThread=new Thread(new ThreadStart(find));
				calcThread.Start();
			}
		}

		private void Next_Click(object sender, System.EventArgs e)
		{
			findFirst=false;
			if(calcThread==null || !calcThread.IsAlive)
			{
				calcThread=new Thread(new ThreadStart(find));
				calcThread.Start();
			}
		}

		private void Save_Click(object sender, System.EventArgs e)
		{
			DataSet ds1=new DataSet();
			ds1.Tables.Add((DataTable)dataGrid1.DataSource);
			ds1.WriteXml(textBox1.Text,XmlWriteMode.WriteSchema);
		}

		private void btnLoad_Click(object sender, System.EventArgs e)
		{
			DataSet ds1=new DataSet();
			ds1.ReadXml(textBox1.Text);
			DataTable t1=ds1.Tables[0];
			t1.DefaultView.AllowNew=false;
			t1.DefaultView.AllowDelete=false;
			dataGrid1.DataSource=t1;
		}

		private void BtnReset_Click(object sender, System.EventArgs e)
		{
			Form1_Load(sender,e);
		}

		private void btnStop_Click(object sender, System.EventArgs e)
		{
			calcThread.Abort();
		}
	}
}
