Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/games/cgram Add a curses gizmo for solving Sunday-paper-type...



details:   https://anonhg.NetBSD.org/src/rev/e6fb688e0116
branches:  trunk
changeset: 789019:e6fb688e0116
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Aug 04 05:42:47 2013 +0000

description:
Add a curses gizmo for solving Sunday-paper-type cryptograms based on
substitution ciphers. It gets the cleartext from fortune. I wrote this
some years ago for my own amusement; a couple people have suggested
that I should import it.

Approved only by groo, so I'm going to wait a couple days to hook it
to the build in case anyone demands it be removed again...

diffstat:

 games/cgram/Makefile    |   10 +
 games/cgram/cgram.6     |   64 ++++++++
 games/cgram/cgram.c     |  344 ++++++++++++++++++++++++++++++++++++++++++++++++
 games/cgram/pathnames.h |   30 ++++
 4 files changed, 448 insertions(+), 0 deletions(-)

diffs (truncated from 464 to 300 lines):

diff -r eaa3b94fe13d -r e6fb688e0116 games/cgram/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/games/cgram/Makefile      Sun Aug 04 05:42:47 2013 +0000
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2013/08/04 05:42:47 dholland Exp $
+
+PROG=cgram
+DPADD=${LIBCURSES} ${LIBTERMINFO}
+LDADD=-lcurses -lterminfo
+SRCS=cgram.c
+MAN=cgram.6
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff -r eaa3b94fe13d -r e6fb688e0116 games/cgram/cgram.6
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/games/cgram/cgram.6       Sun Aug 04 05:42:47 2013 +0000
@@ -0,0 +1,64 @@
+.\"
+.\" Copyright (c) 2004, 2013 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by David A. Holland.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd August 3, 2013
+.Dt CGRAM 6
+.Os
+.Sh NAME
+.Nm cgram
+.Nd solve Sunday-paper cryptograms
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+is a curses-based widget for solving Sunday-paper-type cryptograms
+based on substitution ciphers.
+A random cleartext is chosen using
+.Xr fortune 6
+and a random substitution key is generated.
+.Pp
+The ciphertext is displayed.
+Typing a letter changes the key so that the letter under the cursor
+maps to the newly typed letter, and updates the display accordingly.
+Use Emacs-type cursor commands to move around.
+Enter a tilde
+.Pq ~
+to quit.
+Press asterisk
+.Pq *
+to enter an easier mode where correct letters are displayed in
+boldface.
+.Sh SEE ALSO
+.Xr caesar 6
+.Sh HISTORY
+.Nm
+was written circa 2004.
+It was imported into
+.Nx
+in 2013 and first appeared in
+.Nx 7.0 .
diff -r eaa3b94fe13d -r e6fb688e0116 games/cgram/cgram.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/games/cgram/cgram.c       Sun Aug 04 05:42:47 2013 +0000
@@ -0,0 +1,344 @@
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by David A. Holland.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+#include <err.h>
+#include <assert.h>
+#include <curses.h>
+#include "pathnames.h"
+
+////////////////////////////////////////////////////////////
+
+static char *xstrdup(const char *s) {
+   char *ret;
+
+   ret = malloc(strlen(s) + 1);
+   if (ret == NULL) {
+      errx(1, "Out of memory");
+   }
+   strcpy(ret, s);
+   return ret;
+}
+
+////////////////////////////////////////////////////////////
+
+struct stringarray {
+   char **v;
+   int num;
+};
+
+static void stringarray_init(struct stringarray *a) {
+   a->v = NULL;
+   a->num = 0;
+}
+
+static void stringarray_cleanup(struct stringarray *a) {
+   free(a->v);
+}
+
+static void stringarray_add(struct stringarray *a, const char *s) {
+   a->v = realloc(a->v, (a->num + 1) * sizeof(a->v[0]));
+   if (a->v == NULL) {
+      errx(1, "Out of memory");
+   }
+   a->v[a->num] = xstrdup(s);
+   a->num++;
+}
+
+////////////////////////////////////////////////////////////
+
+static struct stringarray lines;
+static struct stringarray sollines;
+static bool hinting;
+static int scrolldown;
+static unsigned curx;
+static int cury;
+
+static void readquote(void) {
+   FILE *f = popen(_PATH_FORTUNE, "r");
+   if (!f) {
+      err(1, "%s", _PATH_FORTUNE);
+   }
+
+   char buf[128], buf2[8*sizeof(buf)];
+   while (fgets(buf, sizeof(buf), f)) {
+      char *s = strrchr(buf, '\n');
+      assert(s);
+      assert(strlen(s)==1);
+      *s = 0;
+
+      int i,j;
+      for (i=j=0; buf[i]; i++) {
+        if (buf[i]=='\t') {
+           buf2[j++] = ' ';
+           while (j%8) buf2[j++] = ' ';
+        }
+        else if (buf[i]=='\b') {
+           if (j>0) j--;
+        }
+        else {
+           buf2[j++] = buf[i];
+        }
+      }
+      buf2[j] = 0;
+
+      stringarray_add(&lines, buf2);
+      stringarray_add(&sollines, buf2);
+   }
+
+   pclose(f);
+}
+
+static void encode(void) {
+   int used[26];
+   for (int i=0; i<26; i++) used[i] = 0;
+
+   int key[26];
+   int keypos=0;
+   while (keypos < 26) {
+      int c = random()%26;
+      if (used[c]) continue;
+      key[keypos++] = c;
+      used[c] = 1;
+   }
+
+   for (int y=0; y<lines.num; y++) {
+      for (unsigned x=0; lines.v[y][x]; x++) {
+        if (islower((unsigned char)lines.v[y][x])) {
+           int q = lines.v[y][x]-'a';
+           lines.v[y][x] = 'a'+key[q];
+        }
+        if (isupper((unsigned char)lines.v[y][x])) {
+           int q = lines.v[y][x]-'A';
+           lines.v[y][x] = 'A'+key[q];
+        }
+      }
+   }
+}
+
+static int substitute(int ch) {
+   assert(cury>=0 && cury<lines.num);
+   if (curx >= strlen(lines.v[cury])) {
+      beep();
+      return -1;
+   }
+
+   int och = lines.v[cury][curx];
+   if (!isalpha((unsigned char)och)) {
+      beep();
+      return -1;
+   }
+
+   int loch = tolower((unsigned char)och);
+   int uoch = toupper((unsigned char)och);
+   int lch = tolower((unsigned char)ch);
+   int uch = toupper((unsigned char)ch);
+
+   for (int y=0; y<lines.num; y++) {
+      for (unsigned x=0; lines.v[y][x]; x++) {
+        if (lines.v[y][x]==loch) {
+           lines.v[y][x] = lch;
+        }
+        else if (lines.v[y][x]==uoch) {
+           lines.v[y][x] = uch;
+        }
+        else if (lines.v[y][x]==lch) {
+           lines.v[y][x] = loch;
+        }
+        else if (lines.v[y][x]==uch) {
+           lines.v[y][x] = uoch;
+        }
+      }
+   }
+   return 0;
+}
+
+////////////////////////////////////////////////////////////
+
+static void redraw(void) {
+   erase();
+   bool won = true;
+   for (int i=0; i<LINES-1; i++) {
+      move(i, 0);
+      int ln = i+scrolldown;
+      if (ln < lines.num) {
+        for (unsigned j=0; lines.v[i][j]; j++) {
+           int ch = lines.v[i][j];
+           if (ch != sollines.v[i][j] && isalpha((unsigned char)ch)) {
+              won = false;
+           }
+           bool bold=false;
+           if (hinting && ch==sollines.v[i][j] &&
+               isalpha((unsigned char)ch)) {
+              bold = true;
+              attron(A_BOLD);
+           }
+           addch(lines.v[i][j]);
+           if (bold) {
+              attroff(A_BOLD);
+           }
+        }
+      }
+      clrtoeol();
+   }
+



Home | Main Index | Thread Index | Old Index