Minesweeper example

New to FreeBASIC? Post your questions here.
Post Reply
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Minesweeper example

Post by Löwenherz »

Hello all I have found an old freebasic example but Iit doesn't Work properly anymore and Crashes after row and col inputs

I am Not very familiär anymore with freebasic so I am asking Here for little help

Something is Missing Help is very Welcome thanks :) loewenherz

Code: Select all

' kind of MineSweeper

screenres 640, 480, 32

const rows = 10
const cols = 10
dim board(rows, cols) as string
dim revealed(rows, cols) as integer

dim shared as integer mineCount = 15

sub initializeBoard()
    dim i As integer, j as integer
    Dim board(rows, cols) as string
    Dim revealed(rows, cols) as integer

    ' Clear the board
    for i = 0 to rows - 1
        for j = 0 to cols - 1
            board(i, j) = " "
            revealed(i, j) = 0
        next j
    next i
    ' Place mines
    dim row As Integer, col as integer
    dim placedMines as integer = 0
    do
        row = rnd * rows
        col = rnd * cols
        if board(row, col) <> "*" then
            board(row, col) = "*"
            placedMines += 1
        end if
    loop until placedMines = mineCount
end sub

sub printBoard()
    dim board(rows, cols) as string
    Dim revealed(rows, cols) as integer

    cls
    dim i As Integer, j as integer
    for i = 0 to rows - 1
        for j = 0 to cols - 1
            if revealed(i, j) = 1 then
                print board(i, j);
            else
                print ".";
            end if
        next j
        print
    next i
end sub

sub revealCell(row as integer, col as integer)
    dim board(rows, cols) as string
    Dim revealed(rows, cols) as integer

    If row < 0 or row >= rows or col < 0 or col >= cols then return
    if revealed(row, col) = 1 then return
    revealed(row, col) = 1
    if board(row, col) = "*" then
        print "Game over! You hit a mine."
        end
    else
        dim i As integer, j As integer
        dim mineCount as integer = 0
        for i = row - 1 to row + 1
            for j = col - 1 to col + 1
                if i >= 0 and i < rows and j >= 0 and j < cols then
                    if board(i, j) = "*" then
                        mineCount += 1
                    end if
                end if
            next j
        next i
        board(row, col) = str(mineCount)
        if mineCount = 0 then
            ' recursively reveal adjacent cells if there are no adjacent mines
            revealCell(row - 1, col - 1)
            revealCell(row - 1, col)
            revealCell(row - 1, col + 1)
            revealCell(row, col - 1)
            revealCell(row, col + 1)
            revealCell(row + 1, col - 1)
            revealCell(row + 1, col)
            revealCell(row + 1, col + 1)
        end if
    end if
end sub

sub gamemain()
    dim board(rows, cols) as string
    Dim revealed(rows, cols) as integer

    initializeBoard()
    printBoard()

    dim row As integer, col as integer
    do
        print "Enter row (0-9): "
        input row
        print "Enter col (0-9): "
        input col
        revealCell(row, col)
        printBoard()
    Loop
    
    'PRINT "push a key to continue"
    'Sleep
    'Print "you have pressed "; INKEY ; " key: "
    'Print "wait a second"
    'Sleep 1000

end sub

gamemain()
fxm
Moderator
Posts: 12133
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Minesweeper example

Post by fxm »

- The 2 arrays 'board()' and 'revealed()' must be declared global (do not re declare them locally at the level of each procedure).
- Added a 'sleep' before 'end', to maintain persistence of the message "Game over! You hit a mine.".

Code: Select all

' kind of MineSweeper

screenres 640, 480, 32

const rows = 10
const cols = 10
dim shared board(rows, cols) as string
dim shared revealed(rows, cols) as integer

dim shared as integer mineCount = 15

