예제 #1
0
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
			    int x, int y, int button)
{
    int gx, gy, dx, dy;
    char buf[80];

    button &= ~MOD_MASK;

    gx = X(state, state->gap_pos);
    gy = Y(state, state->gap_pos);

    if (button == CURSOR_RIGHT && gx > 0)
        dx = gx - 1, dy = gy;
    else if (button == CURSOR_LEFT && gx < state->w-1)
        dx = gx + 1, dy = gy;
    else if (button == CURSOR_DOWN && gy > 0)
        dy = gy - 1, dx = gx;
    else if (button == CURSOR_UP && gy < state->h-1)
        dy = gy + 1, dx = gx;
    else if (button == LEFT_BUTTON) {
        dx = FROMCOORD(x);
        dy = FROMCOORD(y);
        if (dx < 0 || dx >= state->w || dy < 0 || dy >= state->h)
            return NULL;               /* out of bounds */
        /*
         * Any click location should be equal to the gap location
         * in _precisely_ one coordinate.
         */
        if ((dx == gx && dy == gy) || (dx != gx && dy != gy))
            return NULL;
    } else
        return NULL;                   /* no move */

    sprintf(buf, "M%d,%d", dx, dy);
    return dupstr(buf);
}
예제 #2
0
파일: towers.c 프로젝트: xymus/sgtpuzzles
static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
			    int x, int y, int button)
{
    int w = state->par.w;
    int tx, ty;
    char buf[80];

    button &= ~MOD_MASK;

    tx = FROMCOORD(x);
    ty = FROMCOORD(y);

    if (ds->three_d) {
	/*
	 * In 3D mode, just locating the mouse click in the natural
	 * square grid may not be sufficient to tell which tower the
	 * user clicked on. Investigate the _tops_ of the nearby
	 * towers to see if a click on one grid square was actually
	 * a click on a tower protruding into that region from
	 * another.
	 */
	int dx, dy;
	for (dy = 0; dy <= 1; dy++)
	    for (dx = 0; dx >= -1; dx--) {
		int cx = tx + dx, cy = ty + dy;
		if (cx >= 0 && cx < w && cy >= 0 && cy < w) {
		    int height = state->grid[cy*w+cx];
		    int bx = COORD(cx), by = COORD(cy);
		    int ox = bx + X_3D_DISP(height, w);
		    int oy = by - Y_3D_DISP(height, w);
		    if (/* on top face? */
			(x - ox >= 0 && x - ox < TILESIZE &&
			 y - oy >= 0 && y - oy < TILESIZE) ||
			/* in triangle between top-left corners? */
			(ox > bx && x >= bx && x <= ox && y <= by &&
			 (by-y) * (ox-bx) <= (by-oy) * (x-bx)) ||
			/* in triangle between bottom-right corners? */
			(ox > bx && x >= bx+TILESIZE && x <= ox+TILESIZE &&
			 y >= oy+TILESIZE &&
			 (by-y+TILESIZE)*(ox-bx) >= (by-oy)*(x-bx-TILESIZE))) {
			tx = cx;
			ty = cy;
		    }
		}
	    }
    }

    if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
        if (button == LEFT_BUTTON) {
	    if (tx == ui->hx && ty == ui->hy &&
		ui->hshow && ui->hpencil == 0) {
                ui->hshow = 0;
            } else {
                ui->hx = tx;
                ui->hy = ty;
		ui->hshow = !state->clues->immutable[ty*w+tx];
                ui->hpencil = 0;
            }
            ui->hcursor = 0;
            return "";		       /* UI activity occurred */
        }
        if (button == RIGHT_BUTTON) {
            /*
             * Pencil-mode highlighting for non filled squares.
             */
            if (state->grid[ty*w+tx] == 0) {
                if (tx == ui->hx && ty == ui->hy &&
                    ui->hshow && ui->hpencil) {
                    ui->hshow = 0;
                } else {
                    ui->hpencil = 1;
                    ui->hx = tx;
                    ui->hy = ty;
                    ui->hshow = 1;
                }
            } else {
                ui->hshow = 0;
            }
            ui->hcursor = 0;
            return "";		       /* UI activity occurred */
        }
    }
    if (IS_CURSOR_MOVE(button)) {
        move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
        ui->hshow = ui->hcursor = 1;
        return "";
    }
    if (ui->hshow &&
        (button == CURSOR_SELECT)) {
        ui->hpencil = 1 - ui->hpencil;
        ui->hcursor = 1;
        return "";
    }

    if (ui->hshow &&
	((button >= '0' && button <= '9' && button - '0' <= w) ||
	 button == CURSOR_SELECT2 || button == '\b')) {
	int n = button - '0';
	if (button == CURSOR_SELECT2 || button == '\b')
	    n = 0;

        /*
         * Can't make pencil marks in a filled square. This can only
         * become highlighted if we're using cursor keys.
         */
        if (ui->hpencil && state->grid[ui->hy*w+ui->hx])
            return NULL;

	/*
	 * Can't do anything to an immutable square.
	 */
        if (state->clues->immutable[ui->hy*w+ui->hx])
            return NULL;

	sprintf(buf, "%c%d,%d,%d",
		(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);

        if (!ui->hcursor) ui->hshow = 0;

	return dupstr(buf);
    }

    if (button == 'M' || button == 'm')
        return dupstr("M");

    return NULL;
}
예제 #3
0
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
			    int x, int y, int button)
{
    int w = state->w, h = state->h, n = state->n /* , wh = w*h */;
    char buf[80];
    int dir;

    button = button & (~MOD_MASK | MOD_NUM_KEYPAD);

    if (IS_CURSOR_MOVE(button)) {
        if (button == CURSOR_LEFT && ui->cur_x > 0)
            ui->cur_x--;
        if (button == CURSOR_RIGHT && (ui->cur_x+n) < (w))
            ui->cur_x++;
        if (button == CURSOR_UP && ui->cur_y > 0)
            ui->cur_y--;
        if (button == CURSOR_DOWN && (ui->cur_y+n) < (h))
            ui->cur_y++;
        ui->cur_visible = 1;
        return "";
    }

    if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
	/*
	 * Determine the coordinates of the click. We offset by n-1
	 * half-blocks so that the user must click at the centre of
	 * a rotation region rather than at the corner.
	 */
	x -= (n-1) * TILE_SIZE / 2;
	y -= (n-1) * TILE_SIZE / 2;
	x = FROMCOORD(x);
	y = FROMCOORD(y);
	dir = (button == LEFT_BUTTON ? 1 : -1);
	if (x < 0 || x > w-n || y < 0 || y > h-n)
	    return NULL;
        ui->cur_visible = 0;
    } else if (IS_CURSOR_SELECT(button)) {
        if (ui->cur_visible) {
            x = ui->cur_x;
            y = ui->cur_y;
            dir = (button == CURSOR_SELECT2) ? -1 : +1;
        } else {
            ui->cur_visible = 1;
            return "";
        }
    } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') {
        x = y = 0;
        dir = (button == 'A' ? -1 : +1);
    } else if (button == 'b' || button == 'B' || button==MOD_NUM_KEYPAD+'9') {
        x = w-n;
        y = 0;
        dir = (button == 'B' ? -1 : +1);
    } else if (button == 'c' || button == 'C' || button==MOD_NUM_KEYPAD+'1') {
        x = 0;
        y = h-n;
        dir = (button == 'C' ? -1 : +1);
    } else if (button == 'd' || button == 'D' || button==MOD_NUM_KEYPAD+'3') {
        x = w-n;
        y = h-n;
        dir = (button == 'D' ? -1 : +1);
    } else if (button==MOD_NUM_KEYPAD+'8' && (w-n) % 2 == 0) {
        x = (w-n) / 2;
        y = 0;
        dir = +1;
    } else if (button==MOD_NUM_KEYPAD+'2' && (w-n) % 2 == 0) {
        x = (w-n) / 2;
        y = h-n;
        dir = +1;
    } else if (button==MOD_NUM_KEYPAD+'4' && (h-n) % 2 == 0) {
        x = 0;
        y = (h-n) / 2;
        dir = +1;
    } else if (button==MOD_NUM_KEYPAD+'6' && (h-n) % 2 == 0) {
        x = w-n;
        y = (h-n) / 2;
        dir = +1;
    } else if (button==MOD_NUM_KEYPAD+'5' && (w-n) % 2 == 0 && (h-n) % 2 == 0){
        x = (w-n) / 2;
        y = (h-n) / 2;
        dir = +1;
    } else {
        return NULL;                   /* no move to be made */
    }

    /*
     * If we reach here, we have a valid move.
     */
    sprintf(buf, "M%d,%d,%d", x, y, dir);
    return dupstr(buf);
}
예제 #4
0
파일: pattern.c 프로젝트: azaka/puzzless60
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
			    int x, int y, int button)
{
    button &= ~MOD_MASK;

    x = FROMCOORD(state->w, x);
    y = FROMCOORD(state->h, y);

    if (x >= 0 && x < state->w && y >= 0 && y < state->h &&
        (button == LEFT_BUTTON || button == RIGHT_BUTTON ||
         button == MIDDLE_BUTTON)) {
#ifdef STYLUS_BASED
        int currstate = state->grid[y * state->w + x];
#endif

        ui->dragging = TRUE;

        if (button == LEFT_BUTTON) {
            ui->drag = LEFT_DRAG;
            ui->release = LEFT_RELEASE;
#ifdef STYLUS_BASED
            ui->state = (currstate + 2) % 3; /* FULL -> EMPTY -> UNKNOWN */
#else
            ui->state = GRID_FULL;
#endif
        } else if (button == RIGHT_BUTTON) {
            ui->drag = RIGHT_DRAG;
            ui->release = RIGHT_RELEASE;
#ifdef STYLUS_BASED
            ui->state = (currstate + 1) % 3; /* EMPTY -> FULL -> UNKNOWN */
#else
            ui->state = GRID_EMPTY;
#endif
        } else /* if (button == MIDDLE_BUTTON) */ {
            ui->drag = MIDDLE_DRAG;
            ui->release = MIDDLE_RELEASE;
            ui->state = GRID_UNKNOWN;
        }

        ui->drag_start_x = ui->drag_end_x = x;
        ui->drag_start_y = ui->drag_end_y = y;
        ui->cur_visible = 0;

        return "";		       /* UI activity occurred */
    }

    if (ui->dragging && button == ui->drag) {
        /*
         * There doesn't seem much point in allowing a rectangle
         * drag; people will generally only want to drag a single
         * horizontal or vertical line, so we make that easy by
         * snapping to it.
         * 
         * Exception: if we're _middle_-button dragging to tag
         * things as UNKNOWN, we may well want to trash an entire
         * area and start over!
         */
        if (ui->state != GRID_UNKNOWN) {
            if (abs(x - ui->drag_start_x) > abs(y - ui->drag_start_y))
                y = ui->drag_start_y;
            else
                x = ui->drag_start_x;
        }

        if (x < 0) x = 0;
        if (y < 0) y = 0;
        if (x >= state->w) x = state->w - 1;
        if (y >= state->h) y = state->h - 1;

        ui->drag_end_x = x;
        ui->drag_end_y = y;

        return "";		       /* UI activity occurred */
    }

    if (ui->dragging && button == ui->release) {
        int x1, x2, y1, y2, xx, yy;
        int move_needed = FALSE;

        x1 = min(ui->drag_start_x, ui->drag_end_x);
        x2 = max(ui->drag_start_x, ui->drag_end_x);
        y1 = min(ui->drag_start_y, ui->drag_end_y);
        y2 = max(ui->drag_start_y, ui->drag_end_y);

        for (yy = y1; yy <= y2; yy++)
            for (xx = x1; xx <= x2; xx++)
                if (state->grid[yy * state->w + xx] != ui->state)
                    move_needed = TRUE;

        ui->dragging = FALSE;

        if (move_needed) {
	    char buf[80];
	    sprintf(buf, "%c%d,%d,%d,%d",
		    (char)(ui->state == GRID_FULL ? 'F' :
		           ui->state == GRID_EMPTY ? 'E' : 'U'),
		    x1, y1, x2-x1+1, y2-y1+1);
	    return dupstr(buf);
        } else
            return "";		       /* UI activity occurred */
    }

    if (IS_CURSOR_MOVE(button)) {
        move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0);
        ui->cur_visible = 1;
        return "";
    }
    if (IS_CURSOR_SELECT(button)) {
        int currstate = state->grid[ui->cur_y * state->w + ui->cur_x];
        int newstate;
        char buf[80];

        if (!ui->cur_visible) {
            ui->cur_visible = 1;
            return "";
        }

        if (button == CURSOR_SELECT2)
            newstate = currstate == GRID_UNKNOWN ? GRID_EMPTY :
                currstate == GRID_EMPTY ? GRID_FULL : GRID_UNKNOWN;
        else
            newstate = currstate == GRID_UNKNOWN ? GRID_FULL :
                currstate == GRID_FULL ? GRID_EMPTY : GRID_UNKNOWN;

        sprintf(buf, "%c%d,%d,%d,%d",
                (char)(newstate == GRID_FULL ? 'F' :
		       newstate == GRID_EMPTY ? 'E' : 'U'),
                ui->cur_x, ui->cur_y, 1, 1);
        return dupstr(buf);
    }

    return NULL;
}