Main Menu

Minesweeper

Started by programaths, January 26, 2021, 03:23:58 AM

Previous topic - Next topic

programaths

A simple minesweeper game.

The game allow to flag cells and has a win/loss condition.

It demonstrate a technique called recursion and how to use parallel arrays to implement the logic.

It's accompanied with a 3h long tutorial which is uncut and show also how I trouble shoot issues.
Specifically a variant of "off by one" classic error due to my misunderstanding of array bounds in Play Basic.
Indeed, in PB it's the upper bound and not the size that is given! So, declaring an array of size 3 is done using "DIM a(2)"!

PlayBASIC Code: [Select]
; PROJECT : Mines
; AUTHOR : Programaths
; CREATED : 1/26/2021
; ---------------------------------------------------------------------

blankTile = newImage(32,32)
renderToImage blankTile

ink $222222
box 0,0,31,31,0
ink $444444
box 1,1,30,30,0
ink $888888
box 2,2,29,29,0
ink $cccccc
box 3,3,28,28,1

openedTile = newImage(32,32)
renderToImage openedTile

ink $222222
box 0,0,31,31,0
ink $444444
box 1,1,30,30,0
ink $888888
box 2,2,29,29,0
ink $eeeeee
box 3,3,28,28,1

constant hiddenMines = 3
constant boardW = 6
constant boardH = 5

dim tiles(12)
dim mines(boardH-1,boardW-1)
dim counters(boardH-1,boardW-1)
dim userFlags(boardH-1,boardW-1)

tiles(0) = createTile(blankTile,"",0)

for n=1 to 8
tiles(n)=createTile(openedTile,str$(n),0)
next n

tiles(9) = createTile(blankTile,"!",$ff0000)
tiles(10) = createTile(blankTile,"?",$ffff00)

tiles(11) = openedTile

renderToScreen

nbMines = 0

while nbMines<hiddenMines
mineX = rnd(boardW-1)
mineY = rnd(boardH-1)
if not mines(mineY,mineX)
mines(mineY,mineX)=1
counters(mineY,mineX)=0
for r=-1 to 1
for c=-1 to 1
if c=0 and r=0 then continue
checkX = mineX+c
checkY = mineY+r
if not range(checkX,0,boardW-1) then continue
if not range(checkY,0,boardH-1) then continue
if mines(checkY,checkX) then continue
counters(checkY,checkX)+=1
next c
next r
nbMines++
endif
endWhile

do
for r=0 to boardH-1
for c=0 to boardW-1
if userFlags(r,c)
drawImage tiles(userFlags(r,c)+8),32*(c+1),32*(r+1),0
elseif not mines(r,c)
drawImage tiles(counters(r,c)),32*(c+1),32*(r+1),0
else
drawImage tiles(0),32*(c+1),32*(r+1),0
endif
next c
next r
sync
waitmouse 0,3

targetY = (mouseY()/32)-1
targetX = (mouseX()/32)-1

if not range(targetY,0,boardH-1) or not range(targetX,0,boardW-1)
FlushMouse
continue
endif

if rightMouseButton()
FlushMouse
if not counters(targetY,targetX)
userFlags(targetY,targetX)=mod(userFlags(targetY,targetX)+1,3)
endif
continue
endif

if leftMouseButton()
FlushMouse
if mines(targetY,targetX)
goto gameOver
elseif (not counters(targetY,targetX)) or userFlags(targetY,targetX)
revealMines(mines(),counters(),userFlags(),targetX,targetY,boardW,boardH)
endif
endif

nbUncoveredCells = 0
for i=0 to boardH-1
for j=0 to boardW-1
if counters(i,j) then inc nbUncoveredCells
next j
next i

if nbUncoveredCells = boardH*boardW - hiddenMines then goto win

loop

gameOver:
cls
ink $ff0000
print "You lose!"
sync
waitkey
end

win:
cls
ink $00ff00
print "Congratulation!"
sync
waitkey
end

function revealMines(mines(),counters(),userFlags(),x,y,bw,bh)
for r=-1 to 1
for c=-1 to 1
checkX = x+c
checkY = y+r
if not range(checkX,0,bw-1) then continue
if not range(checkY,0,bh-1) then continue
if counters(checkY,checkX) then continue
Login required to view complete source code


Small 3h tutorial:



stevmjon

you have been busy. i will check out the video soon. (my speakers are playing up at the moment. sound goes very low then louder. ordering new ones.)

this video is not on your youtube channel main page. is this because the video is marked as "unlisted" intentionally or by mistake?
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

programaths