aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2005-05-01 13:22:44 +0000
committerSimon Tatham <anakin@pobox.com>2005-05-01 13:22:44 +0000
commitcb413f837b685393666a0ccb63b1a94119acb435 (patch)
tree7bbb218f6375b874234c3e7f6347be1a35a4acb2
parent791940b043d500c096a56d57467b4b68ea31ce1f (diff)
downloadpuzzles-cb413f837b685393666a0ccb63b1a94119acb435.zip
puzzles-cb413f837b685393666a0ccb63b1a94119acb435.tar.gz
puzzles-cb413f837b685393666a0ccb63b1a94119acb435.tar.bz2
puzzles-cb413f837b685393666a0ccb63b1a94119acb435.tar.xz
Copy-to-clipboard facility for Fifteen, Sixteen and Twiddle.
[originally from svn r5725]
-rw-r--r--fifteen.c41
-rw-r--r--sixteen.c38
-rw-r--r--twiddle.c46
3 files changed, 119 insertions, 6 deletions
diff --git a/fifteen.c b/fifteen.c
index 3fad78a..8439faa 100644
--- a/fifteen.c
+++ b/fifteen.c
@@ -372,7 +372,44 @@ static void free_game(game_state *state)
static char *game_text_format(game_state *state)
{
- return NULL;
+ char *ret, *p, buf[80];
+ int x, y, col, maxlen;
+
+ /*
+ * First work out how many characters we need to display each
+ * number.
+ */
+ col = sprintf(buf, "%d", state->n-1);
+
+ /*
+ * Now we know the exact total size of the grid we're going to
+ * produce: it's got h rows, each containing w lots of col, w-1
+ * spaces and a trailing newline.
+ */
+ maxlen = state->h * state->w * (col+1);
+
+ ret = snewn(maxlen, char);
+ p = ret;
+
+ for (y = 0; y < state->h; y++) {
+ for (x = 0; x < state->w; x++) {
+ int v = state->tiles[state->w*y+x];
+ if (v == 0)
+ sprintf(buf, "%*s", col, "");
+ else
+ sprintf(buf, "%*d", col, v);
+ memcpy(p, buf, col);
+ p += col;
+ if (x+1 == state->w)
+ *p++ = '\n';
+ else
+ *p++ = ' ';
+ }
+ }
+
+ assert(p - ret == maxlen);
+ *p = '\0';
+ return ret;
}
static game_ui *new_ui(game_state *state)
@@ -743,7 +780,7 @@ const struct game thegame = {
new_game,
dup_game,
free_game,
- FALSE, game_text_format,
+ TRUE, game_text_format,
new_ui,
free_ui,
make_move,
diff --git a/sixteen.c b/sixteen.c
index 3a5d722..4611e3c 100644
--- a/sixteen.c
+++ b/sixteen.c
@@ -381,7 +381,41 @@ static void free_game(game_state *state)
static char *game_text_format(game_state *state)
{
- return NULL;
+ char *ret, *p, buf[80];
+ int x, y, col, maxlen;
+
+ /*
+ * First work out how many characters we need to display each
+ * number.
+ */
+ col = sprintf(buf, "%d", state->n);
+
+ /*
+ * Now we know the exact total size of the grid we're going to
+ * produce: it's got h rows, each containing w lots of col, w-1
+ * spaces and a trailing newline.
+ */
+ maxlen = state->h * state->w * (col+1);
+
+ ret = snewn(maxlen, char);
+ p = ret;
+
+ for (y = 0; y < state->h; y++) {
+ for (x = 0; x < state->w; x++) {
+ int v = state->tiles[state->w*y+x];
+ sprintf(buf, "%*d", col, v);
+ memcpy(p, buf, col);
+ p += col;
+ if (x+1 == state->w)
+ *p++ = '\n';
+ else
+ *p++ = ' ';
+ }
+ }
+
+ assert(p - ret == maxlen);
+ *p = '\0';
+ return ret;
}
static game_ui *new_ui(game_state *state)
@@ -793,7 +827,7 @@ const struct game thegame = {
new_game,
dup_game,
free_game,
- FALSE, game_text_format,
+ TRUE, game_text_format,
new_ui,
free_ui,
make_move,
diff --git a/twiddle.c b/twiddle.c
index 4bfd30c..162f68b 100644
--- a/twiddle.c
+++ b/twiddle.c
@@ -454,7 +454,49 @@ static void free_game(game_state *state)
static char *game_text_format(game_state *state)
{
- return NULL;
+ char *ret, *p, buf[80];
+ int i, x, y, col, o, maxlen;
+
+ /*
+ * First work out how many characters we need to display each
+ * number. We're pretty flexible on grid contents here, so we
+ * have to scan the entire grid.
+ */
+ col = 0;
+ for (i = 0; i < state->w * state->h; i++) {
+ x = sprintf(buf, "%d", state->grid[i] / 4);
+ if (col < x) col = x;
+ }
+ o = (state->orientable ? 1 : 0);
+
+ /*
+ * Now we know the exact total size of the grid we're going to
+ * produce: it's got h rows, each containing w lots of col+o,
+ * w-1 spaces and a trailing newline.
+ */
+ maxlen = state->h * state->w * (col+o+1);
+
+ ret = snewn(maxlen, char);
+ p = ret;
+
+ for (y = 0; y < state->h; y++) {
+ for (x = 0; x < state->w; x++) {
+ int v = state->grid[state->w*y+x];
+ sprintf(buf, "%*d", col, v/4);
+ memcpy(p, buf, col);
+ p += col;
+ if (o)
+ *p++ = "^<v>"[v & 3];
+ if (x+1 == state->w)
+ *p++ = '\n';
+ else
+ *p++ = ' ';
+ }
+ }
+
+ assert(p - ret == maxlen);
+ *p = '\0';
+ return ret;
}
static game_ui *new_ui(game_state *state)
@@ -947,7 +989,7 @@ const struct game thegame = {
new_game,
dup_game,
free_game,
- FALSE, game_text_format,
+ TRUE, game_text_format,
new_ui,
free_ui,
make_move,