QB64.org Forum

Active Forums => Programs => Topic started by: bplus on August 01, 2019, 10:02:05 pm

Title: Quick Minesweeper
Post by: bplus on August 01, 2019, 10:02:05 pm
A quick game of Minesweeper:
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus 2019-08-01
  2. DEFINT A-Z '      9 squares 60 x 60 pixels = 540 x 540 screen
  3. CONST xmax = 540, ymax = 540, sq = 60, arrD = 9, mines = 13
  4. _TITLE STR$(mines) + " Mine-sweeper: left click cell to reveal, right click to mark mine (red)"
  5. SCREEN _NEWIMAGE(xmax, ymax, 32)
  6. _SCREENMOVE 300, 10
  7. TYPE boardType
  8.     id AS INTEGER '0 to 8 neighbor mines
  9.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  10.     mine AS INTEGER '0 or -1
  11. REDIM SHARED b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType 'oversize the board to make it easy to count mines
  12. DIM SHARED restart
  13. DIM gameOver, cc, cr, mbN, c, r
  14. restart = 1
  15.     gameOver = 0
  16.     WHILE gameOver = 0
  17.         IF restart THEN initialize
  18.         mbN = 0
  19.         getCell cc, cr, mbN
  20.         'LOCATE 1, 1: PRINT cc, cr, mbN
  21.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  22.             IF b(cc, cr).mine THEN 'ka boom
  23.                 FOR r = 1 TO arrD 'show all mines
  24.                     FOR c = 1 TO arrD
  25.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  26.                     NEXT
  27.                 NEXT
  28.                 cText xmax / 2, ymax / 2, 72, &HFF000000, "KA - BOOOMMMM!"
  29.                 cText xmax / 2 - 4, ymax / 2 - 4, 64, &HFFFF0000, "KA - BOOOMMMM!"
  30.                 cText xmax / 2 - 8, ymax / 2 - 8, 56, &HFFFFFF00, "KA - BOOOMMMM!"
  31.                 gameOver = -1
  32.                 _DELAY 7
  33.             ELSE
  34.                 b(cc, cr).reveal = -1: showCell cc, cr
  35.                 IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  36.             END IF
  37.         ELSEIF mbN = 2 THEN
  38.             IF b(cc, cr).reveal = 1 THEN
  39.                 b(cc, cr).reveal = 0: showCell cc, cr
  40.             ELSE
  41.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  42.             END IF
  43.         END IF
  44.         IF TFwin THEN
  45.             cText xmax / 2, ymax / 2, 30, &HFF001144, "You found all the free cells!"
  46.             cText xmax / 2 - 1, ymax / 2 - 2, 30, &HFF3399BB, "You found all the free cells!"
  47.             _DELAY 5
  48.             gameOver = -1
  49.         END IF
  50.         _LIMIT 60
  51.     WEND
  52.     restart = 1
  53.  
  54. SUB initialize ()
  55.     DIM minesPlaced, rx, ry, x, y, nMines
  56.     restart = 0
  57.     REDIM b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType
  58.     minesPlaced = 0
  59.     WHILE minesPlaced < mines
  60.         rx = INT(RND * arrD) + 1: ry = INT(RND * arrD) + 1
  61.         IF b(rx, ry).mine = 0 THEN
  62.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  63.         END IF
  64.     WEND
  65.     'count mines amoung the neighbors
  66.     FOR y = 1 TO arrD
  67.         FOR x = 1 TO arrD
  68.             IF b(x, y).mine <> -1 THEN 'not already a mine
  69.                 nMines = b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  70.                 nMines = nMines + b(x, y - 1).mine + b(x, y + 1).mine
  71.                 nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  72.                 b(x, y).id = -nMines
  73.             ELSE
  74.                 b(x, y).id = 0
  75.             END IF
  76.             b(x, y).reveal = 0
  77.             showCell x, y
  78.         NEXT
  79.     NEXT
  80.  
  81. SUB showCell (c, r)
  82.     DIM x, y, clr AS _UNSIGNED LONG
  83.     x = (c - 1) * sq: y = (r - 1) * sq
  84.     SELECT CASE b(c, r).reveal
  85.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  86.         CASE 0: clr = &HFF008800 'hidden green
  87.         CASE 1: clr = &HFFFF0000 'marked red
  88.     END SELECT
  89.     LINE (x, y)-STEP(sq - 1, sq - 1), clr, BF
  90.     LINE (x, y)-STEP(sq - 1, sq - 1), &HFF000000, B
  91.     IF b(c, r).reveal = -1 THEN
  92.         IF b(c, r).id > 0 THEN cText x + 30, y + 30, 50, &HFF000000, _TRIM$(STR$(b(c, r).id))
  93.         IF b(c, r).mine = -1 THEN cText x + 30, y + 30, 50, &HFFFFFFFF, "*"
  94.     END IF
  95.  
  96. FUNCTION TFwin
  97.     DIM c, x, y
  98.     FOR y = 1 TO arrD
  99.         FOR x = 1 TO arrD
  100.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  101.         NEXT
  102.     NEXT
  103.     IF c = arrD * arrD - mines THEN TFwin = -1
  104.  
  105. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  106.     DIM m, mx, my, mb1, mb2
  107.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  108.     IF mb1 THEN mbNum = 1
  109.     IF mb2 THEN mbNum = 2
  110.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  111.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  112.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  113.             mx = _MOUSEX: my = _MOUSEY
  114.         WEND
  115.         returnCol = INT(mx / sq) + 1: returnRow = INT(my / sq) + 1
  116.     END IF
  117.  
  118. SUB sweepZeros (col, row) ' recursive sweep with Rod's limits set
  119.     DIM c, r, cMin, cMax, rMin, rMax, x, y, id
  120.     c = col: r = row 'get copies for recursive sub
  121.     IF c > 2 THEN cMin = c - 1 ELSE cMin = 1
  122.     IF c < arrD - 1 THEN cMax = c + 1 ELSE cMax = arrD
  123.     IF r > 2 THEN rMin = r - 1 ELSE rMin = 1
  124.     IF r < arrD - 1 THEN rMax = r + 1 ELSE rMax = arrD
  125.     FOR y = rMin TO rMax
  126.         FOR x = cMin TO cMax
  127.             IF b(x, y).reveal = 0 THEN
  128.                 id = b(x, y).id
  129.                 IF b(x, y).mine = 0 AND id = 0 THEN
  130.                     b(x, y).reveal = -1 'mark played
  131.                     showCell x, y
  132.                     sweepZeros x, y
  133.                 ELSE
  134.                     IF b(x, y).mine = 0 AND id >= 1 AND id <= 8 THEN
  135.                         b(x, y).reveal = -1
  136.                         showCell x, y
  137.                     END IF
  138.                 END IF
  139.             END IF
  140.         NEXT
  141.     NEXT
  142.  
  143. 'center the text around (x, y) point, needs a graphics screen!
  144. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  145.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  146.     fg = _DEFAULTCOLOR
  147.     'screen snapshot
  148.     cur& = _DEST
  149.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  150.     _DEST I&
  151.     COLOR K, _RGBA32(0, 0, 0, 0)
  152.     _PRINTSTRING (0, 0), txt$
  153.     mult = textHeight / 16
  154.     xlen = LEN(txt$) * 8 * mult
  155.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  156.     COLOR fg
  157.     _FREEIMAGE I&
  158.  
  159.  

2019-08-02 Update: _title change line number location and reflects mines set.
Title: Re: Quick Minesweeper
Post by: Pete on August 01, 2019, 10:32:19 pm
Rigged! I played 5 times, and it never took more than 2 moves for me to blow my ascii up!

Pete :O
Title: Re: Quick Minesweeper
Post by: bplus on August 01, 2019, 10:36:23 pm
Ha! It does have a shade more than std 15% mines. 14/81 = 17.28.. %

Title: Re: Quick Minesweeper
Post by: SierraKen on August 02, 2019, 12:38:56 pm
LOL awesome game!
Title: Re: Quick Minesweeper
Post by: bplus on August 02, 2019, 12:44:47 pm
Thanks, I am pretty sure Pete knows how to hack this game to play nicer :D

OK I will mine my own business now...
Title: Re: Quick Minesweeper
Post by: bplus on August 02, 2019, 04:43:30 pm
Update: A tiny change to _title to reflect the amount of mines you are playing.
Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 03, 2019, 08:22:34 pm
Very cool!

In this kind of games I have not so much luck!
At first attempt I got a 1 in the middle of the green land ... so at the second click I got the mine :-))) LOL
Title: Re: Quick Minesweeper
Post by: bplus on August 03, 2019, 08:57:10 pm
Thanks TempodiBasic!

