+static game_state *execute_move(game_state *from, char *move)
+{
+ int i, n;
+ game_state *ret;
+
+ if (move[0] == 'M') {
+ ret = dup_game(from);
+
+ n = 0;
+ move++;
+
+ while (*move) {
+ i = atoi(move);
+ if (i < 0 || i >= ret->n) {
+ free_game(ret);
+ return NULL;
+ }
+ n++;
+ ret->tiles[i] = 0;
+
+ while (*move && isdigit((unsigned char)*move)) move++;
+ if (*move == ',') move++;
+ }
+
+ ret->score += npoints(&ret->params, n);
+
+ sg_snuggle(ret); /* shifts blanks down and to the left */
+ sg_check(ret); /* checks for completeness or impossibility */
+
+ return ret;
+ } else
+ return NULL; /* couldn't parse move string */
+}
+