OPTION _EXPLICIT 'Bplus started 2019-08-08 from quick version of Hex Minesweeper and Minesweeper Custom Field ' 2021-01-19 update move all ogg files into separate sub folder for Windows users
'============================================================================================================
'
' Hex Minesweeper v3.1W: Field Customization, Sound Effects and mod Crater Maker!
'
' bplus mod 2021-01-19
'=============================================================================================================
' Attention: this program creates a file: "Hexagon Minefield Custom Specs.txt"
' that you edit with your text editor, if you select that option in the opening screen menu.
' 2019-08-13 Hex Minesweeper Custom and Sound.bas add ogg file sound effects
' Public domain .ogg files source
' https://bigsoundbank.com/detail-0029-computer-mouse.html
' and bomb #6: https://www.mediacollege.com/downloads/sound-effects/explosion/
'2020-02-09 adding Crater Maker effect I devloped for SmallBASIC 2020-02-08 should work even better with QB64.
' It does indeed!!!!
'
'2020-02-10 refined Crater Maker to scale to board size and Bombsound time of blast
'
'to make things easy set cellR as const at 25
CONST cellR
= 25 ' which makes the following constant xspacing!
= 2 * cellR
* COS(_D2R(30)): yspacing!
= cellR
* (1 + SIN(_D2R(30)))DIM SHARED xmax
, ymax
, Xarrd
, Yarrd
, mines
'set all this in customField sub
'sound events
_TITLE "Hexagon Minesweeper v3.1W: Customize, Sound Effects and now Crater Maker" ogg$ = "Ogg Files\"
ToggleSnd
= _SNDOPEN(ogg$
+ "Toggle.ogg")openSnd
= _SNDOPEN(ogg$
+ "Ticking.ogg")ApplauseSnd
= _SNDOPEN(ogg$
+ "Applause sm.ogg")SwooshSnd
= _SNDOPEN(ogg$
+ "Flyby.ogg")'_SNDPLAY SwooshSnd: IF SwooshSnd = 0 THEN PRINT " not loaded." ELSE PRINT "OK loaded.": END
'rnd reveal sounds
rndSnd
(0) = _SNDOPEN(ogg$
+ "357 shot.ogg")rndSnd
(1) = _SNDOPEN(ogg$
+ "alarm.ogg")rndSnd
(2) = _SNDOPEN(ogg$
+ "Apple bite.ogg")rndSnd
(3) = _SNDOPEN(ogg$
+ "Barkings.ogg")rndSnd
(5) = _SNDOPEN(ogg$
+ "brake.ogg")rndSnd
(6) = _SNDOPEN(ogg$
+ "bumble bee.ogg")rndSnd
(7) = _SNDOPEN(ogg$
+ "creaking.ogg")rndSnd
(8) = _SNDOPEN(ogg$
+ "crows.ogg")rndSnd
(10) = _SNDOPEN(ogg$
+ "dinggg.ogg")rndSnd
(11) = _SNDOPEN(ogg$
+ "Donkey.ogg")rndSnd
(12) = _SNDOPEN(ogg$
+ "elec phone.ogg")rndSnd
(13) = _SNDOPEN(ogg$
+ "Fill mug.ogg")rndSnd
(14) = _SNDOPEN(ogg$
+ "goat.ogg")rndSnd
(16) = _SNDOPEN(ogg$
+ "Horse.ogg")rndSnd
(17) = _SNDOPEN(ogg$
+ "Kids.ogg")rndSnd
(18) = _SNDOPEN(ogg$
+ "M scream.ogg")rndSnd
(19) = _SNDOPEN(ogg$
+ "Male Hilarious.ogg")rndSnd
(20) = _SNDOPEN(ogg$
+ "Marimba.ogg")rndSnd
(21) = _SNDOPEN(ogg$
+ "neighing.ogg")rndSnd
(22) = _SNDOPEN(ogg$
+ "polaris ring.ogg")rndSnd
(23) = _SNDOPEN(ogg$
+ "pull top can.ogg")rndSnd
(24) = _SNDOPEN(ogg$
+ "Punch line drum.ogg")rndSnd
(25) = _SNDOPEN(ogg$
+ "Ring 2.ogg")rndSnd
(26) = _SNDOPEN(ogg$
+ "Rooster.ogg")rndSnd
(27) = _SNDOPEN(ogg$
+ "Unlock door.ogg")rndSnd
(28) = _SNDOPEN(ogg$
+ "whook.ogg")'DIM i 'test load and sounds
'FOR i = 10 TO 28
' _SNDPLAY (rndSnd(i))
' PRINT i;
' IF rndSnd(i) = 0 THEN PRINT i; " not loaded." ELSE PRINT
' _DELAY 2
'NEXT
'END
customField
reveal
AS INTEGER ' 1 for marked, 0 hidden, -1 for revealedREDIM SHARED b
(0 TO Xarrd
+ 1, 0 TO Yarrd
+ 1) AS boardType
'oversize the board to make it easy to count mines DIM gameOver
, cc
, cr
, mbN
, s$
, sz!
_TITLE _TRIM$(STR$(Yarrd
* Xarrd
- mines
)) + " Cells to Free Instructions: Left click Reveals, Right Marks Red" restart = 1
gameOver = 0
mbN = 0
getCell cc, cr, mbN
IF b
(cc
, cr
).mine
THEN 'ka boom makeCrater cc, cr
's$ = "KA - BOOOMMMM!" 'comment out since post code
'sz! = 1.2 * xmax / LEN(s$)
'cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
'cText xmax / 2 - 4, ymax / 2 - 4, sz!, &HFFFF0000, s$
'cText xmax / 2 - 8, ymax / 2 - 8, sz!, &HFFFFFF00, s$
gameOver = -1
b(cc, cr).reveal = -1: showCell cc, cr
sweepZeros cc, cr
b(cc, cr).reveal = 0: showCell cc, cr
IF b
(cc
, cr
).reveal
= 0 THEN b
(cc
, cr
).reveal
= 1: showCell cc
, cr
s$ = "Good Job!"
sz!
= 1.2 * xmax
/ LEN(s$
) cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
cText xmax / 2 - 1, ymax / 2 - 2, sz!, &HFF000055, s$
gameOver = -1
restart = 1
NoOff:
DATA 1,0,0,-1,0,1,-1,-1,-1,0,-1,1
xOff:
DATA -1,0,0,-1,0,1,1,-1,1,0,1,1
SUB makeCrater
(col
, row
)
DIM nP
, r
, c
, a!
, i
, ra!
, red!
, j
, stopper
nP = 25 * Xarrd * Yarrd
_DELAY .500 'need a fairly long delay before actually hear sound LINE (0, 0)-(xmax
, ymax
), &HFFFFFFFF, BF
FOR r
= 1 TO Yarrd
'show all mines IF b
(c
, r
).mine
THEN b
(c
, r
).reveal
= -1 showCell c, r
a!
= _ATAN2(b
(c
, r
).y
- b
(col
, row
).y
, b
(c
, r
).x
- b
(col
, row
).x
) b
(c
, r
).dx
= .005 * Xarrd
* Yarrd
* COS(a!
) b
(c
, r
).dy
= .005 * Xarrd
* Yarrd
* SIN(a!
) p
(i
).x
= b
(col
, row
).x
+ RND * 2 * cellR
- cellR
p
(i
).y
= b
(col
, row
).y
+ RND * 2 * cellR
- cellR
p
(i
).dx
= .09 * Xarrd
* Yarrd
/ p
(i
).sz
* COS(ra!
) p
(i
).dy
= .09 * Xarrd
* Yarrd
/ p
(i
).sz
* SIN(ra!
) p
(i
).c
= _RGB32(red!
, .5 * red!
+ .1 * red!
* RND - .05 * red!
, .25 * red!
+ .05 * red!
* RND - .025 * red!
) stopper = .5 * nP 'orig .3
FOR i
= 1 TO 170 'make a Crater!!! maybe runs to long try 70 from original post 270 FOR r
= 1 TO Yarrd
'redraw board with cells moved b(c, r).dx = .9 * b(c, r).dx
b(c, r).dy = .9 * b(c, r).dy
b(c, r).x = b(c, r).x + b(c, r).dx
b(c, r).y = b(c, r).y + b(c, r).dy
showCell c, r
fcirc p(j).x, p(j).y, p(j).sz, p(j).c
LINE (p
(j
).x
- .5 * p
(i
).sz
, p
(j
).y
- .5 * p
(j
).sz
)-STEP(p
(j
).sz
, p
(j
).sz
), p
(j
).c
, BF
p(j).x = p(j).x + p(j).dx
p(j).y = p(j).y + p(j).dy
p(j).dx = .97 * p(j).dx ' original post .992
p(j).dy = .97 * p(j).dy
IF i
< 70 THEN stopper
= stopper
+ 80 ' ELSE stopper = stopper + 1 IF stopper
> nP
THEN stopper
= nP
'set all these 'DIM SHARED xmax, ymax, XarrD, YarrD, mines
DIM fName$
, fe
, fLine$
, p
, inCnt
, beenHere
, allow$
, choice$
fName$ = "Hexagon Minefield Custom Specs.txt"
PRINT " Hexagom Minesweeper options:" PRINT " 1. Use mine field settings: 10 X 10 cells and 10 mines." PRINT " 2. Customize your own field settings." IF fe
THEN PRINT " 3. Use the last customized mine field settings.": allow$
= allow$
+ "3" PRINT " or press esc to quit." choice$ = getChar$(allow$)
CASE "1": xmax
= 800: ymax
= 600: Xarrd
= 10: Yarrd
= 10: mines
= 10 xmax = (Xarrd + 2.5) * xspacing!: ymax = (Yarrd + 2) * yspacing!
editCustom:
PRINT #1, " Custom Field Specs For Your Hexagon Minesweeper Game" PRINT #1, " We will be sizing the screen according to a constant cell radius of 25" PRINT #1, " and then numbers filled in here." PRINT #1, " Please fill out the right side of all Equal signs." PRINT #1, " X dimensions across the screen:" PRINT #1, " Your Max Screen Width (pixels) = " PRINT #1, " Number of Horizontal Cells Across = " PRINT #1, " Y dimensions going down:" PRINT #1, " Your Max Screen Height (pixels) = " PRINT #1, " Number of Cells Down = " PRINT #1, "The percent of mines (8 easy - 15 hard) = " PRINT #1, " To finish, Save the file and then close the editor." ' I picked up this shortcut from Ken, normally I would call a text editor that I don't know if you have!
loadCustom:
beenHere = beenHere + 1 'we'll give it 5 tries
PRINT "OK we tried 5 times, going with default settings..." xmax = 800: ymax = 600: Xarrd = 10: Yarrd = 10: mines = 10
inCnt = 0
WHILE EOF(1) = 0 ' look to get 5 values from 5 = signs inCnt = inCnt + 1
CASE 1: xmax
= VAL(rightOf$
(fLine$
, "=")) CASE 2: Xarrd
= VAL(rightOf$
(fLine$
, "=")) CASE 3: ymax
= VAL(rightOf$
(fLine$
, "=")) CASE 4: Yarrd
= VAL(rightOf$
(fLine$
, "=")) CASE 5: mines
= VAL(rightOf$
(fLine$
, "=")) * Xarrd
* Yarrd
/ 100 IF inCnt
= 5 THEN 'alternate exit from gosub IF xmax
>= (Xarrd
+ 2.5) * xspacing!
THEN IF ymax
< (Yarrd
+ 2) * yspacing!
THEN 'all good PRINT "Opps, Screen height is not big enough for Y cells down." PRINT "Opps, Screen width is not big enough for X cells across." PRINT "We did not get everything filled out by = signs."
DIM minesPlaced
, rx
, ry
, x
, y
, nMines
, xoffset!
restart = 0
minesPlaced = 0
WHILE minesPlaced
< mines
b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
'count mines amoung the neighbors
IF b
(x
, y
).mine
<> -1 THEN 'not already a mine '2 sets of neighbors depending if x offset or not
nMines = b(x - 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
nMines = b(x + 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
nMines = nMines + b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
b(x, y).id = -nMines
b(x, y).id = 0
b(x, y).x = x * xspacing! + xoffset! + .5 * xspacing!
b(x, y).y = y * yspacing! + .5 * yspacing!
b(x, y).reveal = 0
showCell x, y
CASE -1:
IF b
(c
, r
).mine
THEN clr
= &HFF883300 ELSE clr
= &HFFFFFFFF 'revealed white with number of mine neighbors CASE 0: clr
= &HFF008800 'hidden green CASE 1: clr
= &HFFFF0000 'marked red lastx!
= b
(c
, r
).x
+ cellR
* COS(_D2R(-30)) lasty!
= b
(c
, r
).y
+ cellR
* SIN(_D2R(-30)) x!
= b
(c
, r
).x
+ cellR
* COS(_D2R(da
)) y!
= b
(c
, r
).y
+ cellR
* SIN(_D2R(da
)) LINE (lastx!
, lasty!
)-(x!
, y!
), &HFFFF00FF lastx! = x!: lasty! = y!
PAINT (b
(c
, r
).x
, b
(c
, r
).y
), clr
, &HFFFF00FF 'cText b(c, r).x, b(c, r).y, 15, &HFF000000, _TRIM$(STR$(c)) + "," + _TRIM$(STR$(r))
IF b
(c
, r
).id
> 0 THEN cText b
(c
, r
).x
, b
(c
, r
).y
, 35, &HFF000000, _TRIM$(STR$(b
(c
, r
).id
)) IF b
(c
, r
).mine
= -1 THEN cText b
(c
, r
).x
, b
(c
, r
).y
, 35, &HFFFFFFFF, "*"
IF b
(x
, y
).reveal
= -1 AND b
(x
, y
).mine
= 0 THEN c
= c
+ 1 IF c
= Xarrd
* Yarrd
- mines
THEN TFwin
= -1
DIM m
, mx
, my
, mb1
, mb2
, r
, c
IF mb1
OR mb2
THEN ' get last place mouse button was down WHILE mb1
OR mb2
' wait for mouse button release as a "click" IF ((mx
- b
(c
, r
).x
) ^ 2 + (my
- b
(c
, r
).y
) ^ 2) ^ .5 < .5 * xspacing!
THEN returnCol
= c: returnRow
= r:
EXIT SUB mbNum = 0 'still here then clicked wrong
SUB sweepZeros
(col
, row
) ' recursive sweep DIM c
, r
, cMin
, cMax
, rMin
, rMax
, x
, y
, id
c = col: r = row 'get copies for recursive sub
IF c
< Xarrd
- 1 THEN cMax
= c
+ 1 ELSE cMax
= Xarrd
IF r
< Yarrd
- 1 THEN rMax
= r
+ 1 ELSE rMax
= Yarrd
id = b(x, y).id
b(x, y).reveal = -1 'mark played
showCell x, y
sweepZeros x, y
b(x, y).reveal = -1
showCell x, y
'center the text around (x, y) point, needs a graphics screen!
'screen snapshot
mult! = textHeight / 16
xlen
= LEN(txt$
) * 8 * mult!
_PUTIMAGE (x
- .5 * xlen
, y
- .5 * textHeight
)-STEP(xlen
, textHeight
), I&
, cur&
getChar$ = k$
'from Steve Gold standard
Radius
= ABS(R
): RadiusError
= -Radius: X
= Radius: Y
= 0 LINE (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
RadiusError = RadiusError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF