C/C++ Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 
Go Back   Dev Articles Community ForumsProgrammingC/C++ Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old April 28th, 2006, 04:08 PM
GernerPSU GernerPSU is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Apr 2006
Posts: 2 GernerPSU User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 19 m 32 sec
Reputation Power: 0
SuDoKu Backtracking program

I need to write a c++ SuDoKu solver using backtracking. I am using a Vector-Vector-Deque where the Vector-Vector is the coordinate system for the puzzle and the Deque is the available numbers for each cell. I distinguish the constant numbers as a negative number(yes, i use abs() when i actually use them). Through thorough testing I'm near positive my functions to check if the number conflicts are all working perfectly. The backtracking function seems perfect, and I am just starting to wonder if, for some reason, it just takes forever to complete. Using the provided puzzle, it took about 15 minutes before it back tracked to the original cell and it popped the 1 to increse up to 2. Anyway, here is the code:

main.cpp:
Code:
#include <iostream>
#include "SuDoKu.h"
using namespace std;

int main(){
	string PuzzleName;
	cout << "Which puzzle would you like to load?" << endl;
	cin >> PuzzleName;
	SuDoKu puzzle;
	if(!puzzle.Solve(PuzzleName)){
		cout << "The puzzle is not solvable" << endl;
	}
	return 0;
}



SuDoKu.h:
Code:
#ifndef SUDOKU
#define SUDOKU

#include <fstream>
#include <iostream>
#include <vector>
#include <deque>
#include <string>
using namespace std;

class SuDoKu {
public:
	
	SuDoKu();//Default Constructor

	bool CheckRow(int R, int Val, vector<vector<deque<int > > > Puzzle);

	bool CheckCol(int C, int Val, vector<vector<deque<int > > > Puzzle);

	bool CheckSquare(int R, int C, int Val, vector<vector<deque<int > > > Puzzle);

	bool CheckAll(int R, int C, int Val, vector<vector<deque<int > > > Puzzle);

	bool Solve(string PuzzleName);
};
#endif


SuDoKu.cpp:
Code:
#include <fstream>
#include <iostream>
#include <vector>
#include <deque>
#include <string>
#include "SuDoKu.h"
using namespace std;

SuDoKu::SuDoKu(){
	//nothing for default constructor to do
}

bool SuDoKu::CheckAll(int R, int C, int Val, vector<vector<deque<int > > > Puzzle){
	//debug msg
	cout << "Row: " << R << ", Col: " << C << ", Val: " << Val << endl;
	if(CheckCol(C, Val, Puzzle) && CheckRow(R, Val, Puzzle) && CheckSquare(R, C, Val, Puzzle)){
		return true;
	}
	else{
		return false;
	}
}

bool SuDoKu::CheckCol(int C, int Val, vector<vector<deque<int > > > Puzzle){
	int x = 0;//counter
	int conflicts = 0;
	for(x = 0; x < 9; x++){
		if(abs(Puzzle[x][C].front()) == Val){
			conflicts++;
		}
	}
	if(conflicts == 1){
		//debug msg
		cout << "Col is OK" << endl;
		return true;
	}
	else if(conflicts > 1){
		//debug msg
		cout << "Col is not OK" << endl;
		return false;
	}
}

bool SuDoKu::CheckRow(int R, int Val, vector<vector<deque<int > > > Puzzle){
	int x = 0;//counter
	int conflicts = 0;
	for(x = 0; x < 9; x++){
		if(Puzzle[R][x].front() < 0){
			if(int((Puzzle[R][x].front()))*(-1) == Val){
				conflicts++;
			}
		}
		if(Puzzle[R][x].front() == Val){
			conflicts++;
		}
	}
	if(conflicts == 1){
		//debug msg
		cout << "Row is OK" << endl;
		return true;
	}
	else{
		//debug msg
		cout << "Row is not OK" << endl;
		return false;
	}
}

bool SuDoKu::CheckSquare(int R, int C, int Val, vector<vector<deque<int > > > Puzzle){
	int squareC = 0;//sub-grib col
	int squareR = 0;//sub-grid row
	int x = 0;//counter
	int y = 0;//counter
	int conflicts = 0;
	//which sub-grid row is the space in
	if(R < 3){
		squareR = 0;
	}
	else if(R > 2 && R < 6){
		squareR = 1;
	}
	else if(R > 5 && R < 9){
		squareR = 2;
	}
	//which sub-grid col is the space in
	if(C < 3){
		squareC = 0;
	}
	else if(C > 2 && C < 6){
		squareC = 1;
	}
	else if(C > 5 && C < 9){
		squareC = 2;
	}
	//actually check the grid now
	for(x = (squareR*3); x < (squareR*3 + 3); x++){
		for(y = (squareC*3); y < (squareC*3 + 3); y++){
			if(Puzzle[x][y].front() < 0){
				if(int((Puzzle[x][y].front()))*(-1) == Val){//****need int? here and above*********************************************  *********************
					conflicts++;
				}
			}
			if(Puzzle[x][y].front() == Val){
				conflicts++;
			}
		}
	}
	if(conflicts == 1){
		//debug msg
		cout << "Square is OK" << endl;
		return true;
	}
	else{
		//debug msg
		cout << "Square is not OK" << endl;
		return false;
	}
}


