xref: /plan9/sys/src/games/sudoku/levels.c (revision 5fe11e2580d4833b76e3395a87f740886ced2411)
1*5fe11e25SDavid du Colombier #include <u.h>
2*5fe11e25SDavid du Colombier #include <libc.h>
3*5fe11e25SDavid du Colombier #include <bio.h>
4*5fe11e25SDavid du Colombier #include <draw.h>
5*5fe11e25SDavid du Colombier 
6*5fe11e25SDavid du Colombier #include "sudoku.h"
7*5fe11e25SDavid du Colombier 
8*5fe11e25SDavid du Colombier void
consumeline(Biobuf * b)9*5fe11e25SDavid du Colombier consumeline(Biobuf *b)
10*5fe11e25SDavid du Colombier {
11*5fe11e25SDavid du Colombier 	while(Bgetc(b) != '\n')
12*5fe11e25SDavid du Colombier 		;
13*5fe11e25SDavid du Colombier }
14*5fe11e25SDavid du Colombier 
15*5fe11e25SDavid du Colombier void
fprettyprintbrd(Cell * board)16*5fe11e25SDavid du Colombier fprettyprintbrd(Cell *board)
17*5fe11e25SDavid du Colombier {
18*5fe11e25SDavid du Colombier 	int x, y, fd;
19*5fe11e25SDavid du Colombier 
20*5fe11e25SDavid du Colombier 	fd = create("/tmp/sudoku-print", OWRITE|OTRUNC, 0600);
21*5fe11e25SDavid du Colombier 	if(fd < 0) {
22*5fe11e25SDavid du Colombier 		perror("can not open save file /tmp/sudoku-save");
23*5fe11e25SDavid du Colombier 		return;
24*5fe11e25SDavid du Colombier 	}
25*5fe11e25SDavid du Colombier 
26*5fe11e25SDavid du Colombier 	for(x = 0; x < Brdsize; x++) {
27*5fe11e25SDavid du Colombier 		for(y = 0; y < Brdsize; y++) {
28*5fe11e25SDavid du Colombier 			fprint(fd, " ");
29*5fe11e25SDavid du Colombier 			if(board[y*Brdsize + x].digit == -1)
30*5fe11e25SDavid du Colombier 				fprint(fd, ".");
31*5fe11e25SDavid du Colombier 			else
32*5fe11e25SDavid du Colombier 				fprint(fd, "%d", board[y*Brdsize + x].digit+1);
33*5fe11e25SDavid du Colombier 
34*5fe11e25SDavid du Colombier 			if(((x*Brdsize + y + 1) % Brdsize) == 0 || (x*Brdsize + y + 1) == Psize)
35*5fe11e25SDavid du Colombier 				fprint(fd, "\n");
36*5fe11e25SDavid du Colombier 
37*5fe11e25SDavid du Colombier 			if(((x*Brdsize + y + 1) % 3) == 0 && ((x*Brdsize + y + 1) % Brdsize) != 0)
38*5fe11e25SDavid du Colombier 				fprint(fd, "|");
39*5fe11e25SDavid du Colombier 
40*5fe11e25SDavid du Colombier 			if(((x*Brdsize + y + 1) % 27) == 0 && ((x*Brdsize + y + 1) % Psize) != 0)
41*5fe11e25SDavid du Colombier 				fprint(fd, " -------------------\n");
42*5fe11e25SDavid du Colombier 
43*5fe11e25SDavid du Colombier 		}
44*5fe11e25SDavid du Colombier 	}
45*5fe11e25SDavid du Colombier 	close(fd);
46*5fe11e25SDavid du Colombier }
47*5fe11e25SDavid du Colombier 
48*5fe11e25SDavid du Colombier void
fprintbrd(int fd,Cell * board)49*5fe11e25SDavid du Colombier fprintbrd(int fd, Cell *board)
50*5fe11e25SDavid du Colombier {
51*5fe11e25SDavid du Colombier 	int i;
52*5fe11e25SDavid du Colombier 
53*5fe11e25SDavid du Colombier 	for(i = 0; i < Psize; i++) {
54*5fe11e25SDavid du Colombier 		if(board[i].digit == -1)
55*5fe11e25SDavid du Colombier 			fprint(fd, ".");
56*5fe11e25SDavid du Colombier 		else
57*5fe11e25SDavid du Colombier 			fprint(fd, "%d", board[i].digit+1);
58*5fe11e25SDavid du Colombier 
59*5fe11e25SDavid du Colombier 		if((i + 1) % Brdsize == 0)
60*5fe11e25SDavid du Colombier 			fprint(fd, "\n");
61*5fe11e25SDavid du Colombier 	}
62*5fe11e25SDavid du Colombier 	for(i = 0; i < Psize; i++) {
63*5fe11e25SDavid du Colombier 		fprint(fd, "%d", board[i].solve+1);
64*5fe11e25SDavid du Colombier 		if((i + 1) % Brdsize == 0)
65*5fe11e25SDavid du Colombier 			fprint(fd, "\n");
66*5fe11e25SDavid du Colombier 	}
67*5fe11e25SDavid du Colombier 
68*5fe11e25SDavid du Colombier 	close(fd);
69*5fe11e25SDavid du Colombier }
70*5fe11e25SDavid du Colombier 
71*5fe11e25SDavid du Colombier int
loadlevel(char * name,Cell * board)72*5fe11e25SDavid du Colombier loadlevel(char *name, Cell *board)
73*5fe11e25SDavid du Colombier {
74*5fe11e25SDavid du Colombier 	Biobuf *b;
75*5fe11e25SDavid du Colombier 	char c;
76*5fe11e25SDavid du Colombier 	int i;
77*5fe11e25SDavid du Colombier 
78*5fe11e25SDavid du Colombier 	b = Bopen(name, OREAD);
79*5fe11e25SDavid du Colombier 	if(b == nil) {
80*5fe11e25SDavid du Colombier 		fprint(2, "could not open file %s: %r\n", name);
81*5fe11e25SDavid du Colombier 		return -1;
82*5fe11e25SDavid du Colombier 	}
83*5fe11e25SDavid du Colombier 
84*5fe11e25SDavid du Colombier 	i = 0;
85*5fe11e25SDavid du Colombier 	while((c = Bgetc(b)) > 0) {
86*5fe11e25SDavid du Colombier 		switch(c) {
87*5fe11e25SDavid du Colombier 		case '.':
88*5fe11e25SDavid du Colombier 			board[i].digit = -1;
89*5fe11e25SDavid du Colombier 			board[i].locked = 0;
90*5fe11e25SDavid du Colombier 			if(++i == 81)
91*5fe11e25SDavid du Colombier 				goto next;
92*5fe11e25SDavid du Colombier 			break;
93*5fe11e25SDavid du Colombier 		case 0x31:
94*5fe11e25SDavid du Colombier 		case 0x32:
95*5fe11e25SDavid du Colombier 		case 0x33:
96*5fe11e25SDavid du Colombier 		case 0x34:
97*5fe11e25SDavid du Colombier 		case 0x35:
98*5fe11e25SDavid du Colombier 		case 0x36:
99*5fe11e25SDavid du Colombier 		case 0x37:
100*5fe11e25SDavid du Colombier 		case 0x38:
101*5fe11e25SDavid du Colombier 		case 0x39:
102*5fe11e25SDavid du Colombier 			board[i].digit = c - 0x31;
103*5fe11e25SDavid du Colombier 			board[i].locked = 1;
104*5fe11e25SDavid du Colombier 			if(++i == 81)
105*5fe11e25SDavid du Colombier 				goto next;
106*5fe11e25SDavid du Colombier 			break;
107*5fe11e25SDavid du Colombier 		case '\n':
108*5fe11e25SDavid du Colombier 			break;
109*5fe11e25SDavid du Colombier 		default:
110*5fe11e25SDavid du Colombier 			fprint(2, "unknown character in initial board: %c\n", c);
111*5fe11e25SDavid du Colombier 			goto done;
112*5fe11e25SDavid du Colombier 		}
113*5fe11e25SDavid du Colombier 	}
114*5fe11e25SDavid du Colombier next:
115*5fe11e25SDavid du Colombier 	i = 0;
116*5fe11e25SDavid du Colombier 	while((c = Bgetc(b)) > 0) {
117*5fe11e25SDavid du Colombier 		switch(c) {
118*5fe11e25SDavid du Colombier 		case 0x31:
119*5fe11e25SDavid du Colombier 		case 0x32:
120*5fe11e25SDavid du Colombier 		case 0x33:
121*5fe11e25SDavid du Colombier 		case 0x34:
122*5fe11e25SDavid du Colombier 		case 0x35:
123*5fe11e25SDavid du Colombier 		case 0x36:
124*5fe11e25SDavid du Colombier 		case 0x37:
125*5fe11e25SDavid du Colombier 		case 0x38:
126*5fe11e25SDavid du Colombier 		case 0x39:
127*5fe11e25SDavid du Colombier 			board[i].solve = c - 0x31;
128*5fe11e25SDavid du Colombier 			if(++i == 81)
129*5fe11e25SDavid du Colombier 				goto done;
130*5fe11e25SDavid du Colombier 			break;
131*5fe11e25SDavid du Colombier 		case '\n':
132*5fe11e25SDavid du Colombier 			break;
133*5fe11e25SDavid du Colombier 		default:
134*5fe11e25SDavid du Colombier 			fprint(2, "unknown character in board solution: %c\n", c);
135*5fe11e25SDavid du Colombier 			goto done;
136*5fe11e25SDavid du Colombier 		}
137*5fe11e25SDavid du Colombier 	}
138*5fe11e25SDavid du Colombier 
139*5fe11e25SDavid du Colombier done:
140*5fe11e25SDavid du Colombier 	Bterm(b);
141*5fe11e25SDavid du Colombier 
142*5fe11e25SDavid du Colombier 	return i < 81 ? 0 : 1;
143*5fe11e25SDavid du Colombier }
144*5fe11e25SDavid du Colombier 
145*5fe11e25SDavid du Colombier void
printboard(Cell * board)146*5fe11e25SDavid du Colombier printboard(Cell *board)
147*5fe11e25SDavid du Colombier {
148*5fe11e25SDavid du Colombier 	int fd;
149*5fe11e25SDavid du Colombier 
150*5fe11e25SDavid du Colombier 	fd = create("/tmp/sudoku-board", OWRITE|OTRUNC, 0600);
151*5fe11e25SDavid du Colombier 	if(fd < 0) {
152*5fe11e25SDavid du Colombier 		perror("can not open save file /tmp/sudoku-save");
153*5fe11e25SDavid du Colombier 		return;
154*5fe11e25SDavid du Colombier 	}
155*5fe11e25SDavid du Colombier 
156*5fe11e25SDavid du Colombier 	fprintbrd(fd, board);
157*5fe11e25SDavid du Colombier 
158*5fe11e25SDavid du Colombier 	close(fd);
159*5fe11e25SDavid du Colombier }
160*5fe11e25SDavid du Colombier 
161*5fe11e25SDavid du Colombier void
savegame(Cell * board)162*5fe11e25SDavid du Colombier savegame(Cell *board)
163*5fe11e25SDavid du Colombier {
164*5fe11e25SDavid du Colombier 	int fd;
165*5fe11e25SDavid du Colombier 
166*5fe11e25SDavid du Colombier 	fd = create("/tmp/sudoku-save", OWRITE|OTRUNC, 0600);
167*5fe11e25SDavid du Colombier 	if(fd < 0) {
168*5fe11e25SDavid du Colombier 		perror("can not open save file /tmp/sudoku-save");
169*5fe11e25SDavid du Colombier 		return;
170*5fe11e25SDavid du Colombier 	}
171*5fe11e25SDavid du Colombier 
172*5fe11e25SDavid du Colombier 	if(write(fd, board, Psize * sizeof(Cell)) != Psize * sizeof(Cell)) {
173*5fe11e25SDavid du Colombier 		perror("could not save to file");
174*5fe11e25SDavid du Colombier 		close(fd);
175*5fe11e25SDavid du Colombier 	}
176*5fe11e25SDavid du Colombier 
177*5fe11e25SDavid du Colombier 	close(fd);
178*5fe11e25SDavid du Colombier }
179*5fe11e25SDavid du Colombier 
180*5fe11e25SDavid du Colombier int
loadgame(Cell * board)181*5fe11e25SDavid du Colombier loadgame(Cell *board)
182*5fe11e25SDavid du Colombier {
183*5fe11e25SDavid du Colombier 	int fd;
184*5fe11e25SDavid du Colombier 
185*5fe11e25SDavid du Colombier 	fd = open("/tmp/sudoku-save", OREAD);
186*5fe11e25SDavid du Colombier 	if(fd < 0) {
187*5fe11e25SDavid du Colombier 		perror("can not open save file /tmp/sudoku-save");
188*5fe11e25SDavid du Colombier 		return -1;
189*5fe11e25SDavid du Colombier 	}
190*5fe11e25SDavid du Colombier 
191*5fe11e25SDavid du Colombier 	if(read(fd, board, Psize * sizeof(Cell)) != Psize * sizeof(Cell)) {
192*5fe11e25SDavid du Colombier 		perror("insufficient data in save file");
193*5fe11e25SDavid du Colombier 		close(fd);
194*5fe11e25SDavid du Colombier 		return -1;
195*5fe11e25SDavid du Colombier 	}
196*5fe11e25SDavid du Colombier 
197*5fe11e25SDavid du Colombier 	close(fd);
198*5fe11e25SDavid du Colombier 
199*5fe11e25SDavid du Colombier 	return 1;
200*5fe11e25SDavid du Colombier }
201