HP Prime for All
English
Русский
Name | Slider |
Description | Simple sliding panels game. |
Author | John Olwoch |
Source code formatted by website engine
BEGIN
LOCAL puzzle;
LOCAL finish := 0;
IF CHOOSE(puzzle, "Slider Puzzles",
"2x3",
"3x3", "3x4",
"4x3", "4x4", "4x5", "4x6",
"5x3", "5x4", "5x5", "5x6", "5x7") THEN
CHOOSEPUZZLE(puzzle);
MAKEBOARD();
DRAWBOARD();
REPEAT
touch := B→R(MOUSE());
IF SIZE(touch(1)) > 0 THEN
IF touch(1, 5) == 2 THEN
SWIPE();
END;
ELSE
CASE
IF ISKEYDOWN(8) THEN MOVE_R(); END;
IF ISKEYDOWN(7) THEN MOVE_L(); END;
IF ISKEYDOWN(12) THEN MOVE_D(); END;
IF ISKEYDOWN(2) THEN MOVE_U(); END;
IF ISKEYDOWN(4) OR ISKEYDOWN(5) THEN finish := 1; END; // Esc or Home to exit
END;
END;
UNTIL (finish == 1);
END;
END;
CHOOSEPUZZLE(puzzle)
BEGIN
CASE
IF puzzle == 1 THEN maxrow := 2; maxcol := 3; END;
IF puzzle == 2 THEN maxrow := 3; maxcol := 3; END;
IF puzzle == 3 THEN maxrow := 3; maxcol := 4; END;
IF puzzle == 4 THEN maxrow := 4; maxcol := 3; END;
IF puzzle == 5 THEN maxrow := 4; maxcol := 4; END;
IF puzzle == 6 THEN maxrow := 4; maxcol := 5; END;
IF puzzle == 7 THEN maxrow := 4; maxcol := 6; END;
IF puzzle == 8 THEN maxrow := 5; maxcol := 3; END;
IF puzzle == 9 THEN maxrow := 5; maxcol := 4; END;
IF puzzle == 10 THEN maxrow := 5; maxcol := 5; END;
IF puzzle == 11 THEN maxrow := 5; maxcol := 6; END;
IF puzzle == 12 THEN maxrow := 5; maxcol := 7; END;
END;
END;
//
// Make a solvable puzzle.
//
MAKEBOARD()
BEGIN
SHUFFLE();
MAKESOLVABLE();
END;
//
// Draws the board graphics.
//
DRAWBOARD()
BEGIN
LOCAL row, col, xpos, ypos;
//
// set up parameters
tileheight := CEILING(200/maxrow);
tilewidth := tileheight;
w := tilewidth-1; h := tileheight-1;
originX := FLOOR(screenX/2 - (tilewidth*maxcol) / 2);
originY := FLOOR(screenY/2 - (tileheight*maxrow) / 2);
fontX := FLOOR(tilewidth/2-25/2);
fontY := fontX;
//
RECT();
RECT_P(G0, originX-1, originY-1, originX+maxcol*tilewidth, originY+maxrow*tileheight, black, gold);
DIMGROB_P(G1, tilewidth, tileheight);
FOR row FROM 1 TO maxrow DO
FOR col FROM 1 TO maxcol DO
IF board(row, col) ≠ (maxrow*maxcol) THEN
RECT_P(G1, 0, 0, tilewidth-1, tileheight-1, black, red);
TEXTOUT_P(STRING(board(row, col)), G1, fontX, fontY, fontsize);
xpos := originX + (col-1) * tilewidth;
ypos := originY + (row-1) * tileheight;
BLIT_P(G0, xpos, ypos, G1);
END;
END;
END;
END;
//
// Create board with shuffled elements.
//
SHUFFLE()
BEGIN
LOCAL j, k, n;
// Create list and shuffle the elements.
L1 := MAKELIST(X, X, 1, maxrow*maxcol, 1);
FOR n FROM SIZE(L1) DOWNTO 1 DO
j := 1+RANDINT(n-1);
k := L1(j);
L1(j) := L1(n);
L1(n) := k;
END;
// Convert list to matrix.
LOCAL i, r, c;
i := 1;
board := MAKEMAT(0, maxrow, maxcol);
FOR r FROM 1 TO maxrow DO
FOR c FROM 1 TO maxcol DO
board(r, c) := L1(i);
// Get space coordinates.
IF board(r, c) == maxrow*maxcol THEN
spacerow := r; spacecol := c;
END;
i := i+1;
END;
END;
END;
//
// Count no of inversions for each tile.
//
INVERSIONS()
BEGIN
LOCAL i, j, inv;
inv := 0;
FOR j FROM 1 TO SIZE(L1) - 1 DO
IF L1(j) ≠ (maxrow*maxcol) THEN
FOR i FROM j+1 TO SIZE(L1) DO
IF L1(j) > L1(i) THEN
inv := inv+1;
END;
END;
END;
END;
RETURN inv;
END;
//
// Check if game is solvable.
//
ISSOLVABLE()
BEGIN
IF (maxcol MOD 2) == 1 THEN
RETURN (INVERSIONS() MOD 2) == 0;
ELSE
RETURN ((INVERSIONS() + maxrow-spacerow) MOD 2) == 0;
END;
END;
//
// Make solvable if not so.
//
MAKESOLVABLE()
BEGIN
IF NOT ISSOLVABLE() THEN
IF (spacerow == 1) AND (spacecol ≤ 2) THEN
SWAPTILES(maxrow, maxcol-1, maxrow, maxcol);
ELSE
SWAPTILES(1, 1, 1, 2);
END;
END;
END;
SWAPTILES(r1, c1, r2, c2)
BEGIN
LOCAL tmp;
tmp := board(r1, c1);
board(r1, c1) := board(r2, c2);
board(r2, c2) := tmp;
END;
//
// Process finger swipe.
//
SWIPE()
BEGIN
LOCAL xdiff, ydiff;
xdiff := ABS(touch(1, 1) - touch(1, 3));
ydiff := ABS(touch(1, 2) - touch(1, 4));
IF xdiff > ydiff THEN
IF touch(1, 1) < touch(1, 3) THEN
MOVE_L();
ELSE
MOVE_R();
END
ELSE
IF touch(1, 2) < touch(1, 4) THEN
MOVE_U();
ELSE
MOVE_D();
END;
END;
END;
//
// Move tile right, if space not in first column.
//
MOVE_R()
BEGIN
LOCAL x, y, n;
IF spacecol > 1 THEN
x := originX + (spacecol-2) * tilewidth; y := originY + (spacerow-1) * tileheight;
FOR n FROM x TO x+w DO
SUBGROB_P(G0, n, y, n+w+1, y+h+1, G1);
SUBGROB_P(G0, n+w+1, y, n+w+2, y+h+1, G2);
BLIT_P(G0, n+1, y, G1);
BLIT_P(G0, n, y, G2);
WAIT(pause);
END;
spacecol := spacecol-1;
END;
END;
//
// Move tile left, if space not in last column.
//
MOVE_L()
BEGIN
LOCAL x, y, n;
IF spacecol < maxcol THEN
x := originX + (spacecol) * tilewidth; y := originY + (spacerow-1) * tileheight;
FOR n FROM x DOWNTO x-w DO
SUBGROB_P(G0, n, y, n+w+1, y+h+1, G1);
SUBGROB_P(G0, n-1, y, n, y+h+1, G2);
BLIT_P(G0, n-1, y, G1);
BLIT_P(G0, n+w, y, G2);
WAIT(pause);
END;
spacecol := spacecol+1;
END;
END;
//
// Move tile down, if space not in first row.
//
MOVE_D()
BEGIN
LOCAL x, y, n;
IF spacerow > 1 THEN
x := originX + (spacecol-1) * tilewidth; y := originY + (spacerow-2) * tileheight;
FOR n FROM y TO y+h DO
SUBGROB_P(G0, x, n, x+w+1, n+h+1, G1);
SUBGROB_P(G0, x, n+h+1, x+w+1, n+h+2, G2);
BLIT_P(G0, x, n+1, G1);
BLIT_P(G0, x, n, G2);
WAIT(pause);
END;
spacerow := spacerow-1;
END;
END;
//
// Move tile up, if space not in last row.
//
MOVE_U()
BEGIN
LOCAL x, y, n;
IF spacerow < maxrow THEN
x := originX + (spacecol-1) * tilewidth; y := originY + (spacerow) * tileheight;
FOR n FROM y DOWNTO y-h DO
SUBGROB_P(G0, x, n, x+w+1, n+h+1, G1);
SUBGROB_P(G0, x, n-1, x+w+1, n, G2);
BLIT_P(G0, x, n-1, G1);
BLIT_P(G0, x, n+h, G2);
WAIT(pause);
END;
spacerow := spacerow+1;
END;
END;