X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=dominosa.c;h=dc7c2c7439536984f00e0a1d3c5bc482200920bf;hb=3ce69e84cad15844282d691fa03e711c5353c05e;hp=b0f11e11b8a81a31bbd4838de883e57c11e81b54;hpb=251b21c41813055d9c416378508b1ee038bc3dac;p=sgt-puzzles.git diff --git a/dominosa.c b/dominosa.c index b0f11e1..dc7c2c7 100644 --- a/dominosa.c +++ b/dominosa.c @@ -64,6 +64,8 @@ enum { COL_DOMINOCLASH, COL_DOMINOTEXT, COL_EDGE, + COL_HIGHLIGHT_1, + COL_HIGHLIGHT_2, NCOLOURS }; @@ -944,16 +946,78 @@ static char *solve_game(const game_state *state, const game_state *currstate, static int game_can_format_as_text_now(const game_params *params) { - return TRUE; + return params->n < 1000; +} + +static void draw_domino(char *board, int start, char corner, + int dshort, int nshort, char cshort, + int dlong, int nlong, char clong) +{ + int go_short = nshort*dshort, go_long = nlong*dlong, i; + + board[start] = corner; + board[start + go_short] = corner; + board[start + go_long] = corner; + board[start + go_short + go_long] = corner; + + for (i = 1; i < nshort; ++i) { + int j = start + i*dshort, k = start + i*dshort + go_long; + if (board[j] != corner) board[j] = cshort; + if (board[k] != corner) board[k] = cshort; + } + + for (i = 1; i < nlong; ++i) { + int j = start + i*dlong, k = start + i*dlong + go_short; + if (board[j] != corner) board[j] = clong; + if (board[k] != corner) board[k] = clong; + } } static char *game_text_format(const game_state *state) { - return NULL; + int w = state->w, h = state->h, r, c; + int cw = 4, ch = 2, gw = cw*w + 2, gh = ch * h + 1, len = gw * gh; + char *board = snewn(len + 1, char); + + memset(board, ' ', len); + + for (r = 0; r < h; ++r) { + for (c = 0; c < w; ++c) { + int cell = r*ch*gw + cw*c, center = cell + gw*ch/2 + cw/2; + int i = r*w + c, num = state->numbers->numbers[i]; + + if (num < 100) { + board[center] = '0' + num % 10; + if (num >= 10) board[center - 1] = '0' + num / 10; + } else { + board[center+1] = '0' + num % 10; + board[center] = '0' + num / 10 % 10; + board[center-1] = '0' + num / 100; + } + + if (state->edges[i] & EDGE_L) board[center - cw/2] = '|'; + if (state->edges[i] & EDGE_R) board[center + cw/2] = '|'; + if (state->edges[i] & EDGE_T) board[center - gw] = '-'; + if (state->edges[i] & EDGE_B) board[center + gw] = '-'; + + if (state->grid[i] == i) continue; /* no domino pairing */ + if (state->grid[i] < i) continue; /* already done */ + assert (state->grid[i] == i + 1 || state->grid[i] == i + w); + if (state->grid[i] == i + 1) + draw_domino(board, cell, '+', gw, ch, '|', +1, 2*cw, '-'); + else if (state->grid[i] == i + w) + draw_domino(board, cell, '+', +1, cw, '-', gw, 2*ch, '|'); + } + board[r*ch*gw + gw - 1] = '\n'; + board[r*ch*gw + gw + gw - 1] = '\n'; + } + board[len - 1] = '\n'; + board[len] = '\0'; + return board; } struct game_ui { - int cur_x, cur_y, cur_visible; + int cur_x, cur_y, cur_visible, highlight_1, highlight_2; }; static game_ui *new_ui(const game_state *state) @@ -961,6 +1025,7 @@ static game_ui *new_ui(const game_state *state) game_ui *ui = snew(game_ui); ui->cur_x = ui->cur_y = 0; ui->cur_visible = 0; + ui->highlight_1 = ui->highlight_2 = -1; return ui; } @@ -1072,6 +1137,22 @@ static char *interpret_move(const game_state *state, game_ui *ui, sprintf(buf, "%c%d,%d", (int)(button == CURSOR_SELECT2 ? 'E' : 'D'), d1, d2); return dupstr(buf); + } else if (isdigit(button)) { + int n = state->params.n, num = button - '0'; + if (num > n) { + return NULL; + } else if (ui->highlight_1 == num) { + ui->highlight_1 = -1; + } else if (ui->highlight_2 == num) { + ui->highlight_2 = -1; + } else if (ui->highlight_1 == -1) { + ui->highlight_1 = num; + } else if (ui->highlight_2 == -1) { + ui->highlight_2 = num; + } else { + return NULL; + } + return ""; } return NULL; @@ -1277,6 +1358,14 @@ static float *game_colours(frontend *fe, int *ncolours) ret[COL_EDGE * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 2 / 3; ret[COL_EDGE * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 2 / 3; + ret[COL_HIGHLIGHT_1 * 3 + 0] = 0.85; + ret[COL_HIGHLIGHT_1 * 3 + 1] = 0.20; + ret[COL_HIGHLIGHT_1 * 3 + 2] = 0.20; + + ret[COL_HIGHLIGHT_2 * 3 + 0] = 0.30; + ret[COL_HIGHLIGHT_2 * 3 + 1] = 0.85; + ret[COL_HIGHLIGHT_2 * 3 + 2] = 0.20; + *ncolours = NCOLOURS; return ret; } @@ -1317,6 +1406,8 @@ enum { * EDGE_* [0x100 -- 0xF00] * and must fit into an unsigned long (32 bits). */ +#define DF_HIGHLIGHT_1 0x10 +#define DF_HIGHLIGHT_2 0x20 #define DF_FLASH 0x40 #define DF_CLASH 0x80 @@ -1331,7 +1422,7 @@ enum { #define IS_EMPTY(s,x,y) ((s)->grid[(y)*(s)->w+(x)] == ((y)*(s)->w+(x))) static void draw_tile(drawing *dr, game_drawstate *ds, const game_state *state, - int x, int y, int type) + int x, int y, int type, int highlight_1, int highlight_2) { int w = state->w /*, h = state->h */; int cx = COORD(x), cy = COORD(y); @@ -1427,6 +1518,12 @@ static void draw_tile(drawing *dr, game_drawstate *ds, const game_state *state, draw_rect_corners(dr, ox, oy, CURSOR_RADIUS+1, nc); } + if (flags & DF_HIGHLIGHT_1) { + nc = COL_HIGHLIGHT_1; + } else if (flags & DF_HIGHLIGHT_2) { + nc = COL_HIGHLIGHT_2; + } + sprintf(str, "%d", state->numbers->numbers[y*w+x]); draw_text(dr, cx+TILESIZE/2, cy+TILESIZE/2, FONT_VARIABLE, TILESIZE/2, ALIGN_HCENTRE | ALIGN_VCENTRE, nc, str); @@ -1489,8 +1586,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds, else c = TYPE_BLANK; + n1 = state->numbers->numbers[n]; if (c != TYPE_BLANK) { - n1 = state->numbers->numbers[n]; n2 = state->numbers->numbers[state->grid[n]]; di = DINDEX(n1, n2); if (used[di] > 1) @@ -1499,6 +1596,11 @@ static void game_redraw(drawing *dr, game_drawstate *ds, c |= state->edges[n]; } + if (n1 == ui->highlight_1) + c |= DF_HIGHLIGHT_1; + if (n1 == ui->highlight_2) + c |= DF_HIGHLIGHT_2; + if (flashtime != 0) c |= DF_FLASH; /* we're flashing */ @@ -1515,7 +1617,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds, } if (ds->visible[n] != c) { - draw_tile(dr, ds, state, x, y, c); + draw_tile(dr, ds, state, x, y, c, + ui->highlight_1, ui->highlight_2); ds->visible[n] = c; } } @@ -1534,7 +1637,10 @@ static float game_flash_length(const game_state *oldstate, { if (!oldstate->completed && newstate->completed && !oldstate->cheated && !newstate->cheated) + { + ui->highlight_1 = ui->highlight_2 = -1; return FLASH_TIME; + } return 0.0F; } @@ -1592,7 +1698,7 @@ static void game_print(drawing *dr, const game_state *state, int tilesize) else c = TYPE_BLANK; - draw_tile(dr, ds, state, x, y, c); + draw_tile(dr, ds, state, x, y, c, -1, -1); } } @@ -1616,7 +1722,7 @@ const struct game thegame = { dup_game, free_game, TRUE, solve_game, - FALSE, game_can_format_as_text_now, game_text_format, + TRUE, game_can_format_as_text_now, game_text_format, new_ui, free_ui, encode_ui,