A Sudoku Killer

*If you don't know how to play Sudoku, this might not make much sense.*

I'm relatively new to programming and I need some help with this program I'm writing. It's being compiled in Microsoft Visual C++ 2008 Express.

This program will hopefully be able to beat Sudoku puzzles when I'm done with it.
In it, the user inputs the numbers that are on a sudoku game into the program. They put in "0," if the spot is blank.
After the user puts in all 81 spots, the program starts trying different combinations of numbers in the blank spots until it finds a working answer.

Now...I haven't gotten too far into writing this, but as of now, the user can input all numbers and the program can read through and spit them out. I have coded the part of the program that deciphers the blank ("0") spots, but the program only, so far, is basing it off what's in the x-axis of the 0.
Also, that last part doesn't seem to work...but it should! I think...

I'm just going to past the whole code, because as of now, the program's not *too* large and I'm not sure where the actual problem might be. And before anyone says anything, yes I'm using the "goto" function...yeah yeah... I've heard....I know how to not use it, but as far as I can tell, that's not what's causing the problem.

There are a lot of extra bits in the code that I used to test the program with. All of the comments were applied before I made this post, while writing the program, so if any of it doesn't make sense, just ask.

It outputs all of the numbers back correctly, but it can't seem to find the right number for zero, unless the user types in the numbers in order from one to nine.
Line 74 is where it outputs the chosen number for the blank spot.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

int a [9][10]; int b =0; int c =0; int d =0; int e; int f; int testb; int br;

//user puts in known sudoku numbers and this program systematically 
//tries combinations of numbers until it finds a solution.

int main()
{
//PART ONE where the user inputs the given numbers
	cout << "Tell me where each of the numbers are that you know of. \n";
	while (c < 9)
	{
	cout << "What is in ["; cout << b+1; cout << ", "; cout << c+1; cout << "]?   ";
	d = 0;
	cin >> d;//user inputs given number in slot
	a [b][c] = d;
	/*TEST*/cout << d;
	/*TEST*/cout << a [b][c];
	/*TEST*/cout << a [8][0];
	/*TEST*/cout << a [0][1];
	b = b+1;//we move to the next spot on the row...
	if (b == 9)//checking if it's the end of the row...
		{c = c+1;//it is, so we move down one spot on the y-axis
		b = 0;}//spot next checked will be (0,(last + 1))
	}//-

//PART TWO where the computer deciphers what the missing numbers are
	b = 0;
	c = 0;
	loop2:
//A NUMBER WAS GIVEN
	if (a [b][c] > 0)
	{
		//user had a number already in in this spot, so the program skips over it.
		cout << a [b][c];
		b += 1;
		if (b > 8)
		{
			c += 1;
			b = 0;
		}
		if (c == 9)
			{/*TEST*/cout << "hello";}
		else
			{goto loop2;}
	}
//A ZERO WAS GIVEN
	else
	{
		//user had a zero in this spot, so the program tests possible numbers.
		cout << "hi";
		//--+
		testb = 1;
		br = b;
		b = 0;
		startb://-for the x-axis
		if (a [b][c] == testb)
		{
			testb = testb + 1;
			goto startb;
		}
		else
		{
			b = b + 1;
			if (b > 8)
			{
				b = br;
				a [b][c] = testb;
				cout << a [b][c]; cout << "is b  ";
				b = b + 1;
				goto loop2;
			}
			goto startb;
		}
	}


	/*TEST*/cout << a [0][0];
	/*TEST*/cout << a [0][5];
	/*TEST*/cout << a [3][0];
	/*TEST*/cout << a [8][8];
	cout << "You Win!\n \n Press any key and then <enter> to continue!";
	int z;
	cin >> z;
	cin.get();
	return 0;

}//end of int(main) 
Last edited on
I'm not sure what you're planning, but the program is already as long as a complete implementation of a brute force backtracking solver.

The first thing this program needs is more functions. Divide the code into smaller tasks to improve organization. This can also make testing much easier. For example, you can have a function that checks the number within its row, another that does it within the column, and another that checks within the square. The three are independent and can be improved separately.

The second thing it needs, is to get rid of the gotos. An iterative solver is much more complex than a recursive one. Plus, a few more gotos and I'll be compelled to use this code as an example of how not to use goto. You're just making a bowl of spaghetti.
I thought about splitting it up and I guess I could start working on that, but I'll leave this open for now as I still can't find the problem.

