Thu Jul 2 19:11:01 2020 UTC ()
cgram(6): use standard cursor keys, use standard shuffle algorithm

The previous shuffle algorithm asked for 100 random numbers, on average.
The new algorithm asks exactly for 26 random numbers.

Curses predefines numeric constants for keys, and there is no apparent
reason not to use these standard keys for cursor movement.


(rillig)
diff -r1.1 -r1.2 src/games/cgram/cgram.c

cvs diff -r1.1 -r1.2 src/games/cgram/cgram.c (expand / switch to unified diff)

--- src/games/cgram/cgram.c 2013/08/04 05:42:47 1.1
+++ src/games/cgram/cgram.c 2020/07/02 19:11:01 1.2
@@ -110,36 +110,33 @@ static void readquote(void) { @@ -110,36 +110,33 @@ static void readquote(void) {
110 buf2[j++] = buf[i]; 110 buf2[j++] = buf[i];
111 } 111 }
112 } 112 }
113 buf2[j] = 0; 113 buf2[j] = 0;
114 114
115 stringarray_add(&lines, buf2); 115 stringarray_add(&lines, buf2);
116 stringarray_add(&sollines, buf2); 116 stringarray_add(&sollines, buf2);
117 } 117 }
118 118
119 pclose(f); 119 pclose(f);
120} 120}
121 121
122static void encode(void) { 122static void encode(void) {
123 int used[26]; 
124 for (int i=0; i<26; i++) used[i] = 0; 
125 
126 int key[26]; 123 int key[26];
127 int keypos=0; 124 for (int i=0; i<26; i++) key[i] = i;
128 while (keypos < 26) { 125 for (int i=26; i>1; i--) {
129 int c = random()%26; 126 int c = random() % i;
130 if (used[c]) continue; 127 int t = key[i-1];
131 key[keypos++] = c; 128 key[i-1] = key[c];
132 used[c] = 1; 129 key[c] = t;
133 } 130 }
134 131
135 for (int y=0; y<lines.num; y++) { 132 for (int y=0; y<lines.num; y++) {
136 for (unsigned x=0; lines.v[y][x]; x++) { 133 for (unsigned x=0; lines.v[y][x]; x++) {
137 if (islower((unsigned char)lines.v[y][x])) { 134 if (islower((unsigned char)lines.v[y][x])) {
138 int q = lines.v[y][x]-'a'; 135 int q = lines.v[y][x]-'a';
139 lines.v[y][x] = 'a'+key[q]; 136 lines.v[y][x] = 'a'+key[q];
140 } 137 }
141 if (isupper((unsigned char)lines.v[y][x])) { 138 if (isupper((unsigned char)lines.v[y][x])) {
142 int q = lines.v[y][x]-'A'; 139 int q = lines.v[y][x]-'A';
143 lines.v[y][x] = 'A'+key[q]; 140 lines.v[y][x] = 'A'+key[q];
144 } 141 }
145 } 142 }
@@ -234,64 +231,70 @@ static void opencurses(void) { @@ -234,64 +231,70 @@ static void opencurses(void) {
234static void closecurses(void) { 231static void closecurses(void) {
235 endwin(); 232 endwin();
236} 233}
237 234
238//////////////////////////////////////////////////////////// 235////////////////////////////////////////////////////////////
239 236
240static void loop(void) { 237static void loop(void) {
241 bool done=false; 238 bool done=false;
242 while (!done) { 239 while (!done) {
243 redraw(); 240 redraw();
244 int ch = getch(); 241 int ch = getch();
245 switch (ch) { 242 switch (ch) {
246 case 1: /* ^A */ 243 case 1: /* ^A */
 244 case KEY_BEG:
247 curx=0; 245 curx=0;
248 break; 246 break;
249 case 2: /* ^B */ 247 case 2: /* ^B */
 248 case KEY_LEFT:
250 if (curx > 0) { 249 if (curx > 0) {
251 curx--; 250 curx--;
252 } 251 }
253 else if (cury > 0) { 252 else if (cury > 0) {
254 cury--; 253 cury--;
255 curx = strlen(lines.v[cury]); 254 curx = strlen(lines.v[cury]);
256 } 255 }
257 break; 256 break;
258 case 5: /* ^E */ 257 case 5: /* ^E */
 258 case KEY_END:
259 curx = strlen(lines.v[cury]); 259 curx = strlen(lines.v[cury]);
260 break; 260 break;
261 case 6: /* ^F */ 261 case 6: /* ^F */
 262 case KEY_RIGHT:
262 if (curx < strlen(lines.v[cury])) { 263 if (curx < strlen(lines.v[cury])) {
263 curx++; 264 curx++;
264 } 265 }
265 else if (cury < lines.num - 1) { 266 else if (cury < lines.num - 1) {
266 cury++; 267 cury++;
267 curx = 0; 268 curx = 0;
268 } 269 }
269 break; 270 break;
270 case 12: /* ^L */ 271 case 12: /* ^L */
271 clear(); 272 clear();
272 break; 273 break;
273 case 14: /* ^N */ 274 case 14: /* ^N */
 275 case KEY_DOWN:
274 if (cury < lines.num-1) { 276 if (cury < lines.num-1) {
275 cury++; 277 cury++;
276 } 278 }
277 if (curx > strlen(lines.v[cury])) { 279 if (curx > strlen(lines.v[cury])) {
278 curx = strlen(lines.v[cury]); 280 curx = strlen(lines.v[cury]);
279 } 281 }
280 if (scrolldown < cury - (LINES-2)) { 282 if (scrolldown < cury - (LINES-2)) {
281 scrolldown = cury - (LINES-2); 283 scrolldown = cury - (LINES-2);
282 } 284 }
283 break; 285 break;
284 case 16: /* ^P */ 286 case 16: /* ^P */
 287 case KEY_UP:
285 if (cury > 0) { 288 if (cury > 0) {
286 cury--; 289 cury--;
287 } 290 }
288 if (curx > strlen(lines.v[cury])) { 291 if (curx > strlen(lines.v[cury])) {
289 curx = strlen(lines.v[cury]); 292 curx = strlen(lines.v[cury]);
290 } 293 }
291 if (scrolldown > cury) { 294 if (scrolldown > cury) {
292 scrolldown = cury; 295 scrolldown = cury;
293 } 296 }
294 break; 297 break;
295 case '*': 298 case '*':
296 hinting = !hinting; 299 hinting = !hinting;
297 break; 300 break;
@@ -325,20 +328,21 @@ static void loop(void) { @@ -325,20 +328,21 @@ static void loop(void) {
325 } 328 }
326} 329}
327 330
328//////////////////////////////////////////////////////////// 331////////////////////////////////////////////////////////////
329 332
330int main(void) { 333int main(void) {
331 stringarray_init(&lines); 334 stringarray_init(&lines);
332 stringarray_init(&sollines); 335 stringarray_init(&sollines);
333 srandom(time(NULL)); 336 srandom(time(NULL));
334 readquote(); 337 readquote();
335 encode(); 338 encode();
336 opencurses(); 339 opencurses();
337 340
 341 keypad(stdscr, TRUE);
338 loop(); 342 loop();
339 343
340 closecurses(); 344 closecurses();
341 stringarray_cleanup(&sollines); 345 stringarray_cleanup(&sollines);
342 stringarray_cleanup(&lines); 346 stringarray_cleanup(&lines);
343 return 0; 347 return 0;
344} 348}