Maybe this will change everyone's luck, design you own minefield: screen size, cells, cell sizes, and mines.
Here I am using your text editor to fill out a spec form.
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-08-01
  2. ' update 2019-08-02 _title change line number so can reflect changes to mines constant.
  3. ' 2019-08-03 Minesweeper Custom Field.bas creates a file: "Custom Field Specs.txt"
  4. ' that you edit with your text editor, if you select that option in the opening screen menu.
  5.  
  6. DEFINT A-Z
  7. DIM SHARED xmax, ymax, Xsq, Ysq, Xarrd, Yarrd, mines, Xmargin, Ymargin 'set all this in customField sub
  8. _TITLE "Minesweeper: Custom Field"
  9. customField
  10. _TITLE STR$(mines) + " Minesweeper: left click reveals, right marks red"
  11. SCREEN _NEWIMAGE(xmax, ymax, 32)
  12. _SCREENMOVE (1280 - xmax) / 2, (760 - ymax) / 2
  13. TYPE boardType
  14.     id AS INTEGER '0 to 8 neighbor mines
  15.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  16.     mine AS INTEGER '0 or -1
  17. REDIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType 'oversize the board to make it easy to count mines
  18. DIM SHARED restart
  19. DIM gameOver, cc, cr, mbN, c, r, s$, sz!
  20. restart = 1
  21.     gameOver = 0
  22.     WHILE gameOver = 0
  23.         IF restart THEN initialize
  24.         mbN = 0
  25.         getCell cc, cr, mbN
  26.         'LOCATE 1, 1: PRINT cc, cr, mbN
  27.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  28.             IF b(cc, cr).mine THEN 'ka boom
  29.                 FOR r = 1 TO Yarrd 'show all mines
  30.                     FOR c = 1 TO Xarrd
  31.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  32.                     NEXT
  33.                 NEXT
  34.                 s$ = "KA - BOOOMMMM!"
  35.                 sz! = 1.2 * xmax / LEN(s$)
  36.                 cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  37.                 cText xmax / 2 - 4, ymax / 2 - 4, sz!, &HFFFF0000, s$
  38.                 cText xmax / 2 - 8, ymax / 2 - 8, sz!, &HFFFFFF00, s$
  39.                 gameOver = -1
  40.                 _DELAY 7
  41.             ELSE
  42.                 b(cc, cr).reveal = -1: showCell cc, cr
  43.                 IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  44.             END IF
  45.         ELSEIF mbN = 2 THEN
  46.             IF b(cc, cr).reveal = 1 THEN
  47.                 b(cc, cr).reveal = 0: showCell cc, cr
  48.             ELSE
  49.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  50.             END IF
  51.         END IF
  52.         IF TFwin THEN
  53.             s$ = "Good Job!"
  54.             sz! = 1.2 * xmax / LEN(s$)
  55.             cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  56.             cText xmax / 2 - 1, ymax / 2 - 2, sz!, &HFF000055, s$
  57.             _DELAY 5
  58.             gameOver = -1
  59.         END IF
  60.         _LIMIT 60
  61.     WEND
  62.     restart = 1
  63.  
  64. 'set all this 'DIM SHARED xmax, ymax, Xsq, Ysq, XarrD, YarrD, mines, Xmargin, Ymargin
  65. SUB customField
  66.     DIM fName$, fe, fLine$, p, inCnt, beenHere, w$, allow$, choice$
  67.  
  68.     fName$ = "Custom Field Specs.txt"
  69.     IF _FILEEXISTS(fName$) THEN fe = -1 ELSE fe = 0
  70.     allow$ = "12" + CHR$(27)
  71.     PRINT
  72.     PRINT "     Minesweeper options:"
  73.     PRINT
  74.     PRINT "  1. Use mine field settings: 800 x 600 screen with 9 X 9 cells and 10 mines."
  75.     PRINT "  2. Customize your own field settings."
  76.     IF fe THEN PRINT "  3. Use the last customized mine field settings.": allow$ = allow$ + "3"
  77.     PRINT
  78.     PRINT "     or press esc to quit."
  79.     choice$ = getChar$(allow$)
  80.     SELECT CASE choice$
  81.         CASE "1": GOTO default
  82.         CASE "2": GOSUB editCustom
  83.         CASE "3": GOSUB loadCustom
  84.         CASE ELSE: SYSTEM
  85.     END SELECT
  86.     EXIT SUB
  87.  
  88.     editCustom:
  89.     OPEN fName$ FOR OUTPUT AS #1
  90.     PRINT #1, " "
  91.     PRINT #1, "     Custom Field Specs For Your Minesweeper Game"
  92.     PRINT #1, " "
  93.     PRINT #1, " Please fill out the right side of all Equal signs."
  94.     PRINT #1, " "
  95.     PRINT #1, "   X dimensions across the screen:"
  96.     PRINT #1, "                  Screen Width (pixels) = "
  97.     PRINT #1, "      Number of Horizontal Cells Across = "
  98.     PRINT #1, "          Cell Width (12 - 100? pixels) = "
  99.     PRINT #1, " "
  100.     PRINT #1, "   Y dimensions going down:"
  101.     PRINT #1, "                 Screen Height (pixels) = "
  102.     PRINT #1, "                   Number of Cells Down = "
  103.     PRINT #1, "          Cell Height (24 - 80? pixels) = "
  104.     PRINT #1, " "
  105.     PRINT #1, "The percent of mines (8 easy - 15 hard) = "
  106.     PRINT #1, " "
  107.     PRINT #1, "    To finish, Save the file and then close the editor."
  108.     CLOSE #1
  109.     ' I picked up this shortcut from Ken, normally I would call a text editor that I don't know if you have!
  110.     SHELL fName$
  111.     GOSUB loadCustom
  112.     RETURN
  113.  
  114.     loadCustom:
  115.     beenHere = beenHere + 1 'we'll give it 5 tries
  116.     IF beenHere > 5 THEN
  117.         PRINT "OK we tried 5 times, going with default settings..."
  118.         GOTO default 'exit from there
  119.     END IF
  120.     inCnt = 0
  121.     OPEN fName$ FOR INPUT AS #1
  122.     WHILE EOF(1) = 0 ' look to get 7 values from 7 = signs
  123.         LINE INPUT #1, fLine$
  124.         'PRINT fLine$
  125.         p = INSTR(fLine$, "=")
  126.         IF p > 0 THEN
  127.             inCnt = inCnt + 1
  128.             SELECT CASE inCnt
  129.                 CASE 1: xmax = VAL(rightOf$(fLine$, "="))
  130.                 CASE 2: Xarrd = VAL(rightOf$(fLine$, "="))
  131.                 CASE 3: Xsq = VAL(rightOf$(fLine$, "="))
  132.                 CASE 4: ymax = VAL(rightOf$(fLine$, "="))
  133.                 CASE 5: Yarrd = VAL(rightOf$(fLine$, "="))
  134.                 CASE 6: Ysq = VAL(rightOf$(fLine$, "="))
  135.                 CASE 7: mines = VAL(rightOf$(fLine$, "=")) * Xarrd * Yarrd / 100
  136.             END SELECT
  137.             IF inCnt = 7 THEN EXIT WHILE
  138.         END IF
  139.     WEND
  140.     CLOSE #1
  141.     IF inCnt = 7 THEN
  142.         IF Xsq >= 12 THEN
  143.             IF Ysq >= 24 THEN
  144.                 IF xmax >= Xarrd * Xsq THEN
  145.                     IF ymax >= Yarrd * Ysq THEN 'all good
  146.                         GOSUB calcMargins: EXIT SUB
  147.                     ELSE
  148.                         PRINT "Opps, Screen height is not big enough for Y cells * pixels down."
  149.                     END IF
  150.                 ELSE
  151.                     PRINT "Opps, Screen width is not big enough for X cells * pixels across."
  152.                 END IF
  153.             ELSE
  154.                 PRINT "Y Cell pixels down probably not enough."
  155.             END IF
  156.         ELSE
  157.             PRINT "X Cell pixels across probably not enough."
  158.         END IF
  159.     ELSE
  160.         PRINT "We did not get everything filled out by = signs."
  161.     END IF
  162.     PRINT: PRINT "Press any to continue.. "
  163.     SLEEP
  164.     SHELL fName$
  165.     GOTO loadCustom
  166.     RETURN
  167.  
  168.     calcMargins:
  169.     Xmargin = (xmax - Xarrd * Xsq) / 2: Ymargin = (ymax - Yarrd * Ysq) / 2
  170.     RETURN
  171.  
  172.     default:
  173.     xmax = 800: ymax = 600: Xarrd = 9: Yarrd = 9: Xsq = 60: Ysq = 60: mines = 10: GOSUB calcMargins
  174.  
  175. SUB initialize ()
  176.     DIM minesPlaced, rx, ry, x, y, nMines
  177.     restart = 0
  178.     REDIM b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType
  179.     minesPlaced = 0
  180.     WHILE minesPlaced < mines
  181.         rx = INT(RND * Xarrd) + 1: ry = INT(RND * Yarrd) + 1
  182.         IF b(rx, ry).mine = 0 THEN
  183.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  184.         END IF
  185.     WEND
  186.     'count mines amoung the neighbors
  187.     FOR y = 1 TO Yarrd
  188.         FOR x = 1 TO Xarrd
  189.             IF b(x, y).mine <> -1 THEN 'not already a mine
  190.                 nMines = b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  191.                 nMines = nMines + b(x, y - 1).mine + b(x, y + 1).mine
  192.                 nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  193.                 b(x, y).id = -nMines
  194.             ELSE
  195.                 b(x, y).id = 0
  196.             END IF
  197.             b(x, y).reveal = 0
  198.             showCell x, y
  199.         NEXT
  200.     NEXT
  201.  
  202. SUB showCell (c, r)
  203.     DIM x, y, clr AS _UNSIGNED LONG, sz
  204.     x = (c - 1) * Xsq + Xmargin: y = (r - 1) * Ysq + Ymargin
  205.     SELECT CASE b(c, r).reveal
  206.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  207.         CASE 0: clr = &HFF008800 'hidden green
  208.         CASE 1: clr = &HFFFF0000 'marked red
  209.     END SELECT
  210.     LINE (x, y)-STEP(Xsq - 1, Ysq - 1), clr, BF
  211.     LINE (x, y)-STEP(Xsq - 1, Ysq - 1), &HFF000000, B
  212.     IF Xsq < Ysq THEN sz = .8 * Xsq ELSE sz = .8 * Ysq
  213.     IF b(c, r).reveal = -1 THEN
  214.         IF b(c, r).id > 0 THEN cText x + Xsq / 2, y + Ysq / 2, sz, &HFF000000, _TRIM$(STR$(b(c, r).id))
  215.         IF b(c, r).mine = -1 THEN cText x + Xsq / 2, y + Ysq / 2, sz, &HFFFFFFFF, "*"
  216.     END IF
  217.  
  218. FUNCTION TFwin
  219.     DIM c, x, y
  220.     FOR y = 1 TO Yarrd
  221.         FOR x = 1 TO Xarrd
  222.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  223.         NEXT
  224.     NEXT
  225.     IF c = Xarrd * Yarrd - mines THEN TFwin = -1
  226.  
  227. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  228.     DIM m, mx, my, mb1, mb2
  229.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  230.     IF mb1 THEN mbNum = 1
  231.     IF mb2 THEN mbNum = 2
  232.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  233.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  234.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  235.             mx = _MOUSEX: my = _MOUSEY
  236.         WEND
  237.         returnCol = INT((mx - Xmargin) / Xsq) + 1: returnRow = INT((my - Ymargin) / Ysq) + 1
  238.         IF returnCol < 1 OR returnCol > Xarrd OR returnRow < 1 OR returnRow > Yarrd THEN mbNum = 0
  239.     END IF
  240.  
  241. SUB sweepZeros (col, row) ' recursive sweep with Rod's limits set
  242.     DIM c, r, cMin, cMax, rMin, rMax, x, y, id
  243.     c = col: r = row 'get copies for recursive sub
  244.     IF c > 2 THEN cMin = c - 1 ELSE cMin = 1
  245.     IF c < Xarrd - 1 THEN cMax = c + 1 ELSE cMax = Xarrd
  246.     IF r > 2 THEN rMin = r - 1 ELSE rMin = 1
  247.     IF r < Yarrd - 1 THEN rMax = r + 1 ELSE rMax = Yarrd
  248.     FOR y = rMin TO rMax
  249.         FOR x = cMin TO cMax
  250.             IF b(x, y).reveal = 0 THEN
  251.                 id = b(x, y).id
  252.                 IF b(x, y).mine = 0 AND id = 0 THEN
  253.                     b(x, y).reveal = -1 'mark played
  254.                     showCell x, y
  255.                     sweepZeros x, y
  256.                 ELSE
  257.                     IF b(x, y).mine = 0 AND id >= 1 AND id <= 8 THEN
  258.                         b(x, y).reveal = -1
  259.                         showCell x, y
  260.                     END IF
  261.                 END IF
  262.             END IF
  263.         NEXT
  264.     NEXT
  265.  
  266. 'center the text around (x, y) point, needs a graphics screen!
  267. SUB cText (x, y, textHeight AS SINGLE, K AS _UNSIGNED LONG, txt$)
  268.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult!, xlen
  269.     fg = _DEFAULTCOLOR
  270.     'screen snapshot
  271.     cur& = _DEST
  272.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  273.     _DEST I&
  274.     COLOR K, _RGBA32(0, 0, 0, 0)
  275.     _PRINTSTRING (0, 0), txt$
  276.     mult! = textHeight / 16
  277.     xlen = LEN(txt$) * 8 * mult!
  278.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  279.     COLOR fg
  280.     _FREEIMAGE I&
  281.  
  282. FUNCTION rightOf$ (source$, of$)
  283.     IF INSTR(source$, of$) > 0 THEN rightOf$ = MID$(source$, INSTR(source$, of$) + LEN(of$))
  284.  
  285. FUNCTION getChar$ (fromStr$)
  286.     DIM OK AS INTEGER, k$
  287.     WHILE OK = 0
  288.         k$ = INKEY$
  289.         IF LEN(k$) THEN
  290.             IF INSTR(fromStr$, k$) <> 0 THEN OK = -1
  291.         END IF
  292.         _LIMIT 200
  293.     WEND
  294.     _KEYCLEAR
  295.     getChar$ = k$
  296.  
  297.  