sub initializeBoard()
    dim i As integer, j as integer

    ' Clear the board
    for i = 0 to rows - 1
        for j = 0 to cols - 1
            board(i, j) = " "
            revealed(i, j) = 0
        next j
    next i
    ' Place mines
    dim row As Integer, col as integer
    dim placedMines as integer = 0
    do
        row = rnd * rows
        col = rnd * cols
        if board(row, col) <> "*" then
            board(row, col) = "*"
            placedMines += 1
        end if
    loop until placedMines = mineCount
end sub

sub printBoard()
    cls
    dim i As Integer, j as integer
    for i = 0 to rows - 1
        for j = 0 to cols - 1
            if revealed(i, j) = 1 then
                print board(i, j);
            else
                print ".";
            end if
        next j
        print
    next i
end sub

sub revealCell(row as integer, col as integer)
    If row < 0 or row >= rows or col < 0 or col >= cols then return
    if revealed(row, col) = 1 then return
    revealed(row, col) = 1
    if board(row, col) = "*" then
        print "Game over! You hit a mine."
        sleep
        end
    else
        dim i As integer, j As integer
        dim mineCount as integer = 0
        for i = row - 1 to row + 1
            for j = col - 1 to col + 1
                if i >= 0 and i < rows and j >= 0 and j < cols then
                    if board(i, j) = "*" then
                        mineCount += 1
                    end if
                end if
            next j
        next i
        board(row, col) = str(mineCount)
        if mineCount = 0 then
            ' recursively reveal adjacent cells if there are no adjacent mines
            revealCell(row - 1, col - 1)
            revealCell(row - 1, col)
            revealCell(row - 1, col + 1)
            revealCell(row, col - 1)
            revealCell(row, col + 1)
            revealCell(row + 1, col - 1)
            revealCell(row + 1, col)
            revealCell(row + 1, col + 1)
        end if
    end if
end sub

sub gamemain()
    initializeBoard()
    printBoard()

    dim row As integer, col as integer
    do
        print "Enter row (0-9): "
        input row
        print "Enter col (0-9): "
        input col
        revealCell(row, col)
        printBoard()
    Loop
    
    'PRINT "push a key to continue"
    'Sleep
    'Print "you have pressed "; INKEY ; " key: "
    'Print "wait a second"
    'Sleep 1000

end sub

gamemain()
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Minesweeper example

Post by Löwenherz »

Many thanks fxm thats all running fine now :)

PS what sub is exactly responsible for this Matrix of 10x10 Points in a shape of a rectangle when you start the Game? Some issues ago of my example produced only one straight Line of Points ;) thx
shadow008
Posts: 86
Joined: Nov 26, 2013 2:43

Re: Minesweeper example

Post by shadow008 »

Löwenherz wrote: Mar 12, 2024 22:31 PS what sub is exactly responsible for this Matrix of 10x10 Points in a shape of a rectangle when you start the Game? Some issues ago of my example produced only one straight Line of Points ;) thx
The sub responsible is printBoard()

Code: Select all

sub printBoard()
    cls
    dim i As Integer, j as integer
    for i = 0 to rows - 1
        for j = 0 to cols - 1
            if revealed(i, j) = 1 then
                print board(i, j); '***IMPORTANT: note the semicolon (;)
            else
                print "."; '***IMPORTANT: note the semicolon (;)
            end if
        next j
        print '***IMPORTANT***
    next i
end sub
It iterates over each row, then each column, and sequentially prints the contents of the board() array. It's important to note the empty "print" statement in each iteration of the "for i = 0 to rows - 1" loop. It's effectively "printing" a newline, moving the cursor to the next row. Perhaps your issue was forgetting this extra print?

Edit: Also important to note would be the semicolons after printing the "." or board contents. It foregoes the automatic addition of a newline in the print statement, allowing you to continue printing on the same row. Without the semicolons, you would just get a vertical line of "." on new game, as each element would be printed on a new line.
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Minesweeper example

Post by Löwenherz »


Without the semicolons, you would just get a vertical line of "." on new game, as each element would be printed on a new line.
Many thanks for explanation shadow008 .. indeed First of all I Had a vertical Line later the example runs but couldn't See the result when I have Met a Mine but now all is running Well thx :)
Post Reply