As for the goto thing, I did say I know I shouldn't use it, and when I get to reorganizing my pasta I'll be sure not to use it again.
Thanks for the input.

(I just moved int testb and int br up to before main () just a couple minutes ago, by the way, to keep from declaring them more than once (that doesn't fix the problem, of course))
Last edited on
Use of "goto" makes debugging programs very very difficult, and that alone may scare away anyone
from giving you useful advice.
Use of "goto" makes debugging programs very very difficult, and that alone may scare away anyone
from giving you useful advice.

Indeed, goto makes it very hard to understand what this program is doing. You should have a look at for and while, because these provide the loop functionality that you're trying to emulate here.
But even worse are the variable names - they're absolutely devoid of any meaning.
Yeah, when I can, i'll rewrite the program sans goto and post it back here...and that's a good point on the variable names; I hadn't really thought about that.
Thanks for the feedback!
By the way, you might have more success with having the program solve the sudoku similar to how a human would do it: cross out numbers that appear somewhere in the same row/column/box. When only one possible number remains, write it into the space. If you find "isles" (e.g. three fields in the same box where the only possible numbers are 1, 5, 4), you also know that these numbers can't be anywhere else in the box and thus eliminate them. Repeat this until the puzzle is solved or until these steps can't eliminate any more numbers. If the latter is the case (happens rarely), you can proceed with brute-forcing.
I found that this method can successfully solve many hard sudoku puzzles in mere microseconds.
Last edited on
you might have more success
How exactly are you defining "success"? A brute force can solve any solvable sudoku in no more than a couple of seconds and is much simpler than a human method. Fast, simple, and infallible. What more can you ask of an algorithm?
However, I would think the "natural" solution is easier to implement. For the brute force approach it's necessary to implement some game logic anyway, otherwise it would never finish.
Alas! I figured it out! It's also easier to read (but please let me know if there's more that needs work (like the way the user exits the program; I plan on fixing that)), both for the programmer and the user!

Keep in mind, the program (so far) only cares about the x-axis.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

int axis [9][9]; int x =0; int y =0; int given =0; int end; int testx; int fx;
//user puts in known sudoku numbers and this program systematically 
//tries combinations of numbers until it finds a solution.

void input()
{
	cout << "Tell me where each of the numbers are that you know of. \n";
	while (y < 9)
	{
		cout << "What is in ["; cout << x +1; cout << ", "; cout << y +1; cout << "]?   ";
		cin >> given;//user inputs given number in slot
		axis [x][y] = given;
		x +=1;//we move to the next spot on the row...
		if (x == 9)//checking if it's the end of the row...
		{
			y +=1;//it is, so we move down one spot on the y-axis
			x = 0;
		}//spot next checked will be (0,y+1)
	}
}


int main()
{
	input();//user inputs given numbers.
	x,y = 0;
	cout << "\n \n \n \n";
	while (y < 9)
	{
		if (axis [x][y] > 0)
		{//user had a number already in in this spot, so the program skips over it.
			cout << axis [x][y];
			x +=1;
			cout << "  ";
			if (x > 8)
			{
				cout << "\n \n";
				y +=1;
				x = 0;
			}
		}
		else
		{//user had a zero in this spot, so the program tests possible numbers.
			testx = 1;
			while (axis [x][y] == 0)
			{
				if (axis [fx][y] == testx)
				{
					testx +=1;
					fx = 0;
				}
				else
				{
					fx +=1;
					if (fx == 9)
					{
						fx = 0;
						axis [x][y] = testx;
						cout << axis [x][y];
						x +=1;
						cout << "  ";
						if (x > 8)
						{
							cout << "\n \n";
							y +=1;
							x = 0;
						}
					}
				}
			}
		}
	}

	cout << "You Win!\n \n Press any key and then <enter> to continue!";
	cin >> end;
	cin.get();
	return 0;
}


And to some of the above posters: I'm pretty certain that the natural method is unnecessary for this to work and I had thought about doing that, but it's unnecessary, so yeah. Also, for me at least, doing it the brute way seems easier. Maybe down the road I could make the program actually apply some decent logic.
Last edited on
Topic archived. No new replies allowed.