EDIT: shorten 2nd _TITLE for smaller screens
Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 04, 2019, 01:18:03 pm
and fine also customizable version.
Title: Re: Quick Minesweeper
Post by: bplus on August 04, 2019, 02:55:17 pm
Thanks TempodiBasic,

I am putting together sound effects and maybe images for next round of customization's.
Title: Re: Quick Minesweeper
Post by: bplus on August 04, 2019, 11:12:23 pm
And here is Minesweeper you may customize and with sound effects added:
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-08-01
  2. ' update 2019-08-02 _title change line number so can reflect changes to mines constant.
  3. ' 2019-08-03 Minesweeper Custom Field.bas creates a file: "Custom Field Specs.txt"
  4. ' that you edit with your text editor, if you select that option in the opening screen menu.
  5.  
  6. ' 2019-08-04 add assets can use to the customize file, also if the file exits don't rewrite a blank one.
  7. ' Thanks to SoundBible for sounds dowmloaded under License Attribution 3.0
  8. ' http://soundbible.com
  9. ' https://creativecommons.org/licenses/by/3.0/us/
  10.  
  11. DEFINT A-Z
  12. DIM SHARED xmax, ymax, Xsq, Ysq, Xarrd, Yarrd, mines, Xmargin, Ymargin 'set all this in customField sub
  13. DIM SHARED ToggleSnd AS LONG, BombSnd AS LONG, ApplauseSnd AS LONG, ButtonSnd AS LONG, AhhSnd AS LONG, ShipBellSnd AS LONG
  14. DIM SHARED SwooshSnd AS LONG
  15. _TITLE "Minesweeper Custom wAssets"
  16. customField
  17. ToggleSnd = _SNDOPEN("Toggle.wav") '
  18. BombSnd = _SNDOPEN("BigBomb.wav") '
  19. ApplauseSnd = _SNDOPEN("Applause.wav") '
  20. ButtonSnd = _SNDOPEN("Button.wav") '
  21. ShipBellSnd = _SNDOPEN("Ships bell.wav") '
  22. SwooshSnd = _SNDOPEN("Swoosh.wav")
  23. DIM SHARED rndSnd(9) AS LONG
  24. rndSnd(0) = _SNDOPEN("Ahhh.wav") '
  25. rndSnd(1) = _SNDOPEN("BuzzFade.wav") '
  26. rndSnd(2) = _SNDOPEN("Carpet Ripping.wav") '
  27. rndSnd(3) = _SNDOPEN("DrumRoll.wav") '
  28. rndSnd(4) = _SNDOPEN("DyingNeon.wav") '
  29. rndSnd(5) = _SNDOPEN("ElectricMotor.wav") '
  30. rndSnd(6) = _SNDOPEN("Slime.wav")
  31. rndSnd(7) = _SNDOPEN("Gaffy.wav") '
  32. rndSnd(8) = _SNDOPEN("Monkey.wav") '
  33. rndSnd(9) = _SNDOPEN("Rooster.wav") '
  34. 'DIM i    'test load and sounds
  35. 'FOR i = 6 TO 6
  36. '    _SNDPLAY (rndSnd(i))
  37. '    PRINT i;
  38. '    IF rndSnd(i) = 0 THEN PRINT i; " not loaded." ELSE PRINT
  39. '    _DELAY 3
  40. 'NEXT
  41.  
  42. IF ButtonSnd = 0 THEN PRINT "No Button snd": END
  43. _TITLE STR$(mines) + " Minesweeper: left click cell to reveal, right click to mark mine (red)"
  44. SCREEN _NEWIMAGE(xmax, ymax, 32)
  45. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  46. TYPE boardType
  47.     id AS INTEGER '0 to 8 neighbor mines
  48.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  49.     mine AS INTEGER '0 or -1
  50. REDIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType 'oversize the board to make it easy to count mines
  51. DIM SHARED restart
  52. DIM gameOver, cc, cr, mbN, c, r, s$, sz!
  53. restart = 1
  54.     gameOver = 0
  55.     WHILE gameOver = 0
  56.         IF restart THEN initialize
  57.         mbN = 0
  58.         getCell cc, cr, mbN
  59.         'LOCATE 1, 1: PRINT cc, cr, mbN
  60.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  61.             IF b(cc, cr).mine THEN 'ka boom
  62.                 _SNDPLAY BombSnd
  63.                 FOR r = 1 TO Yarrd 'show all mines
  64.                     FOR c = 1 TO Xarrd
  65.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  66.                     NEXT
  67.                 NEXT
  68.                 s$ = "KA - BOOOMMMM!"
  69.                 sz! = 1.2 * xmax / LEN(s$)
  70.                 cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  71.                 cText xmax / 2 - 4, ymax / 2 - 4, sz!, &HFFFF0000, s$
  72.                 cText xmax / 2 - 8, ymax / 2 - 8, sz!, &HFFFFFF00, s$
  73.                 gameOver = -1
  74.                 _DELAY 7
  75.             ELSE
  76.                 IF b(cc, cr).reveal = 0 THEN
  77.                     IF RND < .75 THEN _SNDPLAY ButtonSnd ELSE _SNDPLAY rndSnd(INT(RND * 10))
  78.                     b(cc, cr).reveal = -1: showCell cc, cr
  79.                     IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  80.                 END IF
  81.             END IF
  82.         ELSEIF mbN = 2 THEN
  83.             _SNDPLAY ToggleSnd
  84.             IF b(cc, cr).reveal = 1 THEN
  85.                 b(cc, cr).reveal = 0: showCell cc, cr
  86.             ELSE
  87.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  88.             END IF
  89.         END IF
  90.         IF TFwin THEN
  91.             _SNDPLAY ApplauseSnd
  92.             s$ = "Good Job!"
  93.             sz! = 1.2 * xmax / LEN(s$)
  94.             cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  95.             cText xmax / 2 - 1, ymax / 2 - 2, sz!, &HFF000055, s$
  96.             _DELAY 5
  97.             gameOver = -1
  98.         END IF
  99.         _LIMIT 60
  100.     WEND
  101.     restart = 1
  102.  
  103. 'set all this 'DIM SHARED xmax, ymax, Xsq, Ysq, XarrD, YarrD, mines, Xmargin, Ymargin
  104. SUB customField
  105.     DIM fName$, fe, fLine$, p, inCnt, beenHere, w$, allow$, choice$
  106.  
  107.     fName$ = "Custom Field Specs.txt"
  108.     IF _FILEEXISTS(fName$) THEN fe = -1 ELSE fe = 0
  109.     allow$ = "12" + CHR$(27)
  110.     PRINT
  111.     PRINT "     Minesweeper options:"
  112.     PRINT
  113.     PRINT "  1. Use mine field settings: 800 x 600 screen with 9 X 9 cells and 10 mines."
  114.     PRINT "  2. Customize your own field settings."
  115.     IF fe THEN PRINT "  3. Use the last customized mine field settings.": allow$ = allow$ + "3"
  116.     PRINT
  117.     PRINT "     or press esc to quit."
  118.     choice$ = getChar$(allow$)
  119.     SELECT CASE choice$
  120.         CASE "1": GOTO default
  121.         CASE "2": GOSUB editCustom
  122.         CASE "3": GOSUB loadCustom
  123.         CASE ELSE: SYSTEM
  124.     END SELECT
  125.     EXIT SUB
  126.  
  127.     editCustom:
  128.     IF fe = 0 THEN 'need to start the file, otherwise just edit what's there
  129.         OPEN fName$ FOR OUTPUT AS #1
  130.         PRINT #1, " "
  131.         PRINT #1, "     Custom Field Specs for your Minesweeper Game"
  132.         PRINT #1, " "
  133.         PRINT #1, " Please fill out the right side of all Equal signs."
  134.         PRINT #1, " "
  135.         PRINT #1, "   X dimensions across the screen:"
  136.         PRINT #1, "                  Screen Width (pixels) = "
  137.         PRINT #1, "      Number of Horizontal Cells Across = "
  138.         PRINT #1, "          Cell Width (12 - 100? pixels) = "
  139.         PRINT #1, " "
  140.         PRINT #1, "   Y dimensions going down:"
  141.         PRINT #1, "                 Screen Height (pixels) = "
  142.         PRINT #1, "                   Number of Cells Down = "
  143.         PRINT #1, "          Cell Height (24 - 80? pixels) = "
  144.         PRINT #1, " "
  145.         PRINT #1, "The percent of mines (8 easy - 15 hard) = "
  146.         PRINT #1, " "
  147.         PRINT #1, "    To finish, Save the file and then close the editor."
  148.         CLOSE #1
  149.     END IF
  150.     ' I picked up this shortcut from Ken, normally I would call a text editor that I don't know if you have!
  151.     SHELL fName$
  152.     GOSUB loadCustom
  153.     RETURN
  154.  
  155.     loadCustom:
  156.     beenHere = beenHere + 1 'we'll give it 5 tries
  157.     IF beenHere > 5 THEN
  158.         PRINT "OK we tried 5 times, going with default settings..."
  159.         GOTO default 'exit from there
  160.     END IF
  161.     inCnt = 0
  162.     OPEN fName$ FOR INPUT AS #1
  163.     WHILE EOF(1) = 0 ' look to get 7 values from 7 = signs
  164.         LINE INPUT #1, fLine$
  165.         'PRINT fLine$
  166.         p = INSTR(fLine$, "=")
  167.         IF p > 0 THEN
  168.             inCnt = inCnt + 1
  169.             SELECT CASE inCnt
  170.                 CASE 1: xmax = VAL(rightOf$(fLine$, "="))
  171.                 CASE 2: Xarrd = VAL(rightOf$(fLine$, "="))
  172.                 CASE 3: Xsq = VAL(rightOf$(fLine$, "="))
  173.                 CASE 4: ymax = VAL(rightOf$(fLine$, "="))
  174.                 CASE 5: Yarrd = VAL(rightOf$(fLine$, "="))
  175.                 CASE 6: Ysq = VAL(rightOf$(fLine$, "="))
  176.                 CASE 7: mines = VAL(rightOf$(fLine$, "=")) * Xarrd * Yarrd / 100
  177.             END SELECT
  178.             IF inCnt = 7 THEN EXIT WHILE
  179.         END IF
  180.     WEND
  181.     CLOSE #1
  182.  
  183.     'debug....................
  184.     'PRINT "xmax = "; xmax, "ymax = "; ymax, "Xarrd = "; Xarrd, "Yarrd = "; Yarrd
  185.     'PRINT "Xsq = "; Xsq, "Ysq = "; Ysq, "Mines = "; mines
  186.     'INPUT "OK... enter "; w$
  187.  
  188.     IF inCnt = 7 THEN
  189.         IF Xsq >= 12 THEN
  190.             IF Ysq >= 24 THEN
  191.                 IF xmax >= Xarrd * Xsq THEN
  192.                     IF ymax >= Yarrd * Ysq THEN 'all good
  193.                         GOSUB calcMargins: EXIT SUB
  194.                     ELSE
  195.                         PRINT "Opps, Screen height is not big enough for Y cells * pixels down. "
  196.                     END IF
  197.                 ELSE
  198.                     PRINT "Opps, Screen width is not big enough for X cells * pixels across. "
  199.                 END IF
  200.             ELSE
  201.                 PRINT "Y Cell pixels down probably not enough. "
  202.             END IF
  203.         ELSE
  204.             PRINT "X Cell pixels across probably not enough. "
  205.         END IF
  206.     ELSE
  207.         PRINT "We did not get everything filled out by = signs."
  208.     END IF
  209.     PRINT: PRINT "Press any to continue.. "
  210.     SLEEP
  211.     SHELL fName$
  212.     GOTO loadCustom
  213.     RETURN
  214.  
  215.     calcMargins:
  216.     Xmargin = (xmax - Xarrd * Xsq) / 2: Ymargin = (ymax - Yarrd * Ysq) / 2
  217.     RETURN
  218.  
  219.     default:
  220.     xmax = 800: ymax = 600: Xarrd = 9: Yarrd = 9: Xsq = 60: Ysq = 60: mines = 10: GOSUB calcMargins
  221.  
  222.  
  223. SUB initialize ()
  224.     DIM minesPlaced, rx, ry, x, y, nMines
  225.     restart = 0
  226.     _SNDPLAY ShipBellSnd
  227.     REDIM b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType
  228.     minesPlaced = 0
  229.     WHILE minesPlaced < mines
  230.         rx = INT(RND * Xarrd) + 1: ry = INT(RND * Yarrd) + 1
  231.         IF b(rx, ry).mine = 0 THEN
  232.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  233.         END IF
  234.     WEND
  235.     'count mines amoung the neighbors
  236.     FOR y = 1 TO Yarrd
  237.         FOR x = 1 TO Xarrd
  238.             IF b(x, y).mine <> -1 THEN 'not already a mine
  239.                 nMines = b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  240.                 nMines = nMines + b(x, y - 1).mine + b(x, y + 1).mine
  241.                 nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  242.                 b(x, y).id = -nMines
  243.             ELSE
  244.                 b(x, y).id = 0
  245.             END IF
  246.             b(x, y).reveal = 0
  247.             showCell x, y
  248.         NEXT
  249.     NEXT
  250.  
  251. SUB showCell (c, r)
  252.     DIM x, y, clr AS _UNSIGNED LONG, sz
  253.     x = (c - 1) * Xsq + Xmargin: y = (r - 1) * Ysq + Ymargin
  254.     SELECT CASE b(c, r).reveal
  255.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  256.         CASE 0: clr = &HFF008800 'hidden green
  257.         CASE 1: clr = &HFFFF0000 'marked red
  258.     END SELECT
  259.     LINE (x, y)-STEP(Xsq - 1, Ysq - 1), clr, BF
  260.     LINE (x, y)-STEP(Xsq - 1, Ysq - 1), &HFF000000, B
  261.     IF Xsq < Ysq THEN sz = .8 * Xsq ELSE sz = .8 * Ysq
  262.     IF b(c, r).reveal = -1 THEN
  263.         IF b(c, r).id > 0 THEN cText x + Xsq / 2, y + Ysq / 2, sz, &HFF000000, _TRIM$(STR$(b(c, r).id))
  264.         IF b(c, r).mine = -1 THEN cText x + Xsq / 2, y + Ysq / 2, sz, &HFFFFFFFF, "*"
  265.     END IF
  266.  
  267. FUNCTION TFwin
  268.     DIM c, x, y
  269.     FOR y = 1 TO Yarrd
  270.         FOR x = 1 TO Xarrd
  271.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  272.         NEXT
  273.     NEXT
  274.     IF c = Xarrd * Yarrd - mines THEN TFwin = -1
  275.  
  276. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  277.     DIM m, mx, my, mb1, mb2
  278.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  279.     IF mb1 THEN mbNum = 1
  280.     IF mb2 THEN mbNum = 2
  281.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  282.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  283.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  284.             mx = _MOUSEX: my = _MOUSEY
  285.         WEND
  286.         returnCol = INT((mx - Xmargin) / Xsq) + 1: returnRow = INT((my - Ymargin) / Ysq) + 1
  287.         IF returnCol < 1 OR returnCol > Xarrd OR returnRow < 1 OR returnRow > Yarrd THEN mbNum = 0
  288.     END IF
  289.  
  290. SUB sweepZeros (col, row) ' recursive sweep with Rod's limits set
  291.     DIM c, r, cMin, cMax, rMin, rMax, x, y, id
  292.     _SNDPLAY SwooshSnd
  293.     c = col: r = row 'get copies for recursive sub
  294.     IF c > 2 THEN cMin = c - 1 ELSE cMin = 1
  295.     IF c < Xarrd - 1 THEN cMax = c + 1 ELSE cMax = Xarrd
  296.     IF r > 2 THEN rMin = r - 1 ELSE rMin = 1
  297.     IF r < Yarrd - 1 THEN rMax = r + 1 ELSE rMax = Yarrd
  298.     FOR y = rMin TO rMax
  299.         FOR x = cMin TO cMax
  300.             IF b(x, y).reveal = 0 THEN
  301.                 id = b(x, y).id
  302.                 IF b(x, y).mine = 0 AND id = 0 THEN
  303.                     b(x, y).reveal = -1 'mark played
  304.                     showCell x, y
  305.                     sweepZeros x, y
  306.                 ELSE
  307.                     IF b(x, y).mine = 0 AND id >= 1 AND id <= 8 THEN
  308.                         b(x, y).reveal = -1
  309.                         showCell x, y
  310.                     END IF
  311.                 END IF
  312.             END IF
  313.         NEXT
  314.     NEXT
  315.  
  316. 'center the text around (x, y) point, needs a graphics screen!
  317. SUB cText (x, y, textHeight AS SINGLE, K AS _UNSIGNED LONG, txt$)
  318.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult!, xlen
  319.     fg = _DEFAULTCOLOR
  320.     'screen snapshot
  321.     cur& = _DEST
  322.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  323.     _DEST I&
  324.     COLOR K, _RGBA32(0, 0, 0, 0)
  325.     _PRINTSTRING (0, 0), txt$
  326.     mult! = textHeight / 16
  327.     xlen = LEN(txt$) * 8 * mult!
  328.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  329.     COLOR fg
  330.     _FREEIMAGE I&
  331.  
  332. FUNCTION rightOf$ (source$, of$)
  333.     IF INSTR(source$, of$) > 0 THEN rightOf$ = MID$(source$, INSTR(source$, of$) + LEN(of$))
  334.  
  335. FUNCTION getChar$ (fromStr$)
  336.     DIM OK AS INTEGER, k$
  337.     WHILE OK = 0
  338.         k$ = INKEY$
  339.         IF LEN(k$) THEN
  340.             IF INSTR(fromStr$, k$) <> 0 THEN OK = -1
  341.         END IF
  342.         _LIMIT 200
  343.     WEND
  344.     _KEYCLEAR
  345.     getChar$ = k$
  346.  
  347.  

