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