HP Prime for All
English
Русский
Name | Minesweeper |
Description | Faithful touch-based implementation of the mine hunting game. |
Author | Tony Gallo |
Source code formatted by website engine
ICON resource lines were stripped.
BEGIN
local touch;
local done;
local choice;
local i, j, index;
local mode, modetemp;
local highlightindex;
local key;
local result;
//title screen
RECT_P(0, 0, 319, 239, 0, RGB(0, 0, 0));
TEXTOUT_P("MINESWEEPER", 120, 90, 2, RGB(255, 0, 0));
TEXTOUT_P("v1.4.1 2014", 129, 110, 1, RGB(255, 0, 0));
TEXTOUT_P("by Tony Gallo", 128, 130, 1, RGB(255, 0, 0));
wait(1.5);
colorList := {RGB(1, 0, 254), RGB(1, 127, 1), RGB(254, 0, 0), RGB(1, 0, 128), RGB(129, 1, 2), RGB(0, 128, 129), RGB(0, 0…
done := 0;
WHILE (done == 0) DO
CHOOSE(choice, "Choose Difficulty Level", "Beginner - 10 mines", "Intermediate - 15 mines", "Advanced - 20 mines");
if choice == 0 then
//clicked outside choose box - default to Beginner
choice := 1;
end;
bombs := 5 + choice*5;
//clear screen
RECT_P(0, 0, 319, 239, 0, RGB(255, 255, 255));
//credits
TEXTOUT_P("MINESWEEPER", 10, 5, 2, RGB(0, 0, 0));
TEXTOUT_P("v1.4.1 2014", 100, 6, 1, RGB(0, 0, 0));
TEXTOUT_P("by Tony Gallo", 250, 5, 1, RGB(0, 0, 0));
//mode menu
TEXTOUT_P("MODE:", 10, 50, 2, RGB(0, 0, 0));
TEXTOUT_P("↑", 25, 75, 2, RGB(0, 0, 0));
TEXTOUT_P("press", 15, 90, 1, RGB(0, 0, 0));
PlaceFlag(-1, 0);
TEXTOUT_P("flag", 20, 140, 1, RGB(0, 0, 0));
TEXTOUT_P("?", 27, 175, 2, RGB(0, 0, 0));
TEXTOUT_P("unknown", 8, 187, 1, RGB(0, 0, 0));
//press
LINE_P(10, 70, 45, 70, RGB(0, 0, 0));
LINE_P(10, 105, 45, 105, RGB(0, 0, 0));
LINE_P(10, 70, 10, 105, RGB(0, 0, 0));
LINE_P(45, 70, 45, 105, RGB(0, 0, 0));
mode := 0; //0 - press, 1 - flag, 2 - unknown
DrawBoard();
PlantBombs();
unflagged := bombs;
PrintUnflaggedBombs(unflagged);
highlightindex := -1;
WHILE ISKEYDOWN(4) <> 1 do
wait(.1);
touch := mouse();
key := -1;
key := getkey;
if highlightindex > = 1 then
Highlight(highlightindex, 1);
end;
if key == 2 or key == 7 or key == 8 or key == 12 then
highlightindex := Cursor(key, highlightindex);
continue;
end;
if key == 30 then
//pressed board with ENTER
if highlightindex > = 1 then
result := PrePress(highlightindex, mode, 1);
if result == "continue" then continue; end;
if result == "break" then break; end;
end;
end;
if size(touch(1)) then
if touch(1, 5) == 0 then
X := B→R(touch(1, 1));
Y := B→R(touch(1, 2));
if 10 <= X <= 45 and 70 <= Y <= 200 THEN
modetemp := SelectMode(X, Y);
if 0 <= modetemp <= 2 then
mode := modetemp;
end;
end;
if 60 <= X <= 259 and 20 <= Y <= 219 THEN
//pressed board with finger
i := iquo((X-60), 20);
j := iquo((Y-20), 20);
index := 10*j + i + 1;
result := PrePress(index, mode, 0);
if result == "continue" then continue; end;
if result == "break" then break; end;
END;
end;
end;
END;
key := -1;
while key = -1 do
wait(.1);
touch := mouse();
key := getkey;
end;
CHOOSE(choice, "Play Again?", "Yes", "No");
if choice < > 1 then done := 1; end;
END;
END;
PrePress(index, mode, highlighted)
begin
local result;
local I, J;
result := "";
if mode == 1 and minefield(index) > 8 then
PlaceFlag(index, highlighted);
PrintUnflaggedBombs(unflagged);
result := "continue";
return result;
end;
if mode == 2 and minefield(index) > 8 then
PlaceQuestion(index, highlighted);
result := "continue";
return result;
end;
if minefield(index) == 12 or minefield(index) == 14 then
//flagged - cannot press
result := "continue";
return result;
end;
if minefield(index) == 11 or minefield(index) == 15 then
ShowBombs(0);
I := irem(index-1, 10);
J := iquo(index-1, 10);
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, 0, RGB(192, 192, 192));
FilledCircle(70 + 20*irem(index-1, 10), 30 + 20*iquo(index-1, 10), 4, RGB(255, 0, 0));
TEXTOUT_P("YOU", 278, 35, 2, RGB(255, 0, 0));
TEXTOUT_P("LOSE!", 275, 50, 2, RGB(255, 0, 0));
TEXTOUT_P("Press any", 265, 80, 2, RGB(0, 0, 0));
TEXTOUT_P("key.", 280, 95, 2, RGB(0, 0, 0));
result := "break";
return result;
else
PressSquare(index);
if GameWon() == 1 then
ShowBombs(1);
TEXTOUT_P("YOU", 278, 35, 2, RGB(0, 0, 0));
TEXTOUT_P("WIN!", 277, 50, 2, RGB(0, 0, 0));
TEXTOUT_P("Press any", 265, 80, 2, RGB(0, 0, 0));
TEXTOUT_P("key.", 280, 95, 2, RGB(0, 0, 0));
result := "break";
return result;
end;
end;
return result;
end;
PrintUnflaggedBombs(number)
begin
RECT_P(280, 175, 305, 195, 0, RGB(0, 0, 0));
TEXTOUT_P(IntToString(number), 285, 180, 2, RGB(255, 0, 0));
end;
Cursor(key, highlightindex)
begin
if highlightindex == - 1 then
highlightindex := 1;
Highlight(highlightindex, 1);
return 1;
end;
Highlight(highlightindex, 0);
CASE
if key == 2 then
if 1 <= highlightindex < = 10 then
highlightindex := highlightindex + 90;
else
highlightindex := highlightindex - 10;
end;
end;
if key == 7 then
if irem(highlightindex, 10) == 1 then
highlightindex := highlightindex + 9;
else
highlightindex := highlightindex - 1;
end;
end;
if key == 8 then
if irem(highlightindex, 10) == 0 then
highlightindex := highlightindex - 9;
else
highlightindex := highlightindex + 1;
end;
end;
if key == 12 then
if 91 <= highlightindex < = 100 then
highlightindex := highlightindex - 90;
else
highlightindex := highlightindex + 10;
end;
end;
END;
Highlight(highlightindex, 1);
return highlightindex;
end;
Highlight(index, mode)
begin
//mode 0 - unhighlight
//mode 1 - highlight
local color;
local I, J;
I := irem(index-1, 10);
J := iquo(index-1, 10);
if mode == 0 then color := RGB(0, 0, 0); end;
if mode == 1 then color := RGB(255, 244, 43); end;
LINE_P(60+I*20, 20+J*20, 60+I*20, 40+J*20, color);
LINE_P(80+I*20, 20+J*20, 80+I*20, 40+J*20, color);
LINE_P(60+I*20, 20+J*20, 80+I*20, 20+J*20, color);
LINE_P(60+I*20, 40+J*20, 80+I*20, 40+J*20, color);
end;
IsBomb(index)
begin
if minefield(index) == 11 or minefield(index) == 14 or minefield(index) == 15 then
return 1;
else
return 0;
end;
end;
AdjacentBombs(index)
begin
local count;
count := 0;
CASE
//top left corner
if index == 1 then
count := IsBomb(index+1) + IsBomb(index+10) + IsBomb(index+11);
end;
//top row
if 2 <= index < = 9 then
count := IsBomb(index-1) + IsBomb(index+1)
+ IsBomb(index+9) + IsBomb(index+10) + IsBomb(index+11);
end;
//top right corner
if index == 10 then
count := IsBomb(index-1) + IsBomb(index+9) + IsBomb(index+10);
end;
//bottom left corner
if index == 91 then
count := IsBomb(index-10) + IsBomb(index-9) + IsBomb(index+1);
end;
//bottom row
if 92 <= index < = 99 then
count := IsBomb(index-11) + IsBomb(index-10) + IsBomb(index-9)
+ IsBomb(index-1) + IsBomb(index+1);
end;
//bottom right corner
if index == 100 then
count := IsBomb(index-11) + IsBomb(index-10) + IsBomb(index-1);
end;
//farmost left column
if irem(index, 10) == 1 then
count := IsBomb(index-10) + IsBomb(index-9)
+ IsBomb(index+1) + IsBomb(index+10) + IsBomb(index+11);
end;
//farmost right column
if irem(index, 10) == 0 then
count := IsBomb(index-11) + IsBomb(index-10)
+ IsBomb(index-1) + IsBomb(index+9) + IsBomb(index+10);
end;
//everywhere else (in the middle)
count := IsBomb(index-11) + IsBomb(index-10) + IsBomb(index-9)
+ IsBomb(index-1) + IsBomb(index+1)
+ IsBomb(index+9) + IsBomb(index+10) + IsBomb(index+11);
END;
return count;
end;
PressSquare(index)
begin
local bombcount;
local I, J;
I := irem(index-1, 10);
J := iquo(index-1, 10);
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, 0, RGB(192, 192, 192));
bombcount := AdjacentBombs(index);
minefield(index) := bombcount;
if bombcount < > 0 then
TEXTOUT_P(IntToChar(bombcount), 67+20*I, 25+20*J, 2, colorList(bombcount));
else
PressAdjacentSquares(index);
end;
end;
PressAdjacentSquare(index)
begin
if minefield(index) = 10 or minefield(index) = 13 then
PressSquare(index);
end;
end;
PressAdjacentSquares(index)
begin
CASE
//top left corner
if index == 1 then
PressAdjacentSquare(index+1);
PressAdjacentSquare(index+10);
PressAdjacentSquare(index+11);
end;
//top row
if 2 <= index < = 9 then
PressAdjacentSquare(index-1);
PressAdjacentSquare(index+1);
PressAdjacentSquare(index+9);
PressAdjacentSquare(index+10);
PressAdjacentSquare(index+11);
end;
//top right corner
if index == 10 then
PressAdjacentSquare(index-1);
PressAdjacentSquare(index+9);
PressAdjacentSquare(index+10);
end;
//bottom left corner
if index == 91 then
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-9);
PressAdjacentSquare(index+1);
end;
//bottom row
if 92 <= index < = 99 then
PressAdjacentSquare(index-11);
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-9);
PressAdjacentSquare(index-1);
PressAdjacentSquare(index+1);
end;
//bottom right corner
if index == 100 then
PressAdjacentSquare(index-11);
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-1);
end;
//farmost left column
if irem(index, 10) == 1 then
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-9);
PressAdjacentSquare(index+1);
PressAdjacentSquare(index+10);
PressAdjacentSquare(index+11);
end;
//farmost right column
if irem(index, 10) == 0 then
PressAdjacentSquare(index-11);
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-1);
PressAdjacentSquare(index+9);
PressAdjacentSquare(index+10);
end;
//everywhere else (in the middle)
PressAdjacentSquare(index-11);
PressAdjacentSquare(index-10);
PressAdjacentSquare(index-9);
PressAdjacentSquare(index-1);
PressAdjacentSquare(index+1);
PressAdjacentSquare(index+9);
PressAdjacentSquare(index+10);
PressAdjacentSquare(index+11);
END;
end;
DrawBoard()
begin
local I;
RECT_P(60, 20, 260, 220, 0, RGB(65, 105, 225));
FOR I FROM 1 to 9 DO
LINE_P(60+20*I, 20, 60+20*I, 220, RGB(0, 0, 0));
LINE_P(60, 20+20*I, 260, 20+20*I, RGB(0, 0, 0));
END;
end;
PlantBombs()
begin
local index, count;
count := 0;
//minefield values:
//0-8 - # of adjacent bombs
//10 - nothing
//11 - bomb
//12 - flagged nothing
//13 - question nothing
//14 - flagged bomb
//15 - question bomb
minefield := makelist(10, A, 1, 100, 1);
WHILE (count < bombs) DO
index := RANDINT(1, 100);
if minefield(index) == 10 then
minefield(index) := 11;
count := count + 1;
end;
END;
return minefield;
end;
FilledCircle(X, Y, Radius, Color)
begin
local I;
FOR I FROM 0 TO Radius DO
ARC_P(X, Y, I, Color);
END;
end;
ShowBombs(win)
begin
local index;
local I, J;
local color;
if win == 1 then
color := RGB(65, 105, 225);
else
color := RGB(192, 192, 192);
end;
I := irem(index-1, 10);
J := iquo(index-1, 10);
FOR index FROM 1 TO 100 DO
I := irem(index-1, 10);
J := iquo(index-1, 10);
if minefield(index) == 11 or minefield(index) == 14 or minefield(index) == 15 then
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, 0, color);
FilledCircle(70 + 20*I, 30 + 20*J, 4, RGB(0, 0, 0));
end;
if minefield(index) == 12 then
//misflagged
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, 0, color);
FilledCircle(70 + 20*I, 30 + 20*J, 4, RGB(0, 0, 0));
LINE_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, RGB(255, 0, 0));
LINE_P(80+20*I, 20+20*J, 60+20*I, 40+20*J, RGB(255, 0, 0));
end;
END;
end;
GameWon()
begin
local index;
local count;
count := 0;
FOR index FROM 1 TO 100 DO
if minefield(index) < = 8 then
count := count +1;
end;
END;
if count == 100 - bombs then
return 1;
else
return 0;
end;
end;
PlaceFlag(index, highlighted)
begin
local I, J;
local border;
if highlighted == 0 then
border := RGB(0, 0, 0);
else
border := RGB(255, 244, 43);
end;
if index > = 1 then
I := irem(index-1, 10);
J := iquo(index-1, 10);
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, border, RGB(65, 105, 225));
else
//menu
I := -2;
J := 5;
end;
if index > = 1 then
if minefield(index) == 12 then
minefield(index) := 10;
unflagged := unflagged + 1;
return;
end;
if minefield(index) == 14 then
minefield(index) := 11;
unflagged := unflagged + 1;
return;
end;
if minefield(index) == 10 or minefield(index) == 13 then
minefield(index) := 12;
unflagged := unflagged - 1;
end;
if minefield(index) == 11 or minefield(index) == 15 then
minefield(index) := 14;
unflagged := unflagged - 1;
end;
end;
RECT_P(60+20*I+4, 20+20*J+5, 80+20*I-7, 40+20*J-10, 0, RGB(255, 0, 0));
LINE_P(80+20*I-7, 40+20*J-10, 80+20*I-7, 40+20*J-5, RGB(0, 0, 0));
LINE_P(60+20*I+10, 40+20*J-5, 80+20*I-5, 40+20*J-5, RGB(0, 0, 0));
end;
PlaceQuestion(index, highlighted)
begin
local I, J;
local border;
if highlighted == 0 then
border := RGB(0, 0, 0);
else
border := RGB(255, 244, 43);
end;
I := irem(index-1, 10);
J := iquo(index-1, 10);
RECT_P(60+20*I, 20+20*J, 80+20*I, 40+20*J, border, RGB(65, 105, 225));
if minefield(index) == 13 then
minefield(index) := 10;
return;
end;
if minefield(index) == 15 then
minefield(index) := 11;
return;
end;
TEXTOUT_P("?", 60+20*I+8, 20+20*J+5, 2, RGB(0, 0, 0));
if minefield(index) == 10 or minefield(index) == 12 then
minefield(index) := 13;
end;
if minefield(index) == 11 or minefield(index) == 14 then
minefield(index) := 15;
end;
end;
SelectMode(x, y)
begin
local mode;
mode := -1;
case
if 70 <= Y <= 105 then mode := 0; end;
if 120 <= Y <= 155 then mode := 1; end;
if 170 <= Y <= 200 then mode := 2; end;
end;
if mode == -1 then
return mode;
end;
//clear boxes
//press
LINE_P(10, 70, 45, 70, RGB(255, 255, 255));
LINE_P(10, 105, 45, 105, RGB(255, 255, 255));
LINE_P(10, 70, 10, 105, RGB(255, 255, 255));
LINE_P(45, 70, 45, 105, RGB(255, 255, 255));
//flag
LINE_P(10, 120, 45, 120, RGB(255, 255, 255));
LINE_P(10, 155, 45, 155, RGB(255, 255, 255));
LINE_P(10, 120, 10, 155, RGB(255, 255, 255));
LINE_P(45, 120, 45, 155, RGB(255, 255, 255));
//unknown
LINE_P(4, 170, 51, 170, RGB(255, 255, 255));
LINE_P(4, 200, 51, 200, RGB(255, 255, 255));
LINE_P(4, 170, 4, 200, RGB(255, 255, 255));
LINE_P(51, 170, 51, 200, RGB(255, 255, 255));
case
if mode == 0 then
//press
LINE_P(10, 70, 45, 70, RGB(0, 0, 0));
LINE_P(10, 105, 45, 105, RGB(0, 0, 0));
LINE_P(10, 70, 10, 105, RGB(0, 0, 0));
LINE_P(45, 70, 45, 105, RGB(0, 0, 0));
end;
if mode == 1 then
//flag
LINE_P(10, 120, 45, 120, RGB(0, 0, 0));
LINE_P(10, 155, 45, 155, RGB(0, 0, 0));
LINE_P(10, 120, 10, 155, RGB(0, 0, 0));
LINE_P(45, 120, 45, 155, RGB(0, 0, 0));
end;
if mode == 2 then
//unknown
LINE_P(4, 170, 51, 170, RGB(0, 0, 0));
LINE_P(4, 200, 51, 200, RGB(0, 0, 0));
LINE_P(4, 170, 4, 200, RGB(0, 0, 0));
LINE_P(51, 170, 51, 200, RGB(0, 0, 0));
end;
end;
return mode;
end;
IntToString(int)
begin
local rem;
local string = "";
local negative = 0;
if int == 0 then
return "0";
end;
if int < 0 then
negative := 1;
int := int * (-1);
end;
while int > 0 do
rem := irem(int, 10);
string := IntToChar(rem) + string ;
int := (int - rem) / 10;
end;
if negative == 1 then
string := "-" + string;
end;
return string;
end;
IntToChar(int)
begin
if int == 0 then
return "0";
end;
if int == 1 then
return "1";
end;
if int == 2 then
return "2";
end;
if int == 3 then
return "3";
end;
if int == 4 then
return "4";
end;
if int == 5 then
return "5";
end;
if int == 6 then
return "6";
end;
if int == 7 then
return "7";
end;
if int == 8 then
return "8";
end;
if int == 9 then
return "9";
end;
end;