It's currently set to pretty easy game, just don't click top left cell for starters, the percentages are bad.
Title: Re: Quick Minesweeper
Post by: SMcNeill on August 07, 2019, 06:25:13 pm
You like various challenges, bplus; maybe you'll like the idea for this one -- create a hexagonal minesweeper, just to be different.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2. DrawMap 50, 50, 24, 12, 10, -1
  3.  
  4.  
  5. SUB DrawMap (TopLeftX, TopLeftY, Hexsize, MapXLimit, MapYLimit, C)
  6.     F = _FONT
  7.     HexWidth = SQR(3) * Hexsize: HexHeight = 2 * Hexsize 'Height and Width of each individual hex
  8.     FOR X = 0 TO MapXLimit
  9.         FOR Y = 0 TO MapYLimit
  10.             CenterX = TopLeftX + X * HexWidth
  11.             CenterY = TopLeftY + Y * HexHeight * 0.75
  12.             IF Y MOD 2 THEN CenterX = CenterX + HexWidth / 2 'offset for odd/even rows
  13.             Point1X = CenterX - HexWidth / 2
  14.             Point2X = CenterX
  15.             Point3x = CenterX + HexWidth / 2
  16.             Point1y = CenterY - HexHeight / 2
  17.             Point2y = CenterY - HexHeight / 4
  18.             Point3y = CenterY + HexHeight / 4
  19.             Point4y = CenterY + HexHeight / 2
  20.             LINE (Point1X, Point2y)-(Point2X, Point1y), C 'NorthWest
  21.             LINE (Point2X, Point1y)-(Point3x, Point2y), C 'NorthEast
  22.             LINE (Point3x, Point2y)-(Point3x, Point3y), C 'East
  23.             LINE (Point3x, Point3y)-(Point2X, Point4y), C 'SouthEast
  24.             LINE (Point2X, Point4y)-(Point1X, Point3y), C 'SouthWest
  25.             LINE (Point1X, Point3y)-(Point1X, Point2y), C 'West
  26.  
  27.             'If we want the coordinates, we use the following, else just delete or remark out the next few lines:
  28.             _FONT 8
  29.             COLOR &HFFFF0000, 0
  30.             CenterText Point1X, Point1y, Point3x, Point4y, _TRIM$(STR$(X)) + "," + _TRIM$(STR$(Y))
  31.         NEXT
  32.     NEXT
  33.     _FONT F
  34.     COLOR DC, BG
  35.  
  36. SUB CenterText (x1, y1, x2, y2, text$)
  37.     text$ = _TRIM$(text$)
  38.     xmax = x2 - x1: ymax = y2 - y1
  39.     textlength = _PRINTWIDTH(text$)
  40.     xpos = (xmax - textlength) / 2
  41.     ypos = (ymax - _FONTHEIGHT) / 2
  42.     _PRINTSTRING (x1 + xpos, y1 + ypos), text$

Trickiest part here is remembering that diagonals are only a half step off.  View the example above and study the coordinate system carefully:

Y  coordinates change by 1 step each time we move in the grid.
X coordinates only change by .5 each step we move in the grid. 
Title: Re: Quick Minesweeper
Post by: bplus on August 07, 2019, 09:09:35 pm
:) Thanks Steve, you got me thinking.
Title: Re: Quick Minesweeper
Post by: bplus on August 07, 2019, 11:26:06 pm
OK the quick version seems to be working OK:
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus 2019-08-07 instigated by Steve McNeill
  2. '2019-08-08 fixed incomplete sweepZeros problem
  3.  
  4. DEFINT A-Z '      10 x 10 Hex grid, 12% mines
  5. CONST xmax = 510, ymax = 430, cellR = 25, arrD = 10, mines = 10
  6. DIM SHARED xspacing!, yspacing!
  7. xspacing! = 2 * cellR * COS(_D2R(30)): yspacing! = cellR * (1 + SIN(_D2R(30)))
  8.  
  9. _TITLE STR$(mines) + " Mine-sweeper Hexagon Style!: left click cell to reveal, right click to mark mine (red)"
  10. SCREEN _NEWIMAGE(xmax, ymax, 32)
  11. _SCREENMOVE 300, 10
  12. TYPE boardType
  13.     x AS SINGLE 'pixel location
  14.     y AS SINGLE 'pixel location
  15.     id AS INTEGER '0 to 8 neighbor mines
  16.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  17.     mine AS INTEGER '0 or -1
  18. REDIM SHARED b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType 'oversize the board to make it easy to count mines
  19. DIM SHARED restart, dxdyOFF(6, 1), dxdyNoOff(6, 1)
  20. DIM gameOver, cc, cr, mbN, c, r, i, dx, dy
  21.  
  22. 'set the 2 sets of directions to neighbors a cell could have depending if the row is offset or not
  23. RESTORE NoOff
  24. FOR i = 0 TO 5
  25.     READ dx, dy
  26.     dxdyNoOff(i, 0) = dx: dxdyNoOff(i, 1) = dy
  27. RESTORE xOff
  28. FOR i = 0 TO 5
  29.     READ dx, dy
  30.     dxdyOFF(i, 0) = dx: dxdyOFF(i, 1) = dy
  31.  
  32. restart = 1
  33.     gameOver = 0
  34.     WHILE gameOver = 0
  35.         IF restart THEN initialize
  36.         mbN = 0
  37.         getCell cc, cr, mbN
  38.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  39.             IF b(cc, cr).mine THEN 'ka boom
  40.                 FOR r = 1 TO arrD 'show all mines
  41.                     FOR c = 1 TO arrD
  42.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  43.                     NEXT
  44.                 NEXT
  45.                 cText xmax / 2, ymax / 2, 72, &HFF000000, "KA - BOOOMMMM!"
  46.                 cText xmax / 2 - 4, ymax / 2 - 4, 64, &HFFFF0000, "KA - BOOOMMMM!"
  47.                 cText xmax / 2 - 8, ymax / 2 - 8, 56, &HFFFFFF00, "KA - BOOOMMMM!"
  48.                 gameOver = -1
  49.                 _DELAY 7
  50.             ELSE
  51.                 b(cc, cr).reveal = -1: showCell cc, cr
  52.                 IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  53.             END IF
  54.         ELSEIF mbN = 2 THEN
  55.             IF b(cc, cr).reveal = 1 THEN
  56.                 b(cc, cr).reveal = 0: showCell cc, cr
  57.             ELSE
  58.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  59.             END IF
  60.         END IF
  61.         IF TFwin THEN
  62.             cText xmax / 2, ymax / 2, 80, &HFF001144, "Good Job!"
  63.             cText xmax / 2 - 1, ymax / 2 - 2, 80, &HFF000055, "Good Job!"
  64.             _DELAY 5
  65.             gameOver = -1
  66.         END IF
  67.         _LIMIT 60
  68.     WEND
  69.     restart = 1
  70.  
  71. NoOff:
  72. DATA 1,0,0,-1,0,1,-1,-1,-1,0,-1,1
  73.  
  74. xOff:
  75. DATA -1,0,0,-1,0,1,1,-1,1,0,1,1
  76.  
  77. SUB initialize ()
  78.     DIM minesPlaced, rx, ry, x, y, nMines, xoffset!
  79.     CLS
  80.     restart = 0
  81.     REDIM b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType
  82.     minesPlaced = 0
  83.     WHILE minesPlaced < mines
  84.         rx = INT(RND * arrD) + 1: ry = INT(RND * arrD) + 1
  85.         IF b(rx, ry).mine = 0 THEN
  86.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  87.         END IF
  88.     WEND
  89.     'count mines amoung the neighbors
  90.     FOR y = 1 TO arrD
  91.         IF y MOD 2 = 0 THEN xoffset! = .5 * xspacing! ELSE xoffset! = 0
  92.         FOR x = 1 TO arrD
  93.             IF b(x, y).mine <> -1 THEN 'not already a mine
  94.                 '2 sets of neighbors depending if x offset or not
  95.                 IF xoffset! > .1 THEN
  96.                     nMines = b(x - 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  97.                     nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  98.                 ELSE
  99.                     nMines = b(x + 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  100.                     nMines = nMines + b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  101.                 END IF
  102.                 b(x, y).id = -nMines
  103.             ELSE
  104.                 b(x, y).id = 0
  105.             END IF
  106.             b(x, y).x = x * xspacing! + xoffset! + 5
  107.             b(x, y).y = y * yspacing! + 5
  108.             b(x, y).reveal = 0
  109.             showCell x, y
  110.         NEXT
  111.     NEXT
  112.  
  113. SUB showCell (c, r)
  114.     DIM da, x!, y!, lastx!, lasty!, clr AS _UNSIGNED LONG
  115.     SELECT CASE b(c, r).reveal
  116.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  117.         CASE 0: clr = &HFF008800 'hidden green
  118.         CASE 1: clr = &HFFFF0000 'marked red
  119.     END SELECT
  120.     lastx! = b(c, r).x + cellR * COS(_D2R(-30))
  121.     lasty! = b(c, r).y + cellR * SIN(_D2R(-30))
  122.     FOR da = 30 TO 330 STEP 60
  123.         x! = b(c, r).x + cellR * COS(_D2R(da))
  124.         y! = b(c, r).y + cellR * SIN(_D2R(da))
  125.         LINE (lastx!, lasty!)-(x!, y!), &HFFFF00FF
  126.         lastx! = x!: lasty! = y!
  127.     NEXT
  128.     PAINT (b(c, r).x, b(c, r).y), clr, &HFFFF00FF
  129.     IF b(c, r).reveal = -1 THEN
  130.         'cText b(c, r).x, b(c, r).y, 15, &HFF000000, _TRIM$(STR$(c)) + "," + _TRIM$(STR$(r))
  131.         IF b(c, r).id > 0 THEN cText b(c, r).x, b(c, r).y, 35, &HFF000000, _TRIM$(STR$(b(c, r).id))
  132.         IF b(c, r).mine = -1 THEN cText b(c, r).x, b(c, r).y, 35, &HFFFFFFFF, "*"
  133.     END IF
  134.  
  135. FUNCTION TFwin
  136.     DIM c, x, y
  137.     FOR y = 1 TO arrD
  138.         FOR x = 1 TO arrD
  139.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  140.         NEXT
  141.     NEXT
  142.     IF c = arrD * arrD - mines THEN TFwin = -1
  143.  
  144. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  145.     DIM m, mx, my, mb1, mb2, r, c
  146.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  147.     IF mb1 THEN mbNum = 1
  148.     IF mb2 THEN mbNum = 2
  149.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  150.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  151.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  152.             mx = _MOUSEX: my = _MOUSEY
  153.         WEND
  154.         FOR r = 1 TO arrD
  155.             FOR c = 1 TO arrD
  156.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xspacing! THEN
  157.                     returnCol = c: returnRow = r: EXIT SUB
  158.                 END IF
  159.             NEXT
  160.         NEXT
  161.         mbNum = 0 'still here then clicked wrong
  162.     END IF
  163.  
  164. SUB sweepZeros (col, row)
  165.     DIM c, r, d, x, y, id
  166.     c = col: r = row 'get copies for recursive sub
  167.     FOR d = 0 TO 5
  168.         IF r MOD 2 = 0 THEN
  169.             x = dxdyOFF(d, 0) + c: y = dxdyOFF(d, 1) + r
  170.         ELSE
  171.             x = dxdyNoOff(d, 0) + c: y = dxdyNoOff(d, 1) + r
  172.         END IF
  173.         IF x >= 1 AND x <= arrD AND y >= 1 AND y <= arrD THEN
  174.             IF b(x, y).reveal = 0 THEN
  175.                 id = b(x, y).id
  176.                 IF b(x, y).mine = 0 AND id = 0 THEN
  177.                     b(x, y).reveal = -1 'mark played
  178.                     showCell x, y
  179.                     sweepZeros x, y
  180.                 ELSEIF b(x, y).mine = 0 AND id >= 1 THEN
  181.                     b(x, y).reveal = -1
  182.                     showCell x, y
  183.                 END IF
  184.             END IF
  185.         END IF
  186.     NEXT
  187.  
  188. 'center the text around (x, y) point, needs a graphics screen!
  189. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  190.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  191.     fg = _DEFAULTCOLOR
  192.     'screen snapshot
  193.     cur& = _DEST
  194.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  195.     _DEST I&
  196.     COLOR K, _RGBA32(0, 0, 0, 0)
  197.     _PRINTSTRING (0, 0), txt$
  198.     mult = textHeight / 16
  199.     xlen = LEN(txt$) * 8 * mult
  200.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  201.     COLOR fg
  202.     _FREEIMAGE I&
  203.  

hmm... the sweeper might be leaving holes

Update/Code EDIT: found the cause of the incomplete sweeps and fixed in the above code.
Title: Re: Quick Minesweeper
Post by: SMcNeill on August 07, 2019, 11:51:54 pm
Here's a little tweaking to the settings (and number sizes) so you can play around with a 30x30 grid, with 100 mines.  It looks a lot more like an actual minesweeper game to me now.  :D

Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus 2019-08-07 instigated by Steve McNeill
  2.  
  3. DEFINT A-Z '      30 x 30 Hex grid, 12% mines
  4. CONST xmax = 510, ymax = 430, cellR = 9, arrD = 30, mines = 100
  5. DIM SHARED xspacing!, yspacing!
  6. xspacing! = 2 * cellR * COS(_D2R(30)): yspacing! = cellR * (1 + SIN(_D2R(30)))
  7.  
  8. _TITLE STR$(mines) + " Mine-sweeper Hexagon Style!: left click cell to reveal, right click to mark mine (red)"
  9. SCREEN _NEWIMAGE(xmax, ymax, 32)
  10. _SCREENMOVE 300, 10
  11. TYPE boardType
  12.     x AS SINGLE 'pixel location
  13.     y AS SINGLE 'pixel location
  14.     id AS INTEGER '0 to 8 neighbor mines
  15.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  16.     mine AS INTEGER '0 or -1
  17. REDIM SHARED b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType 'oversize the board to make it easy to count mines
  18. DIM SHARED restart, dxdyOFF(5, 1), dxdyNoOff(5, 1)
  19. DIM gameOver, cc, cr, mbN, c, r, i, dx, dy
  20.  
  21. 'set the 2 sets of directions to neighbors a cell could have depending if the row is offset or not
  22. RESTORE NoOff
  23. FOR i = 0 TO 5
  24.     READ dx, dy
  25.     dxdyNoOff(i, 0) = dx: dxdyNoOff(i, 1) = dy
  26. RESTORE xOff
  27. FOR i = 0 TO 5
  28.     READ dx, dy
  29.     dxdyOFF(i, 0) = dx: dxdyOFF(i, 1) = dy
  30.  
  31. restart = 1
  32.     gameOver = 0
  33.     WHILE gameOver = 0
  34.         IF restart THEN initialize
  35.         mbN = 0
  36.         getCell cc, cr, mbN
  37.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  38.             IF b(cc, cr).mine THEN 'ka boom
  39.                 FOR r = 1 TO arrD 'show all mines
  40.                     FOR c = 1 TO arrD
  41.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  42.                     NEXT
  43.                 NEXT
  44.                 cText xmax / 2, ymax / 2, 72, &HFF000000, "KA - BOOOMMMM!"
  45.                 cText xmax / 2 - 4, ymax / 2 - 4, 64, &HFFFF0000, "KA - BOOOMMMM!"
  46.                 cText xmax / 2 - 8, ymax / 2 - 8, 56, &HFFFFFF00, "KA - BOOOMMMM!"
  47.                 gameOver = -1
  48.                 _DELAY 7
  49.             ELSE
  50.                 b(cc, cr).reveal = -1: showCell cc, cr
  51.                 IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  52.             END IF
  53.         ELSEIF mbN = 2 THEN
  54.             IF b(cc, cr).reveal = 1 THEN
  55.                 b(cc, cr).reveal = 0: showCell cc, cr
  56.             ELSE
  57.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  58.             END IF
  59.         END IF
  60.         IF TFwin THEN
  61.             cText xmax / 2, ymax / 2, 80, &HFF001144, "Good Job!"
  62.             cText xmax / 2 - 1, ymax / 2 - 2, 80, &HFF000055, "Good Job!"
  63.             _DELAY 15
  64.             gameOver = -1
  65.         END IF
  66.         _LIMIT 60
  67.     WEND
  68.     restart = 1
  69.  
  70. NoOff:
  71. DATA 1,0,0,-1,0,1,-1,-1,-1,0,-1,1
  72.  
  73. xOff:
  74. DATA -1,0,0,-1,0,1,1,-1,1,0,1,1
  75.  
  76. SUB initialize ()
  77.     DIM minesPlaced, rx, ry, x, y, nMines, xoffset!
  78.     CLS
  79.     restart = 0
  80.     REDIM b(0 TO arrD + 1, 0 TO arrD + 1) AS boardType
  81.     minesPlaced = 0
  82.     WHILE minesPlaced < mines
  83.         rx = INT(RND * arrD) + 1: ry = INT(RND * arrD) + 1
  84.         IF b(rx, ry).mine = 0 THEN
  85.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  86.         END IF
  87.     WEND
  88.     'count mines amoung the neighbors
  89.     FOR y = 1 TO arrD
  90.         IF y MOD 2 = 0 THEN xoffset! = .5 * xspacing! ELSE xoffset! = 0
  91.         FOR x = 1 TO arrD
  92.             IF b(x, y).mine <> -1 THEN 'not already a mine
  93.                 '2 sets of neighbors depending if x offset or not
  94.                 IF xoffset! > .1 THEN
  95.                     nMines = b(x - 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  96.                     nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  97.                 ELSE
  98.                     nMines = b(x + 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  99.                     nMines = nMines + b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  100.                 END IF
  101.                 b(x, y).id = -nMines
  102.             ELSE
  103.                 b(x, y).id = 0
  104.             END IF
  105.             b(x, y).x = x * xspacing! + xoffset! + 5
  106.             b(x, y).y = y * yspacing! + 5
  107.             b(x, y).reveal = 0
  108.             showCell x, y
  109.         NEXT
  110.     NEXT
  111.  
  112. SUB showCell (c, r)
  113.     DIM da, x!, y!, lastx!, lasty!, clr AS _UNSIGNED LONG
  114.     SELECT CASE b(c, r).reveal
  115.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  116.         CASE 0: clr = &HFF008800 'hidden green
  117.         CASE 1: clr = &HFFFF0000 'marked red
  118.     END SELECT
  119.     lastx! = b(c, r).x + cellR * COS(_D2R(-30))
  120.     lasty! = b(c, r).y + cellR * SIN(_D2R(-30))
  121.     FOR da = 30 TO 330 STEP 60
  122.         x! = b(c, r).x + cellR * COS(_D2R(da))
  123.         y! = b(c, r).y + cellR * SIN(_D2R(da))
  124.         LINE (lastx!, lasty!)-(x!, y!), &HFFFF00FF
  125.         lastx! = x!: lasty! = y!
  126.     NEXT
  127.     PAINT (b(c, r).x, b(c, r).y), clr, &HFFFF00FF
  128.     IF b(c, r).reveal = -1 THEN
  129.         'cText b(c, r).x, b(c, r).y, 15, &HFF000000, _TRIM$(STR$(c)) + "," + _TRIM$(STR$(r))
  130.         IF b(c, r).id > 0 THEN cText b(c, r).x, b(c, r).y, 35, &HFF000000, _TRIM$(STR$(b(c, r).id))
  131.         IF b(c, r).mine = -1 THEN cText b(c, r).x, b(c, r).y, 35, &HFFFFFFFF, "*"
  132.     END IF
  133.  
  134. FUNCTION TFwin
  135.     DIM c, x, y
  136.     FOR y = 1 TO arrD
  137.         FOR x = 1 TO arrD
  138.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  139.         NEXT
  140.     NEXT
  141.     IF c = arrD * arrD - mines THEN TFwin = -1
  142.  
  143. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  144.     DIM m, mx, my, mb1, mb2, r, c
  145.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  146.     IF mb1 THEN mbNum = 1
  147.     IF mb2 THEN mbNum = 2
  148.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  149.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  150.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  151.             mx = _MOUSEX: my = _MOUSEY
  152.         WEND
  153.         FOR r = 1 TO arrD
  154.             FOR c = 1 TO arrD
  155.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xspacing! THEN
  156.                     returnCol = c: returnRow = r: EXIT SUB
  157.                 END IF
  158.             NEXT
  159.         NEXT
  160.         mbNum = 0 'still here then clicked wrong
  161.     END IF
  162.  
  163. SUB sweepZeros (col, row) ' recursive sweep with Rod's limits set
  164.     DIM c, r, d, x, y, id
  165.     c = col: r = row 'get copies for recursive sub
  166.     FOR d = 0 TO 5
  167.         IF r MOD 2 = 0 THEN
  168.             x = dxdyNoOff(d, 0) + c: y = dxdyNoOff(d, 1) + r
  169.         ELSE
  170.             x = dxdyOFF(d, 0) + c: y = dxdyOFF(d, 1) + r
  171.         END IF
  172.         IF x >= 1 AND x <= arrD AND y >= 1 AND y <= arrD THEN
  173.             IF b(x, y).reveal = 0 THEN
  174.                 id = b(x, y).id
  175.                 IF b(x, y).mine = 0 AND id = 0 THEN
  176.                     b(x, y).reveal = -1 'mark played
  177.                     showCell x, y
  178.                     sweepZeros x, y
  179.                 ELSE
  180.                     IF b(x, y).mine = 0 AND id >= 1 AND id <= 8 THEN
  181.                         b(x, y).reveal = -1
  182.                         showCell x, y
  183.                     END IF
  184.                 END IF
  185.             END IF
  186.         END IF
  187.     NEXT
  188.  
  189. 'center the text around (x, y) point, needs a graphics screen!
  190. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  191.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  192.     fg = _DEFAULTCOLOR
  193.     'screen snapshot
  194.     cur& = _DEST
  195.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  196.     _DEST I&
  197.     COLOR K, _RGBA32(0, 0, 0, 0)
  198.     _PRINTSTRING (0, 0), txt$
  199.     mult = textHeight / 16
  200.     xlen = LEN(txt$) * 8 * mult
  201.     _PUTIMAGE (x - .15 * xlen, y - .15 * textHeight)-STEP(.33 * xlen, .33 * textHeight), I&, cur&
  202.     COLOR fg
  203.     _FREEIMAGE I&
Title: Re: Quick Minesweeper
Post by: bplus on August 08, 2019, 10:50:46 am
I found the cause of the incomplete sweeps for zeroes; they were being revealed but the sweep was stopped. Turns out I was using the wrong array for finding neighbor cells around a cell, it is different if the row is offset or not. The code is fixed in my 8/7 post.

So with that fixed I can move onto customizing minefields and using cText properly. Instead of the hack of it that Steve used to get a 30 x 30 array up fast, skip changing the cText SUB proper (and ruining it for a ToolBox procedure), the call to it should have been modified in the TextHeight argument using a mult of the cellR constant.

Shouldn't take long to get the quick version modified so that a customization for any reasonable size x, y board can be  done.
Title: Re: Quick Minesweeper
Post by: bplus on August 08, 2019, 12:42:18 pm
And here is Hexagon Minesweeper allowing Custom Field settings. To make things easy, I made the cell size constant so the custom code checks your Max screen size with the amount of cells you want horizontally and vertically to see that that many will fit, it also takes the percent of mines you want to run so you can set your own level of difficulty.

Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-08-08 from quick version of Hex Minesweeper and Minesweeper Custom Field
  2. ' Attention: this program creates a file: "Hexagon Minefield Custom Specs.txt"
  3. ' that you edit with your text editor, if you select that option in the opening screen menu.
  4.  
  5. DEFINT A-Z
  6. 'to make things easy set cellR as const at 25
  7. CONST cellR = 25 ' which makes the following constant
  8. DIM SHARED xspacing!, yspacing!
  9. xspacing! = 2 * cellR * COS(_D2R(30)): yspacing! = cellR * (1 + SIN(_D2R(30)))
  10.  
  11. DIM SHARED xmax, ymax, Xarrd, Yarrd, mines 'set all this in customField sub
  12. _TITLE "Hexagon Minesweeper: Custom Field"
  13. customField
  14. _TITLE STR$(mines) + " Minesweeper: left click reveals, right marks red"
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  17. TYPE boardType
  18.     x AS SINGLE 'pixel location
  19.     y AS SINGLE 'pixel location
  20.     id AS INTEGER '0 to 6 neighbor mines
  21.     reveal AS INTEGER ' 1 for marked, 0 hidden, -1 for revealed
  22.     mine AS INTEGER '0 or -1
  23. REDIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType 'oversize the board to make it easy to count mines
  24. DIM SHARED restart
  25. DIM gameOver, cc, cr, mbN, c, r, s$, sz!
  26. restart = 1
  27.     gameOver = 0
  28.     WHILE gameOver = 0
  29.         IF restart THEN initialize
  30.         mbN = 0
  31.         getCell cc, cr, mbN
  32.         'LOCATE 1, 1: PRINT cc, cr, mbN
  33.         IF mbN = 1 AND b(cc, cr).reveal = 0 THEN
  34.             IF b(cc, cr).mine THEN 'ka boom
  35.                 FOR r = 1 TO Yarrd 'show all mines
  36.                     FOR c = 1 TO Xarrd
  37.                         IF b(c, r).mine THEN b(c, r).reveal = -1: showCell c, r
  38.                     NEXT
  39.                 NEXT
  40.                 s$ = "KA - BOOOMMMM!"
  41.                 sz! = 1.2 * xmax / LEN(s$)
  42.                 cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  43.                 cText xmax / 2 - 4, ymax / 2 - 4, sz!, &HFFFF0000, s$
  44.                 cText xmax / 2 - 8, ymax / 2 - 8, sz!, &HFFFFFF00, s$
  45.                 gameOver = -1
  46.                 _DELAY 7
  47.             ELSE
  48.                 b(cc, cr).reveal = -1: showCell cc, cr
  49.                 IF b(cc, cr).id = 0 THEN sweepZeros cc, cr
  50.             END IF
  51.         ELSEIF mbN = 2 THEN
  52.             IF b(cc, cr).reveal = 1 THEN
  53.                 b(cc, cr).reveal = 0: showCell cc, cr
  54.             ELSE
  55.                 IF b(cc, cr).reveal = 0 THEN b(cc, cr).reveal = 1: showCell cc, cr
  56.             END IF
  57.         END IF
  58.         IF TFwin THEN
  59.             s$ = "Good Job!"
  60.             sz! = 1.2 * xmax / LEN(s$)
  61.             cText xmax / 2, ymax / 2, sz!, &HFF000000, s$
  62.             cText xmax / 2 - 1, ymax / 2 - 2, sz!, &HFF000055, s$
  63.             _DELAY 5
  64.             gameOver = -1
  65.         END IF
  66.         _LIMIT 60
  67.     WEND
  68.     restart = 1
  69.  
  70. NoOff:
  71. DATA 1,0,0,-1,0,1,-1,-1,-1,0,-1,1
  72.  
  73. xOff:
  74. DATA -1,0,0,-1,0,1,1,-1,1,0,1,1
  75.  
  76. 'set all this 'DIM SHARED xmax, ymax, Xsq, Ysq, XarrD, YarrD, mines, Xmargin, Ymargin
  77. SUB customField
  78.     DIM fName$, fe, fLine$, p, inCnt, beenHere, allow$, choice$
  79.  
  80.     fName$ = "Hexagon Minefield Custom Specs.txt"
  81.     IF _FILEEXISTS(fName$) THEN fe = -1 ELSE fe = 0
  82.     allow$ = "12" + CHR$(27)
  83.     PRINT
  84.     PRINT "     Hexagom Minesweeper options:"
  85.     PRINT
  86.     PRINT "  1. Use mine field settings: 10 X 10 cells and 10 mines."
  87.     PRINT "  2. Customize your own field settings."
  88.     IF fe THEN PRINT "  3. Use the last customized mine field settings.": allow$ = allow$ + "3"
  89.     PRINT
  90.     PRINT "     or press esc to quit."
  91.     choice$ = getChar$(allow$)
  92.     SELECT CASE choice$
  93.         CASE "1": xmax = 800: ymax = 600: Xarrd = 10: Yarrd = 10: mines = 10
  94.         CASE "2": GOSUB editCustom
  95.         CASE "3": GOSUB loadCustom
  96.         CASE ELSE: SYSTEM
  97.     END SELECT
  98.     xmax = (Xarrd + 2.5) * xspacing!: ymax = (Yarrd + 2) * yspacing!
  99.     EXIT SUB
  100.  
  101.     editCustom:
  102.     IF fe = 0 THEN
  103.         OPEN fName$ FOR OUTPUT AS #1
  104.         PRINT #1, " "
  105.         PRINT #1, "          Custom Field Specs For Your Hexagon Minesweeper Game"
  106.         PRINT #1, " "
  107.         PRINT #1, " We will be sizing the screen according to a constant cell radius of 25"
  108.         PRINT #1, " and then numbers filled in here."
  109.         PRINT #1, " "
  110.         PRINT #1, " Please fill out the right side of all Equal signs."
  111.         PRINT #1, " "
  112.         PRINT #1, "   X dimensions across the screen:"
  113.         PRINT #1, "         Your Max Screen Width (pixels) = "
  114.         PRINT #1, "      Number of Horizontal Cells Across = "
  115.         PRINT #1, " "
  116.         PRINT #1, "   Y dimensions going down:"
  117.         PRINT #1, "        Your Max Screen Height (pixels) = "
  118.         PRINT #1, "                   Number of Cells Down = "
  119.         PRINT #1, " "
  120.         PRINT #1, "The percent of mines (8 easy - 15 hard) = "
  121.         PRINT #1, " "
  122.         PRINT #1, "    To finish, Save the file and then close the editor."
  123.         CLOSE #1
  124.     END IF
  125.     ' I picked up this shortcut from Ken, normally I would call a text editor that I don't know if you have!
  126.     SHELL fName$
  127.     GOSUB loadCustom
  128.     RETURN
  129.  
  130.     loadCustom:
  131.     beenHere = beenHere + 1 'we'll give it 5 tries
  132.     IF beenHere > 5 THEN
  133.         PRINT "OK we tried 5 times, going with default settings..."
  134.         xmax = 800: ymax = 600: Xarrd = 10: Yarrd = 10: mines = 10
  135.         RETURN
  136.     END IF
  137.     inCnt = 0
  138.     OPEN fName$ FOR INPUT AS #1
  139.     WHILE EOF(1) = 0 ' look to get 5 values from 5 = signs
  140.         LINE INPUT #1, fLine$
  141.         'PRINT fLine$
  142.         p = INSTR(fLine$, "=")
  143.         IF p > 0 THEN
  144.             inCnt = inCnt + 1
  145.             SELECT CASE inCnt
  146.                 CASE 1: xmax = VAL(rightOf$(fLine$, "="))
  147.                 CASE 2: Xarrd = VAL(rightOf$(fLine$, "="))
  148.                 CASE 3: ymax = VAL(rightOf$(fLine$, "="))
  149.                 CASE 4: Yarrd = VAL(rightOf$(fLine$, "="))
  150.                 CASE 5: mines = VAL(rightOf$(fLine$, "=")) * Xarrd * Yarrd / 100
  151.             END SELECT
  152.             IF inCnt = 5 THEN EXIT WHILE
  153.         END IF
  154.     WEND
  155.     CLOSE #1
  156.     IF inCnt = 5 THEN 'alternate exit from gosub
  157.         IF xmax >= (Xarrd + 2.5) * xspacing! THEN
  158.             IF ymax < (Yarrd + 2) * yspacing! THEN 'all good
  159.                 PRINT "Opps, Screen height is not big enough for Y cells down."
  160.             ELSE
  161.                 RETURN
  162.             END IF
  163.         ELSE
  164.             PRINT "Opps, Screen width is not big enough for X cells across."
  165.         END IF
  166.     ELSE
  167.         PRINT "We did not get everything filled out by = signs."
  168.     END IF
  169.     PRINT: PRINT "Press any to continue.. "
  170.     SLEEP
  171.     SHELL fName$
  172.     GOTO loadCustom
  173.  
  174. SUB initialize ()
  175.     DIM minesPlaced, rx, ry, x, y, nMines, xoffset!
  176.     CLS
  177.     restart = 0
  178.     REDIM b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS boardType
  179.     minesPlaced = 0
  180.     WHILE minesPlaced < mines
  181.         rx = INT(RND * Xarrd) + 1: ry = INT(RND * Yarrd) + 1
  182.         IF b(rx, ry).mine = 0 THEN
  183.             b(rx, ry).mine = -1: minesPlaced = minesPlaced + 1
  184.         END IF
  185.     WEND
  186.     'count mines amoung the neighbors
  187.     FOR y = 1 TO Yarrd
  188.         IF y MOD 2 = 0 THEN xoffset! = .5 * xspacing! ELSE xoffset! = 0
  189.         FOR x = 1 TO Xarrd
  190.             IF b(x, y).mine <> -1 THEN 'not already a mine
  191.                 '2 sets of neighbors depending if x offset or not
  192.                 IF xoffset! > .1 THEN
  193.                     nMines = b(x - 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  194.                     nMines = nMines + b(x + 1, y - 1).mine + b(x + 1, y).mine + b(x + 1, y + 1).mine
  195.                 ELSE
  196.                     nMines = b(x + 1, y).mine + b(x, y - 1).mine + b(x, y + 1).mine
  197.                     nMines = nMines + b(x - 1, y - 1).mine + b(x - 1, y).mine + b(x - 1, y + 1).mine
  198.                 END IF
  199.                 b(x, y).id = -nMines
  200.             ELSE
  201.                 b(x, y).id = 0
  202.             END IF
  203.             b(x, y).x = x * xspacing! + xoffset! + .5 * xspacing!
  204.             b(x, y).y = y * yspacing! + .5 * yspacing!
  205.             b(x, y).reveal = 0
  206.             showCell x, y
  207.         NEXT
  208.     NEXT
  209.  
  210. SUB showCell (c, r)
  211.     DIM da, x!, y!, lastx!, lasty!, clr AS _UNSIGNED LONG
  212.     SELECT CASE b(c, r).reveal
  213.         CASE -1: IF b(c, r).mine THEN clr = &HFF883300 ELSE clr = &HFFFFFFFF 'revealed  white with number of mine neighbors
  214.         CASE 0: clr = &HFF008800 'hidden green
  215.         CASE 1: clr = &HFFFF0000 'marked red
  216.     END SELECT
  217.     lastx! = b(c, r).x + cellR * COS(_D2R(-30))
  218.     lasty! = b(c, r).y + cellR * SIN(_D2R(-30))
  219.     FOR da = 30 TO 330 STEP 60
  220.         x! = b(c, r).x + cellR * COS(_D2R(da))
  221.         y! = b(c, r).y + cellR * SIN(_D2R(da))
  222.         LINE (lastx!, lasty!)-(x!, y!), &HFFFF00FF
  223.         lastx! = x!: lasty! = y!
  224.     NEXT
  225.     PAINT (b(c, r).x, b(c, r).y), clr, &HFFFF00FF
  226.     IF b(c, r).reveal = -1 THEN
  227.         'cText b(c, r).x, b(c, r).y, 15, &HFF000000, _TRIM$(STR$(c)) + "," + _TRIM$(STR$(r))
  228.         IF b(c, r).id > 0 THEN cText b(c, r).x, b(c, r).y, 35, &HFF000000, _TRIM$(STR$(b(c, r).id))
  229.         IF b(c, r).mine = -1 THEN cText b(c, r).x, b(c, r).y, 35, &HFFFFFFFF, "*"
  230.     END IF
  231.  
  232. FUNCTION TFwin
  233.     DIM c, x, y
  234.     FOR y = 1 TO Yarrd
  235.         FOR x = 1 TO Xarrd
  236.             IF b(x, y).reveal = -1 AND b(x, y).mine = 0 THEN c = c + 1
  237.         NEXT
  238.     NEXT
  239.     IF c = Xarrd * Yarrd - mines THEN TFwin = -1
  240.  
  241. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  242.     DIM m, mx, my, mb1, mb2, r, c
  243.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  244.     IF mb1 THEN mbNum = 1
  245.     IF mb2 THEN mbNum = 2
  246.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  247.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  248.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  249.             mx = _MOUSEX: my = _MOUSEY
  250.         WEND
  251.         FOR r = 1 TO Yarrd
  252.             FOR c = 1 TO Xarrd
  253.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xspacing! THEN
  254.                     returnCol = c: returnRow = r: EXIT SUB
  255.                 END IF
  256.             NEXT
  257.         NEXT
  258.         mbNum = 0 'still here then clicked wrong
  259.     END IF
  260.  
  261. SUB sweepZeros (col, row) ' recursive sweep with Rod's limits set
  262.     DIM c, r, cMin, cMax, rMin, rMax, x, y, id
  263.     c = col: r = row 'get copies for recursive sub
  264.     IF c > 2 THEN cMin = c - 1 ELSE cMin = 1
  265.     IF c < Xarrd - 1 THEN cMax = c + 1 ELSE cMax = Xarrd
  266.     IF r > 2 THEN rMin = r - 1 ELSE rMin = 1
  267.     IF r < Yarrd - 1 THEN rMax = r + 1 ELSE rMax = Yarrd
  268.     FOR y = rMin TO rMax
  269.         FOR x = cMin TO cMax
  270.             IF b(x, y).reveal = 0 THEN
  271.                 id = b(x, y).id
  272.                 IF b(x, y).mine = 0 AND id = 0 THEN
  273.                     b(x, y).reveal = -1 'mark played
  274.                     showCell x, y
  275.                     sweepZeros x, y
  276.                 ELSE
  277.                     IF b(x, y).mine = 0 AND id >= 1 AND id <= 8 THEN
  278.                         b(x, y).reveal = -1
  279.                         showCell x, y
  280.                     END IF
  281.                 END IF
  282.             END IF
  283.         NEXT
  284.     NEXT
  285.  
  286. 'center the text around (x, y) point, needs a graphics screen!
  287. SUB cText (x, y, textHeight AS SINGLE, K AS _UNSIGNED LONG, txt$)
  288.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult!, xlen
  289.     fg = _DEFAULTCOLOR
  290.     'screen snapshot
  291.     cur& = _DEST
  292.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  293.     _DEST I&
  294.     COLOR K, _RGBA32(0, 0, 0, 0)
  295.     _PRINTSTRING (0, 0), txt$
  296.     mult! = textHeight / 16
  297.     xlen = LEN(txt$) * 8 * mult!
  298.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  299.     COLOR fg
  300.     _FREEIMAGE I&
  301.  
  302. FUNCTION rightOf$ (source$, of$)
  303.     IF INSTR(source$, of$) > 0 THEN rightOf$ = MID$(source$, INSTR(source$, of$) + LEN(of$))
  304.  
  305. FUNCTION getChar$ (fromStr$)
  306.     DIM OK AS INTEGER, k$
  307.     WHILE OK = 0
  308.         k$ = INKEY$
  309.         IF LEN(k$) THEN
  310.             IF INSTR(fromStr$, k$) <> 0 THEN OK = -1
  311.         END IF
  312.         _LIMIT 200
  313.     WEND
  314.     _KEYCLEAR
  315.     getChar$ = k$
  316.  

Anyone want sound effects? Didn't seem too popular with Minesweeper... I enjoy them immensely, they are funny!

BTW, which is more portable wav files or MP3 files?
SoundBible gave a choice of MP3 or wav, maybe I guessed wrong.


Title: Re: Quick Minesweeper
Post by: SMcNeill on August 08, 2019, 12:54:00 pm
I can’t get a single mp3 file to play for me with QB64.  .OGG seems to be the most “glitch-free” play format, in my experience.
Title: Re: Quick Minesweeper
Post by: bplus on August 08, 2019, 12:56:28 pm
Thanks Steve, guess I will have to shop around for .ogg's.

Not impressed with .wav quality from SoundBible, just getting what I paid for I guess.
Title: Re: Quick Minesweeper
Post by: pforpond on August 11, 2019, 06:13:14 am
This is a lot of fun! I think some sounds in there would be cool and maybe something like the smiley face fella off the Windows 9x Minesweeper :)
Title: Re: Quick Minesweeper
Post by: bplus on August 11, 2019, 08:49:24 am
This is a lot of fun! I think some sounds in there would be cool and maybe something like the smiley face fella off the Windows 9x Minesweeper :)

In reply #10 there is a zip file of regular Minesweeper with fun sound effects and field settings you can customize. For the smiley face, look in mirror when you play game! ;-))

I will try to find .ogg files for next set of sound effects.
Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 11, 2019, 12:41:21 pm
Fine Bplus
I find more easy to lay on Hexagonal base because more interactions more exclusions...

I like very much the look...

about sound see here for FREE .OGG or whatformatyouwantdownload
https://bigsoundbank.com/detail-0029-computer-mouse.html (https://bigsoundbank.com/detail-0029-computer-mouse.html)

about the game
is this showed here down  a feature or a bug?
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

thanks
Title: Re: Quick Minesweeper
Post by: bplus on August 11, 2019, 01:39:53 pm
Fine Bplus
I find more easy to lay on Hexagonal base because more interactions more exclusions...

I like very much the look...

about sound see here for FREE .OGG or whatformatyouwantdownload
https://bigsoundbank.com/detail-0029-computer-mouse.html (https://bigsoundbank.com/detail-0029-computer-mouse.html)

about the game
is this showed here down  a feature or a bug?
...

thanks

Thanks TempodiBasic, and I will check out your link.

You do not have to mark all the mines red to win a game of Minesweeper. The alternate name to this game is FreeCell or Free Cell? because you only have to reveal all the cells that are not mines. In fact, I challenge myself when I play games without marking a single mine. The marking of mines sort of sets a safety precaution, you can not accidentally left click a mine when it is marked and it is like leaving a note to yourself not to mess with that cell.
But the marks do toggle, so if you realize, "Oh that cell is OK.", you can switch off the marker and then left click on it to reveal the cell.
Title: Re: Quick Minesweeper
Post by: bplus on August 13, 2019, 10:30:04 pm
Here is Hexagon Minesweeper wSounds
.ogg files source
https://bigsoundbank.com/detail-0029-computer-mouse.html
and bomb #6: https://www.mediacollege.com/downloads/sound-effects/explosion/

Title: Re: Quick Minesweeper
Post by: SierraKen on August 13, 2019, 10:56:26 pm
LOL dang B+ that's tons better than what Microsoft made. lol Great job!
Title: Re: Quick Minesweeper
Post by: bplus on August 13, 2019, 11:05:48 pm
Thanks Ken, it can get pretty noisy if start clicking away at cells faster than the sounds finish playing. :)

BTW, Thanks to Steve McNeill who got me going on the Hexagon project with a challenge and TempodiBasic who gave me the link to public domain .ogg files.
Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 14, 2019, 07:07:42 am
Cool!
Yes I like sound, I like graphic, I like the possibility to customize...
and I have learned that is no need to erd mark mines to get victory.
Thanks to share
Title: Re: Quick Minesweeper
Post by: bplus on August 15, 2019, 11:45:54 am
Thanks TempodiBasic

To all who try out code,

I am curious if the custom field input is working in other OS?
 (I assume it works fine in any Windows). I would like feedback if it works or not for you.

I like using your editor to get a page full of information. IMO it beats creating a form in code or playing 20 questions with INPUT or designing pretty GUI interface. This code does create the form in code, but I could have just as easy included the txt form in the zip, still there is a bunch of code needed for checking. I am considering this method for more complex data entry form and would like other people's reactions or ideas about this.

Append: A good for instance, I was / am considering allowing user to add their own favorite sound files for the Minesweeper events:
Load new field: currently you hear ticking in Hexagon and 4 ships bells in regular Minesweeper
Sweep zero's: both are whoosh like
Reveal a mine: booms, if you have better... (that reminds me another effect I could install like Battleship when finish off a ship...)
Toggle marker: old camera like click
Reveal a cell not a mine or a Zero: in Hex it is a random selection of 28 .ogg sound effects, in regular minesweeper they are played if RND > .8 so it's not every reveal which makes the odd noises more startling, I think.


Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 15, 2019, 03:19:30 pm
Hi Bplus
here my feedback from into Lubuntu 16.04 in VirtualBox
  [ This attachment cannot be displayed inline in 'Print Page' view ]  
and for sounds I can affirm all right!
Title: Re: Quick Minesweeper
Post by: bplus on August 15, 2019, 04:11:24 pm
Hi TempodiBasic,

Thanks!

Option 2 at startup calls up your editor OK?

BTW the background of your Desktop looks like a slight mod of a like a program I wrote.
Title: Re: Quick Minesweeper
Post by: TempodiBasic on August 15, 2019, 05:43:18 pm
Hi Bplus
sorry I have forgotten that!
The answer is negative, no it doesn't start editor of minesweep but it starts a game with 36 cells hexagonal...
  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Quick Minesweeper
Post by: bplus on August 15, 2019, 07:33:04 pm
OK thanks TempodiBasic, I will put plans of using text editor on hold.




Title: Re: Quick Minesweeper
Post by: bplus on February 09, 2020, 01:05:14 pm
I have a new and improved Hexagonal Minesweeper. I was challenged to add particle explosion at SmallBASIC board at Syntax Bomb forum. After I did that, I realized I could have a much better effect with QB64.

Yep, very cool! I'd give screen shots but it would spoil the surprise, I think. So here is the entire new version with Crater Maker (ewh, I've been spelling Crater wrong.) The zip is mostly all .ogg files that's why it's so large.

PS the exe is for Windows 64; the txt file should work in any txt editor in case the customize section of code does not work in exe or your own compiled exe from bas source.

Title: Re: Quick Minesweeper
Post by: bplus on February 10, 2020, 01:42:48 pm
OK, OK I did a screenshot for Aurel on the other forum, here it is for here :)

 


