+ if (dx == 0)
+ sprintf(buf, "C%d,%d", cx, dy);
+ else
+ sprintf(buf, "R%d,%d", cy, dx);
+ return dupstr(buf);
+}
+
+static game_state *execute_move(game_state *from, char *move)
+{
+ game_state *ret;
+ int c, d, col;
+
+ if ((move[0] == 'C' || move[0] == 'R') &&
+ sscanf(move+1, "%d,%d", &c, &d) == 2 &&
+ c >= 0 && c < (move[0] == 'C' ? from->width : from->height)) {
+ col = (move[0] == 'C');
+ } else if (move[0] == 'S' &&
+ strlen(move) == from->width * from->height + 1) {
+ int i;
+ ret = dup_game(from);
+ ret->used_solve = TRUE;
+ ret->completed = ret->move_count = 1;
+
+ for (i = 0; i < from->width * from->height; i++) {
+ c = move[i+1];
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'F')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else {
+ free_game(ret);
+ return NULL;
+ }
+ ret->tiles[i] = c;
+ }
+ return ret;
+ } else
+ return NULL; /* can't parse move string */
+
+ ret = dup_game(from);