bool SuDoKu::Solve(string PuzzleName){
	int a = 0;//counter
	int b = 0;//counter
	int num = 0;//input number
	vector<vector<deque<int > > > Puzzle(9, vector<deque<int > >(9, deque<int>(0)));
	ifstream fin;
	fin.open(PuzzleName.c_str());
	cout << "The puzzle loaded is: " << endl;
	for(a = 0; a < 9; a++){
		if(a == 3 || a == 6){
			cout << endl;
		}
		for(b = 0; b < 9; b++){
			fin >> num;
			if(num == 0){
				for(num = 0; num < 10; num++){
					Puzzle[a][b].push_back(num);
				}
				cout << Puzzle[a][b].front() << " ";
			}
			else{
				Puzzle[a][b].push_back(-1*num);
				cout << -1*(Puzzle[a][b].front()) << " ";
			}
			
			if(b == 2 || b == 5){
				cout << " ";
			}
		}
		cout << endl;
	}
	cout << endl;
	fin.close();
	//Puzzle is now loaded, will begin solving:

	a = 0;//row counter
	b = 0;//col counter
	num = 0;//counter for refilling in backtracking
	while(!(a == 9 && b == 0)){
		if(Puzzle[a][b].front() == 0){
			Puzzle[a][b].pop_front();
		}
		if(Puzzle[0][0].front() == 2){
			cout << "poop" << endl;
		}
		//begin
	//for debugging purposes, displays the puzzle as it is currently. stop at end of big while to see other debug msgs
		cout << endl << "currently..." << endl << endl;
			for(int r = 0; r < 9; r++){
				if(r == 3 || r == 6){
					cout << endl;
				}
				for(int d = 0; d < 9; d++){
					if(Puzzle[r][d].front() < 0){
						cout << Puzzle[r][d].front()*-1 << " ";
					}
					else{
						cout << Puzzle[r][d].front() << " ";
					}
					if(d == 2 || d == 5){
						cout << " ";
					}
				}
				cout << endl;
			}
			//end
		
		if(Puzzle[a][b].front() < 0){//this is not a changeable space
			//debug msg
			cout << "Not a changeable space..." << endl;
			if(b < 8){
				b++;
			}
			else{
				b = 0;
				a++;
			}
		}
		else{
			if(CheckAll(a, b, Puzzle[a][b].front(), Puzzle)){
				if(b < 8){
					b++;
				}
				else{
					b = 0;
					a++;
				}
			}
			else{
				if(Puzzle[a][b].size() == 1){
					Puzzle[a][b].pop_front();
					for(num = 0; num < 10; num++){
						Puzzle[a][b].push_back(num);
					}
					//debug msg
					cout << "At Row " << a << " and Col " << b << " the numbers were pushed on" << endl;
					if(a == 0 && b == 0){
						return false;
					}
					else if(b == 0){
						a--;
						b = 8;
					}
					else{
						b--;
					}
					while(Puzzle[a][b].size() == 1){//need a check for the const or single
						if(Puzzle[a][b].front() < 0){
							if(b == 0){
								a--;
								b = 8;
							}
							else{
								b--;
							}
						}
						else{
							Puzzle[a][b].pop_front();
							for(num = 0; num < 10; num++){
								Puzzle[a][b].push_back(num);
							}
							//debug msg
							cout << "At Row " << a << " and Col " << b << " the numbers were pushed on" << endl;
							if(b == 0){
								a--;
								b = 8;
							}
							else{
								b--;
							}
						}
					}
					Puzzle[a][b].pop_front();
				}
				else{
					Puzzle[a][b].pop_front();
				}
			}
		}
	}//stop here if debuging
	
	cout << "The solved puzzle is: " << endl;
	//solved so display
	for(a = 0; a < 9; a++){
		if(a == 3 || a == 6){
			cout << endl;
		}
		for(b = 0; b < 9; b++){
			if(Puzzle[a][b].front() < 0){
				cout << abs(Puzzle[a][b].front()) << " ";
			}
			else{
				cout << Puzzle[a][b].front() << " ";
			}
			if(b == 2 || b == 5){
				cout << " ";
			}
		}
		cout << endl;
	}
	return true;
}


Included puzzle:
Code:
0 0 0 0 8 6 0 9 0
7 0 0 0 0 0 3 0 2
0 0 0 0 0 0 0 1 0
0 8 1 2 0 0 0 0 0
0 0 0 5 0 0 6 0 7
0 3 0 0 0 0 0 0 4
0 0 0 0 9 0 0 0 0
0 6 0 0 0 2 0 0 1
0 0 0 7 4 0 0 0 0


I left all the debuging cout's in. There is a spot marked in the solving section that I reccomend a stop to be placed if you wanna look how it executes.

Its due at midnight so hopefully I get it done and can move on to more pressing final projects and studying. For now, I'm going to let it run a while since about 30 minutes have passed now and the original cell is still 2.

Reply With Quote
  #2  
Old April 28th, 2006, 04:23 PM
GernerPSU GernerPSU is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Apr 2006
Posts: 2 GernerPSU User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 19 m 32 sec
Reputation Power: 0
Ok. It finally finished after about 45 minutes. I don't get why it takes so long if the example my proffesor showed took less than a second.

Reply With Quote
Reply

Viewing: Dev Articles Community ForumsProgrammingC/C++ Help > SuDoKu Backtracking program


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway
Stay green...Green IT