If only I had 3D glasses ;-((

Of course this makes it hard to win a game, it is too much fun blowing up the field. ;-))
Title: Re: Quick Minesweeper
Post by: bplus on February 10, 2020, 05:02:08 pm
Couldn't help myself, I tweaked Crater Maker some more to scale to board size and closer fit to Bomb sound.

PS I played regular Minesweeper after some time away and Hexagonal is easier! For Hexagonal, it is a matter of just how fast you can clear the free cells.

Title: Re: Quick Minesweeper
Post by: Dimster on February 10, 2020, 05:09:30 pm
Cranked up the sound - ticking clock drives you crazy - explosion very impressive - thanks bplus - now have one of those "wake me ups" when coding long into the night.
Title: Re: Quick Minesweeper
Post by: bplus on February 10, 2020, 07:06:01 pm
Thanks Dimster, wake up or unwind by racing through a minefield with sound effects.
Title: Re: Quick Minesweeper
Post by: bplus on January 19, 2021, 12:54:44 pm
I have updated Hexagonal Minesweeper with Crater Maker with all Ogg files moved to separate folder.

This makes it easier for Windows users to access the main folder and setup a shortcut to the exe for say a Games Folder which I like to use. For Windows users this avoids Files Explorer having to list Ogg files and die.



Title: Re: Quick Minesweeper
Post by: SierraKen on January 19, 2021, 02:36:06 pm
Really fun game B+. I played a few times and won twice. Here is the picture of the last game. Thanks for the game!