I am tryint to convert my c++ coed that solves a HiQ puzzle with a depth first search into c# so that i can play around with a gui for it.

I have tried a few different approaches but the whole idea of everything being inside of a class is throwing me off.

class HiQ
	{
		private int [,,] between;
		private int loopCount, size;
		private Board startingBoard, solutionConfig;
		private HashSet<Board> markedSet;
		private Stack<JumpType> jumpStack;
		bool Solved;


		public HiQ(int startingHole, int boardSize)
		{
			between = new int [5,78,78];
			size = boardSize - 3;

			Solved = false;

			loopCount = (int)Enum.GetValues(typeof(NumberOfPegs)).GetValue(size);
			markedSet = new HashSet<Board>();
			jumpStack = new Stack<JumpType>();

			
			startingBoard.set(loopCount,startingHole);
			solutionConfig.set(loopCount,startingHole,true);
			InitializeBetween();
		}
		public int Size 
		{
			get{return size;}
		}


	
        public bool Solve()
		{
			Solved = false;
			markedSet.Clear();
			
			while (jumpStack.Count != 0) jumpStack.Pop();

			return FindSolution( startingBoard);
		}

		public void Print()
		{

			Console.WriteLine(Solved);
		}

		public void PrintAll()
		{
			//while (jumpStack.Peek() != null)
			//{
			//    PrintBoard(fout, JumpStack.top().config, JumpStack.top().from, JumpStack.top().to);
			//    JumpStack.pop();
			//    system("pause");//wait(20);
			//    system("cls");

			//}
			return;
		}

		//private void PrintBoard(

		private void GetNewMove( JumpType jump)
		{
			jump.Config.flip(jump.From);
			jump.Config.flip(jump.To);
			jump.Config.flip(between[size, jump.From, jump.To]);
		}

		private void PrintBoard(Board board)
		{
			int k = 1;
			for (int i = 0; i < size + 5; i++)
			{
				if (i == 0 || i == size + 4)
				{
					Console.Write("   ");
					for (int j = 0; j < size + 3; j++)
					{
						if (board.check(k))
							Console.ForegroundColor = ConsoleColor.Green;
						else
							Console.ForegroundColor = ConsoleColor.Red;
						Console.Write("{0,3:D}",k++);
					}
					Console.WriteLine();
				}
				else
				{

					for (int j = 0; j < size + 5; j++)
					{
						if (board.check(k))
							Console.ForegroundColor = ConsoleColor.Green;
						else
							Console.ForegroundColor = ConsoleColor.Red;
						Console.Write("{0,3:D}", k++);
					}
					Console.WriteLine();
				}
			}


		}

		private bool FindSolution(  Board board, int level = 0)
		{

			if (board == solutionConfig)
				return true;
		
			markedSet.Add(board);

			for (short from = 1; !Solved && from < loopCount; from++)
			{
				if (board.check(from))
				{
					for (short to = 1; !Solved && to < loopCount; to++)
					{
						if (!board.check(to) && board.check(between[size, from, to]))
						{
							Board newBoard = board;
							JumpType jump = new JumpType(newBoard, from, to);
							Console.WriteLine("\nbefore Jump");
							PrintBoard(board);
							
							GetNewMove( jump);
							PrintBoard(board);
							Console.WriteLine("after jump\n\n");
							
							if (!markedSet.Contains(newBoard))
							{
								
								Solved = FindSolution( newBoard, level + 1);
								if (Solved)
								{
									jumpStack.Push(jump);
									return true;
								}
								Console.WriteLine("just backtracked\n\n");

							}
						}
					}
				}
			}
			return Solved;
		}

That probably isnt the easiest thing to read but i will explain it.
I start with instantiating the HiQ class which generates a Board type struct, that was a BitArray but due to this on going issue has sence been changed to an array of bools.

The solve function calls my FindSolution function which implements a depth first search. I can garente that all moves it should be taking are valid (thats whats inside the InitializeBetween function but its huge and doesnt realy matter.

The issue is, My board is getting replaced with other boards within the DFS which really comes down to me not understanding how data is stored in c#.
here is the Board and JumpType structs;

struct JumpType
	{
		private int from;
		private int to;
		private Board config;

		public JumpType( Board c, int a, int b)
		{
			config = c;
			from = a;
			to = b;
		}
		public JumpType(  JumpType source)
		{
			config = source.Config;
			from = source.From;
			to = source.To;
		}

		public int From
		{
			get { return from; }
			set { from = value; }
		}
		public int To
		{
			get { return to; }
			set { to = value; }
		}
		public Board Config
		{
			get { return config; }
			set { config = value; }
		}



	}
struct Board
	{
		private bool[] B;
		private int count;

		public Board(Board source)
		{
			B = new bool[source.Count];
			count = source.Count;
			for (int i = 0; i < count; i++)
				B[i] = source.check(i);
		}

		public Board(int size, int hole)
		{
			B = new bool[size];
			count = size;
			if (hole > 0)
			{
				for (int i = 0; i < size; i++)
					B[i] = true;
				B[0] = false;
				B[+hole] = false;
			}
			else
			{
				for (int i = 0; i < size; i++)
					B[i] = false;
				B[-hole] = true;
			}
		}

		public void set(int size, int hole, bool solution = false)
		{

			B = new bool[size];
			count = size;
			if (!solution)
			{
				for (int i = 0; i < size; i++)
					B[i] = true;
				B[0] = false;
				B[hole] = false;
			}
			else
			{
				for (int i = 0; i < size; i++)
					B[i] = false;
				B[hole] = true;
			}
		}


		public bool check(int i)
		{
			return (B[i]);
		}

		public void flip(int i)
		{
			B[i] = !B[i];
		}

		public int Count
		{
			get { return count; }
		}

		

		public static bool operator ==(Board one, Board two)
		{
			if (one.Count != two.Count)
				return false;
			else
				for (int i = 0; i < one.Count; i++)
				{
					if (one.check(i) != two.check(i))
						return false;
				}
			return true;
		}

		public static bool operator !=(Board one, Board two)
		{
			if (one.Count != two.Count)
				return true;
			else
				for (int i = 0; i < one.Count; i++)
				{
					if (one.check(i) != two.check(i))
						return true;
				}
			return false;
		}

		public static bool operator <(Board one, Board two)
		{
			if (one.Count < two.Count)
				return true;
			else if (one.Count > two.Count)
				return false;
			else
			{
				for (int i = one.Count - 1; i > 0; i--)
					if (one.check(i) != two.check(i))
						return !(one.check(i));
						
				return false;
			}
		}

		public static bool operator >(Board one, Board two)
		{
			if (one.Count > two.Count)
				return true;
			else if (one.Count < two.Count)
				return false;
			else
			{
				for (int i = one.Count - 1; i > 0; i--)
					if (one.check(i) != two.check(i))
						return (one.check(i));

				return false;
			}
		}
	}

any pointers would be appreciated.

Recommended Answers

All 4 Replies

Don't know what a HIQ puzzle is, but I would not implement it as a Console application. I would use a Windows Forms Application instead. Suggest you read a book about C# :)

It actually is in a windows forum app. i just have console turned on because i don't know how to make the gui yet:)

To get you started with drawing on a form, you could read this MSDN article

commented: Good advice! +11

Im keen on figuring the gui out on my own, i was just hoping someone had an idea as to why my DFS wont backtrack properly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.