xref: /plan9/sys/src/games/sudoku/game.c (revision 5fe11e2580d4833b76e3395a87f740886ced2411)
1*5fe11e25SDavid du Colombier #include <u.h>
2*5fe11e25SDavid du Colombier #include <libc.h>
3*5fe11e25SDavid du Colombier #include <draw.h>
4*5fe11e25SDavid du Colombier 
5*5fe11e25SDavid du Colombier #include "sudoku.h"
6*5fe11e25SDavid du Colombier 
7*5fe11e25SDavid du Colombier int allowbits[Brdsize] = {
8*5fe11e25SDavid du Colombier 	0x00100,
9*5fe11e25SDavid du Colombier 	0x00200,
10*5fe11e25SDavid du Colombier 	0x00400,
11*5fe11e25SDavid du Colombier 	0x00800,
12*5fe11e25SDavid du Colombier 	0x01000,
13*5fe11e25SDavid du Colombier 	0x02000,
14*5fe11e25SDavid du Colombier 	0x04000,
15*5fe11e25SDavid du Colombier 	0x08000,
16*5fe11e25SDavid du Colombier 	0x10000
17*5fe11e25SDavid du Colombier };
18*5fe11e25SDavid du Colombier 
19*5fe11e25SDavid du Colombier int boxind[Brdsize][Brdsize] = {
20*5fe11e25SDavid du Colombier 	{0,1,2,9,10,11,18,19,20},
21*5fe11e25SDavid du Colombier 	{3,4,5,12,13,14,21,22,23},
22*5fe11e25SDavid du Colombier 	{6,7,8,15,16,17,24,25,26},
23*5fe11e25SDavid du Colombier 	{27,28,29,36,37,38,45,46,47},
24*5fe11e25SDavid du Colombier 	{30,31,32,39,40,41,48,49,50},
25*5fe11e25SDavid du Colombier 	{33,34,35,42,43,44,51,52,53},
26*5fe11e25SDavid du Colombier 	{54,55,56,63,64,65,72,73,74},
27*5fe11e25SDavid du Colombier 	{57,58,59,66,67,68,75,76,77},
28*5fe11e25SDavid du Colombier 	{60,61,62,69,70,71,78,79,80},
29*5fe11e25SDavid du Colombier };
30*5fe11e25SDavid du Colombier int colind[Brdsize][Brdsize] = {
31*5fe11e25SDavid du Colombier 	{0,9,18,27,36,45,54,63,72},
32*5fe11e25SDavid du Colombier 	{1,10,19,28,37,46,55,64,73},
33*5fe11e25SDavid du Colombier 	{2,11,20,29,38,47,56,65,74},
34*5fe11e25SDavid du Colombier 	{3,12,21,30,39,48,57,66,75},
35*5fe11e25SDavid du Colombier 	{4,13,22,31,40,49,58,67,76},
36*5fe11e25SDavid du Colombier 	{5,14,23,32,41,50,59,68,77},
37*5fe11e25SDavid du Colombier 	{6,15,24,33,42,51,60,69,78},
38*5fe11e25SDavid du Colombier 	{7,16,25,34,43,52,61,70,79},
39*5fe11e25SDavid du Colombier 	{8,17,26,35,44,53,62,71,80},
40*5fe11e25SDavid du Colombier };
41*5fe11e25SDavid du Colombier int rowind[Brdsize][Brdsize] = {
42*5fe11e25SDavid du Colombier 	{0,1,2,3,4,5,6,7,8},
43*5fe11e25SDavid du Colombier 	{9,10,11,12,13,14,15,16,17},
44*5fe11e25SDavid du Colombier 	{18,19,20,21,22,23,24,25,26},
45*5fe11e25SDavid du Colombier 	{27,28,29,30,31,32,33,34,35},
46*5fe11e25SDavid du Colombier 	{36,37,38,39,40,41,42,43,44},
47*5fe11e25SDavid du Colombier 	{45,46,47,48,49,50,51,52,53},
48*5fe11e25SDavid du Colombier 	{54,55,56,57,58,59,60,61,62},
49*5fe11e25SDavid du Colombier 	{63,64,65,66,67,68,69,70,71},
50*5fe11e25SDavid du Colombier 	{72,73,74,75,76,77,78,79,80},
51*5fe11e25SDavid du Colombier };
52*5fe11e25SDavid du Colombier 
53*5fe11e25SDavid du Colombier static int maxlevel;
54*5fe11e25SDavid du Colombier static int solved;
55*5fe11e25SDavid du Colombier 
56*5fe11e25SDavid du Colombier void
printbrd(int * board)57*5fe11e25SDavid du Colombier printbrd(int *board)
58*5fe11e25SDavid du Colombier {
59*5fe11e25SDavid du Colombier 	int i;
60*5fe11e25SDavid du Colombier 
61*5fe11e25SDavid du Colombier 	for(i = 0; i < Psize; i++) {
62*5fe11e25SDavid du Colombier 		if(i > 0 && i % Brdsize == 0)
63*5fe11e25SDavid du Colombier 			print("\n");
64*5fe11e25SDavid du Colombier 		print("%2.2d ", board[i] & Digit);
65*5fe11e25SDavid du Colombier 	}
66*5fe11e25SDavid du Colombier 	print("\n");
67*5fe11e25SDavid du Colombier }
68*5fe11e25SDavid du Colombier 
69*5fe11e25SDavid du Colombier int
getrow(int cell)70*5fe11e25SDavid du Colombier getrow(int cell)
71*5fe11e25SDavid du Colombier {
72*5fe11e25SDavid du Colombier 	return cell/9;
73*5fe11e25SDavid du Colombier }
74*5fe11e25SDavid du Colombier 
75*5fe11e25SDavid du Colombier int
getcol(int cell)76*5fe11e25SDavid du Colombier getcol(int cell)
77*5fe11e25SDavid du Colombier {
78*5fe11e25SDavid du Colombier 	return cell%9;
79*5fe11e25SDavid du Colombier }
80*5fe11e25SDavid du Colombier 
81*5fe11e25SDavid du Colombier int
getbox(int cell)82*5fe11e25SDavid du Colombier getbox(int cell)
83*5fe11e25SDavid du Colombier {
84*5fe11e25SDavid du Colombier 	int row = getrow(cell);
85*5fe11e25SDavid du Colombier 	int col = getcol(cell);
86*5fe11e25SDavid du Colombier 
87*5fe11e25SDavid du Colombier 	return 3*(row/3)+ col/3;
88*5fe11e25SDavid du Colombier }
89*5fe11e25SDavid du Colombier 
90*5fe11e25SDavid du Colombier void
setdigit(int cc,int num)91*5fe11e25SDavid du Colombier setdigit(int cc, int num)
92*5fe11e25SDavid du Colombier {
93*5fe11e25SDavid du Colombier 	board[cc] = (board[cc] & ~Digit) | num;
94*5fe11e25SDavid du Colombier }
95*5fe11e25SDavid du Colombier 
96*5fe11e25SDavid du Colombier int
boxcheck(int * board)97*5fe11e25SDavid du Colombier boxcheck(int *board)
98*5fe11e25SDavid du Colombier {
99*5fe11e25SDavid du Colombier 	int i,j,d,sum,last,last2;
100*5fe11e25SDavid du Colombier 
101*5fe11e25SDavid du Colombier 	for (i = 0; i < 9; i++) {
102*5fe11e25SDavid du Colombier 		for (d = 0;d < 9; d++) {
103*5fe11e25SDavid du Colombier 			sum=0;
104*5fe11e25SDavid du Colombier 			last=-1;
105*5fe11e25SDavid du Colombier 			last2=-1;
106*5fe11e25SDavid du Colombier 			for (j = 0; j < 9; j++) {
107*5fe11e25SDavid du Colombier 				if (board[boxind[i][j]] & allowbits[d]) {
108*5fe11e25SDavid du Colombier 					sum++;
109*5fe11e25SDavid du Colombier 					last2=last;
110*5fe11e25SDavid du Colombier 					last=boxind[i][j];
111*5fe11e25SDavid du Colombier 				} else
112*5fe11e25SDavid du Colombier 					sum += ((board[boxind[i][j]] & Solve)==(d << 4)) ? 1: 0;
113*5fe11e25SDavid du Colombier 			}
114*5fe11e25SDavid du Colombier 			if (sum==0)
115*5fe11e25SDavid du Colombier 				return(0);
116*5fe11e25SDavid du Colombier 			if ((sum==1)&&(last>=0))
117*5fe11e25SDavid du Colombier 				if (!setallowed(board,last,d))
118*5fe11e25SDavid du Colombier 					return(0);
119*5fe11e25SDavid du Colombier 
120*5fe11e25SDavid du Colombier 			if((sum == 2) && (last >= 0) && ( last2 >= 0) &&
121*5fe11e25SDavid du Colombier 					(getrow(last) == getrow(last2))) {
122*5fe11e25SDavid du Colombier 				for (j = 0; j < 9; j++) {
123*5fe11e25SDavid du Colombier 					int c = rowind[getrow(last)][j];
124*5fe11e25SDavid du Colombier 					if ((c != last)&&(c != last2)) {
125*5fe11e25SDavid du Colombier 						if (board[c] & allowbits[d]) {
126*5fe11e25SDavid du Colombier 							board[c] &= ~allowbits[d];
127*5fe11e25SDavid du Colombier 							if ((board[c] & Allow)==0)
128*5fe11e25SDavid du Colombier 								return(0);
129*5fe11e25SDavid du Colombier 						}
130*5fe11e25SDavid du Colombier 					}
131*5fe11e25SDavid du Colombier 				}
132*5fe11e25SDavid du Colombier 			}
133*5fe11e25SDavid du Colombier 			if((sum == 2) && (last >= 0) && (last2 >= 0) &&
134*5fe11e25SDavid du Colombier 					(getcol(last) == getcol(last2))) {
135*5fe11e25SDavid du Colombier 				for (j = 0;j  <9;j++) {
136*5fe11e25SDavid du Colombier 					int c = colind[getcol(last)][j];
137*5fe11e25SDavid du Colombier 					if ((c != last) && (c != last2)) {
138*5fe11e25SDavid du Colombier 						if (board[c] & allowbits[d]) {
139*5fe11e25SDavid du Colombier 							board[c] &= ~allowbits[d];
140*5fe11e25SDavid du Colombier 							if ((board[c] & Allow) == 0)
141*5fe11e25SDavid du Colombier 								return(0);
142*5fe11e25SDavid du Colombier 						}
143*5fe11e25SDavid du Colombier 					}
144*5fe11e25SDavid du Colombier 				}
145*5fe11e25SDavid du Colombier 			}
146*5fe11e25SDavid du Colombier 		}
147*5fe11e25SDavid du Colombier 	}
148*5fe11e25SDavid du Colombier 	return(1);
149*5fe11e25SDavid du Colombier }
150*5fe11e25SDavid du Colombier 
151*5fe11e25SDavid du Colombier int
rowcheck(int * board)152*5fe11e25SDavid du Colombier rowcheck(int *board)
153*5fe11e25SDavid du Colombier {
154*5fe11e25SDavid du Colombier 	int i,j,d,sum,last;
155*5fe11e25SDavid du Colombier 
156*5fe11e25SDavid du Colombier 	for (i = 0; i < 9; i++) {
157*5fe11e25SDavid du Colombier 		for (d = 0; d < 9; d++) {
158*5fe11e25SDavid du Colombier 			sum = 0;
159*5fe11e25SDavid du Colombier 			last = -1;
160*5fe11e25SDavid du Colombier 			for (j = 0; j <9 ; j++) {
161*5fe11e25SDavid du Colombier 				if (board[rowind[i][j]] & allowbits[d]) {
162*5fe11e25SDavid du Colombier 					sum++;
163*5fe11e25SDavid du Colombier 					last = j;
164*5fe11e25SDavid du Colombier 				} else
165*5fe11e25SDavid du Colombier 					sum += ((board[rowind[i][j]] & Solve) == (d << 4)) ? 1: 0;
166*5fe11e25SDavid du Colombier 			}
167*5fe11e25SDavid du Colombier 			if (sum == 0)
168*5fe11e25SDavid du Colombier 				return(0);
169*5fe11e25SDavid du Colombier 			if ((sum == 1) && (last >= 0)) {
170*5fe11e25SDavid du Colombier 				if (!setallowed(board, rowind[i][last], d))
171*5fe11e25SDavid du Colombier 						return(0);
172*5fe11e25SDavid du Colombier 			}
173*5fe11e25SDavid du Colombier 		}
174*5fe11e25SDavid du Colombier 	}
175*5fe11e25SDavid du Colombier 	return(1);
176*5fe11e25SDavid du Colombier }
177*5fe11e25SDavid du Colombier 
178*5fe11e25SDavid du Colombier int
colcheck(int * board)179*5fe11e25SDavid du Colombier colcheck(int *board)
180*5fe11e25SDavid du Colombier {
181*5fe11e25SDavid du Colombier 	int i,j,d,sum,last;
182*5fe11e25SDavid du Colombier 
183*5fe11e25SDavid du Colombier 	for (i = 0; i < 9; i++) {
184*5fe11e25SDavid du Colombier 		for (d = 0; d < 9; d++) {
185*5fe11e25SDavid du Colombier 			sum = 0;
186*5fe11e25SDavid du Colombier 			last = -1;
187*5fe11e25SDavid du Colombier 			for (j = 0;j < 9;j++) {
188*5fe11e25SDavid du Colombier 				if (board[colind[i][j]] & allowbits[d]) {
189*5fe11e25SDavid du Colombier 					sum++;
190*5fe11e25SDavid du Colombier 					last = j;
191*5fe11e25SDavid du Colombier 				} else
192*5fe11e25SDavid du Colombier 					sum += ((board[colind[i][j]] & Solve) == (d << 4)) ? 1: 0;
193*5fe11e25SDavid du Colombier 			}
194*5fe11e25SDavid du Colombier 			if (sum == 0)
195*5fe11e25SDavid du Colombier 				return(0);
196*5fe11e25SDavid du Colombier 			if ((sum == 1) && (last >= 0)) {
197*5fe11e25SDavid du Colombier 				if (!setallowed(board, colind[i][last], d))
198*5fe11e25SDavid du Colombier 					return(0);
199*5fe11e25SDavid du Colombier 			}
200*5fe11e25SDavid du Colombier 		}
201*5fe11e25SDavid du Colombier 	}
202*5fe11e25SDavid du Colombier 	return(1);
203*5fe11e25SDavid du Colombier }
204*5fe11e25SDavid du Colombier 
205*5fe11e25SDavid du Colombier int
setallowed(int * board,int cc,int num)206*5fe11e25SDavid du Colombier setallowed(int *board, int cc, int num)
207*5fe11e25SDavid du Colombier {
208*5fe11e25SDavid du Colombier 	int j, d;
209*5fe11e25SDavid du Colombier 	int row, col, box;
210*5fe11e25SDavid du Colombier 
211*5fe11e25SDavid du Colombier 	board[cc] &= ~Allow;
212*5fe11e25SDavid du Colombier 	board[cc] = (board[cc] & ~Solve) | (num << 4);
213*5fe11e25SDavid du Colombier 
214*5fe11e25SDavid du Colombier 	row = getrow(cc);
215*5fe11e25SDavid du Colombier 	for (j = 0; j < 9; j++) {
216*5fe11e25SDavid du Colombier 		if (board[rowind[row][j]] & allowbits[num]) {
217*5fe11e25SDavid du Colombier 			board[rowind[row][j]] &= ~allowbits[num];
218*5fe11e25SDavid du Colombier 			if ((board[rowind[row][j]] & Allow) == 0)
219*5fe11e25SDavid du Colombier 				return(0);
220*5fe11e25SDavid du Colombier 		}
221*5fe11e25SDavid du Colombier 	}
222*5fe11e25SDavid du Colombier 
223*5fe11e25SDavid du Colombier 	col = getcol(cc);
224*5fe11e25SDavid du Colombier 	for (j = 0; j < 9; j++) {
225*5fe11e25SDavid du Colombier 		if (board[colind[col][j]] & allowbits[num]) {
226*5fe11e25SDavid du Colombier 			board[colind[col][j]] &= ~allowbits[num];
227*5fe11e25SDavid du Colombier 			if ((board[colind[col][j]] & Allow) == 0)
228*5fe11e25SDavid du Colombier 				return(0);
229*5fe11e25SDavid du Colombier 		}
230*5fe11e25SDavid du Colombier 	}
231*5fe11e25SDavid du Colombier 
232*5fe11e25SDavid du Colombier 	box = getbox(cc);
233*5fe11e25SDavid du Colombier 	for (j = 0;j < 9;j++) {
234*5fe11e25SDavid du Colombier 		if (board[boxind[box][j]] & allowbits[num]) {
235*5fe11e25SDavid du Colombier 			board[boxind[box][j]] &= ~allowbits[num];
236*5fe11e25SDavid du Colombier 			if ((board[boxind[box][j]] & Allow)==0)
237*5fe11e25SDavid du Colombier 				return(0);
238*5fe11e25SDavid du Colombier 		}
239*5fe11e25SDavid du Colombier 	}
240*5fe11e25SDavid du Colombier 
241*5fe11e25SDavid du Colombier 	for (j = 0;j < 81; j++)
242*5fe11e25SDavid du Colombier 		for (d = 0; d < 9; d++)
243*5fe11e25SDavid du Colombier 			if ((board[j] & Allow) == allowbits[d])
244*5fe11e25SDavid du Colombier 				if (!setallowed(board, j, d))
245*5fe11e25SDavid du Colombier 					return(0);
246*5fe11e25SDavid du Colombier 
247*5fe11e25SDavid du Colombier 	if (!boxcheck(board)||!rowcheck(board)||!colcheck(board))
248*5fe11e25SDavid du Colombier 		return(0);
249*5fe11e25SDavid du Colombier 
250*5fe11e25SDavid du Colombier 	for (j = 0; j < 81; j++)
251*5fe11e25SDavid du Colombier 		for (d = 0; d < 9; d++)
252*5fe11e25SDavid du Colombier 			if ((board[j] & Allow) == allowbits[d])
253*5fe11e25SDavid du Colombier 				if (!setallowed(board, j, d))
254*5fe11e25SDavid du Colombier 					return(0);
255*5fe11e25SDavid du Colombier 
256*5fe11e25SDavid du Colombier 	return(1);
257*5fe11e25SDavid du Colombier }
258*5fe11e25SDavid du Colombier 
259*5fe11e25SDavid du Colombier int
chksolved(int * board)260*5fe11e25SDavid du Colombier chksolved(int *board)
261*5fe11e25SDavid du Colombier {
262*5fe11e25SDavid du Colombier 	int i;
263*5fe11e25SDavid du Colombier 
264*5fe11e25SDavid du Colombier 	for (i = 0; i < Psize; i++)
265*5fe11e25SDavid du Colombier 		if ((board[i] & Allow) != 0)
266*5fe11e25SDavid du Colombier 			return 0;
267*5fe11e25SDavid du Colombier 
268*5fe11e25SDavid du Colombier 	solved = 1;
269*5fe11e25SDavid du Colombier 	return solved;
270*5fe11e25SDavid du Colombier }
271*5fe11e25SDavid du Colombier 
272*5fe11e25SDavid du Colombier int
findmove(int * board)273*5fe11e25SDavid du Colombier findmove(int *board)
274*5fe11e25SDavid du Colombier {
275*5fe11e25SDavid du Colombier 	int i, d;
276*5fe11e25SDavid du Colombier 	int s;
277*5fe11e25SDavid du Colombier 
278*5fe11e25SDavid du Colombier 	s = nrand(Psize);
279*5fe11e25SDavid du Colombier 	for (i=(s+1)%81;i!=s;i=(i+1)%81) {
280*5fe11e25SDavid du Colombier 		if (!(board[i] & Allow)) {
281*5fe11e25SDavid du Colombier 			d=(board[i] & Solve) >> 4;
282*5fe11e25SDavid du Colombier 			if ((board[i] & Digit)!=d)
283*5fe11e25SDavid du Colombier 				return(i);
284*5fe11e25SDavid du Colombier 		}
285*5fe11e25SDavid du Colombier 	}
286*5fe11e25SDavid du Colombier 	return(-1);
287*5fe11e25SDavid du Colombier }
288*5fe11e25SDavid du Colombier 
289*5fe11e25SDavid du Colombier void
attempt(int * pboard,int level)290*5fe11e25SDavid du Colombier attempt(int *pboard, int level)
291*5fe11e25SDavid du Colombier {
292*5fe11e25SDavid du Colombier 	int tb[Psize];
293*5fe11e25SDavid du Colombier 	int i, j, k;
294*5fe11e25SDavid du Colombier 	int s, e;
295*5fe11e25SDavid du Colombier 
296*5fe11e25SDavid du Colombier 	if (level > maxlevel)
297*5fe11e25SDavid du Colombier 		maxlevel = level;
298*5fe11e25SDavid du Colombier 
299*5fe11e25SDavid du Colombier 	if (level > 25)
300*5fe11e25SDavid du Colombier 		exits("level");	/* too much */
301*5fe11e25SDavid du Colombier 
302*5fe11e25SDavid du Colombier 	s = nrand(Psize);
303*5fe11e25SDavid du Colombier 	for (i = (s + 1) % Psize; i != s; i = (i + 1) % Psize) {
304*5fe11e25SDavid du Colombier 		if ((pboard[i] & Allow) != 0) {
305*5fe11e25SDavid du Colombier 			e=nrand(9);
306*5fe11e25SDavid du Colombier 			for (j = (e + 1) % 9; j != e; j = (j + 1) % 9) {
307*5fe11e25SDavid du Colombier 				if (pboard[i] & allowbits[j]) {
308*5fe11e25SDavid du Colombier 					for (k = 0; k < Psize; k++)
309*5fe11e25SDavid du Colombier 						tb[k] = pboard[k];
310*5fe11e25SDavid du Colombier 
311*5fe11e25SDavid du Colombier 					if (setallowed(tb, i, j)) {
312*5fe11e25SDavid du Colombier 						tb[i] = (tb[i] & ~Digit) | j;
313*5fe11e25SDavid du Colombier 						if (chksolved(tb)) {
314*5fe11e25SDavid du Colombier 							for (k = 0;k < Psize; k++)
315*5fe11e25SDavid du Colombier 								pboard[k] = tb[k];
316*5fe11e25SDavid du Colombier 							return;	/* bad! */
317*5fe11e25SDavid du Colombier 						}
318*5fe11e25SDavid du Colombier 
319*5fe11e25SDavid du Colombier 						attempt(tb, level + 1);
320*5fe11e25SDavid du Colombier 						if (chksolved(tb)) {
321*5fe11e25SDavid du Colombier 							for (k = 0; k < Psize; k++)
322*5fe11e25SDavid du Colombier 								pboard[k] = tb[k];
323*5fe11e25SDavid du Colombier 							return;
324*5fe11e25SDavid du Colombier 						}
325*5fe11e25SDavid du Colombier 						tb[i] |= Digit;
326*5fe11e25SDavid du Colombier 						if (level > 25)
327*5fe11e25SDavid du Colombier 							return;
328*5fe11e25SDavid du Colombier 					}
329*5fe11e25SDavid du Colombier 				}
330*5fe11e25SDavid du Colombier 			}
331*5fe11e25SDavid du Colombier 		}
332*5fe11e25SDavid du Colombier 	}
333*5fe11e25SDavid du Colombier }
334*5fe11e25SDavid du Colombier 
335*5fe11e25SDavid du Colombier void
solve(void)336*5fe11e25SDavid du Colombier solve(void)
337*5fe11e25SDavid du Colombier {
338*5fe11e25SDavid du Colombier 	int pboard[Psize];
339*5fe11e25SDavid du Colombier 	int	i, c;
340*5fe11e25SDavid du Colombier 
341*5fe11e25SDavid du Colombier 	if (!solved) {
342*5fe11e25SDavid du Colombier 		for (i = 0; i < Psize; i++)
343*5fe11e25SDavid du Colombier 			pboard[i] = Allow | Solve | Digit;
344*5fe11e25SDavid du Colombier 
345*5fe11e25SDavid du Colombier 		for (i = 0; i < Psize; i++) {
346*5fe11e25SDavid du Colombier 
347*5fe11e25SDavid du Colombier 			c = board[i] & Digit;
348*5fe11e25SDavid du Colombier 			if ((0 <= c) && (c < 9)) {
349*5fe11e25SDavid du Colombier 				if (!setallowed(pboard,i,c)) {
350*5fe11e25SDavid du Colombier 					print("starting position impossible... failed at cell %d char: %d\n", i, c + 1);
351*5fe11e25SDavid du Colombier 					return;
352*5fe11e25SDavid du Colombier 				}
353*5fe11e25SDavid du Colombier 			}
354*5fe11e25SDavid du Colombier 		}
355*5fe11e25SDavid du Colombier 		attempt(pboard,0);
356*5fe11e25SDavid du Colombier 
357*5fe11e25SDavid du Colombier 		for (i = 0; i < Psize; i++)
358*5fe11e25SDavid du Colombier 			board[i] = (board[i] & ~Solve) | (pboard[i] & Solve);
359*5fe11e25SDavid du Colombier 	}
360*5fe11e25SDavid du Colombier }
361*5fe11e25SDavid du Colombier 
362*5fe11e25SDavid du Colombier int
checklegal(int cc,int d)363*5fe11e25SDavid du Colombier checklegal(int cc, int d)
364*5fe11e25SDavid du Colombier {
365*5fe11e25SDavid du Colombier 	int hold = board[cc];
366*5fe11e25SDavid du Colombier 	int j, row, col, box;
367*5fe11e25SDavid du Colombier 	board[cc] |= Digit;
368*5fe11e25SDavid du Colombier 
369*5fe11e25SDavid du Colombier 	row = getrow(cc);
370*5fe11e25SDavid du Colombier 	for (j = 0; j < Brdsize; j++)
371*5fe11e25SDavid du Colombier 		if ((board[rowind[row][j]] & Digit) == d) {
372*5fe11e25SDavid du Colombier 			board[cc] = hold;
373*5fe11e25SDavid du Colombier 			return(0);
374*5fe11e25SDavid du Colombier 		}
375*5fe11e25SDavid du Colombier 
376*5fe11e25SDavid du Colombier 	col = getcol(cc);
377*5fe11e25SDavid du Colombier 	for (j = 0; j < Brdsize; j++)
378*5fe11e25SDavid du Colombier 		if ((board[colind[col][j]] & Digit) == d) {
379*5fe11e25SDavid du Colombier 			board[cc] = hold;
380*5fe11e25SDavid du Colombier 			return(0);
381*5fe11e25SDavid du Colombier 		}
382*5fe11e25SDavid du Colombier 
383*5fe11e25SDavid du Colombier 	box = getbox(cc);
384*5fe11e25SDavid du Colombier 	for (j = 0; j < Brdsize; j++)
385*5fe11e25SDavid du Colombier 		if ((board[boxind[box][j]] & Digit) == d) {
386*5fe11e25SDavid du Colombier 			board[cc] = hold;
387*5fe11e25SDavid du Colombier 			return(0);
388*5fe11e25SDavid du Colombier 		}
389*5fe11e25SDavid du Colombier 
390*5fe11e25SDavid du Colombier 	board[cc]=hold;
391*5fe11e25SDavid du Colombier 	return(1);
392*5fe11e25SDavid du Colombier }
393*5fe11e25SDavid du Colombier 
394*5fe11e25SDavid du Colombier void
clearp(void)395*5fe11e25SDavid du Colombier clearp(void)
396*5fe11e25SDavid du Colombier {
397*5fe11e25SDavid du Colombier 	int i;
398*5fe11e25SDavid du Colombier 	for(i = 0; i < Psize; i++) {
399*5fe11e25SDavid du Colombier 		board[i] = (Allow | Solve | Digit);
400*5fe11e25SDavid du Colombier 	}
401*5fe11e25SDavid du Colombier 	solved = 0;
402*5fe11e25SDavid du Colombier }
403*5fe11e25SDavid du Colombier 
404*5fe11e25SDavid du Colombier void
makep(void)405*5fe11e25SDavid du Colombier makep(void)
406*5fe11e25SDavid du Colombier {
407*5fe11e25SDavid du Colombier 	int i,d;
408*5fe11e25SDavid du Colombier 
409*5fe11e25SDavid du Colombier 	do {
410*5fe11e25SDavid du Colombier 		clearp();
411*5fe11e25SDavid du Colombier 		maxlevel=0;
412*5fe11e25SDavid du Colombier 
413*5fe11e25SDavid du Colombier 		for (d = 0; d < Brdsize; d++) {
414*5fe11e25SDavid du Colombier 			i = nrand(Psize);
415*5fe11e25SDavid du Colombier 			if (board[i] & allowbits[d]) {
416*5fe11e25SDavid du Colombier 				setallowed(board, i, d);
417*5fe11e25SDavid du Colombier 				board[i] = (board[i] & ~Digit) | d;
418*5fe11e25SDavid du Colombier 			}
419*5fe11e25SDavid du Colombier 		}
420*5fe11e25SDavid du Colombier 
421*5fe11e25SDavid du Colombier 		attempt(board, 0);
422*5fe11e25SDavid du Colombier 
423*5fe11e25SDavid du Colombier 		for (i = 0; i < Psize; i++) {
424*5fe11e25SDavid du Colombier 			if ((0 <= (board[i] & Digit)) && ((board[i] & Digit) < 9))
425*5fe11e25SDavid du Colombier 				board[i] |= MLock;
426*5fe11e25SDavid du Colombier 			setdigit(i, board[i] & Digit);
427*5fe11e25SDavid du Colombier 		}
428*5fe11e25SDavid du Colombier 
429*5fe11e25SDavid du Colombier 		if (!solved) {
430*5fe11e25SDavid du Colombier 			fprint(2, "failed to make puzzle\n");
431*5fe11e25SDavid du Colombier 			exits("failed to make puzzle");
432*5fe11e25SDavid du Colombier 		}
433*5fe11e25SDavid du Colombier 
434*5fe11e25SDavid du Colombier 	} while (!solved);
435*5fe11e25SDavid du Colombier 
436*5fe11e25SDavid du Colombier }
437