
-----------------------------------
Johnny19931993
Wed Mar 18, 2009 4:43 pm

Need help for my minesweeper game
-----------------------------------
I am trying to make a minesweeper game but i got stuck and don't know what to do

My intention is to check the surrounding tiles for every tile that does not contain any mine
and put the number of mines around it in that tile
but when i execute it, only 1s appear in the tiles and some tiles don't even have a number in it even though it's beside a mine

Can anyone help me?

These are the codes so far


("graphics:240;240, title: Minesweeper, nobuttonbar, offscreenonly")
Mouse.ButtonChoose ("multibutton")
const LEN_X := 9
const LEN_Y := 9
var tile : array 1 .. LEN_X, 1 .. LEN_Y of string
var mine : int
var mine_counter := 0
var num : array 1 .. 8 of int
var reveal : array 1 .. LEN_X, 1 .. LEN_Y of boolean
var num_counter := 0
var mx, my, button := 0

for i : 1 .. 8
    Font.Draw (intstr (i), 0, 0, Font.New ("mono:12"), i)
    num (i) := Pic.New (0, 0, 12, 12)
    cls
end for

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        tile (i, j) := "b"
        reveal (i, j) := false
    end for
end for

loop
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            randint (mine, 1, 100)
            if mine = 1 and mine_counter not= 10 then
                if tile (i, j) = "b" then
                    tile (i, j) := "m"
                    mine_counter += 1
                end if
            end if
        end for
    end for
    exit when mine_counter = 10
end loop

proc up (i, j : int)
    if tile (i, j + 1) = "m" then
        num_counter += 1
    end if
end up

proc down (i, j : int)
    if tile (i, j - 1) = "m" then
        num_counter += 1
    end if
end down

proc left (i, j : int)
    if tile (i - 1, j) = "m" then
        num_counter += 1
    end if
end left

proc right (i, j : int)
    if tile (i + 1, j) = "m" then
        num_counter += 1
    end if
end right

proc up_left (i, j : int)
    if tile (i - 1, j + 1) = "m" then
        num_counter += 1
    end if
end up_left

proc up_right (i, j : int)
    if tile (i + 1, j + 1) = "m" then
        num_counter += 1
    end if
end up_right

proc down_left (i, j : int)
    if tile (i - 1, j - 1) = "m" then
        num_counter += 1
    end if
end down_left

proc down_right (i, j : int)
    if tile (i + 1, j - 1) = "m" then
        num_counter += 1
    end if
end down_right

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if tile (i, j) = "b" then
            if i = 1 and j = 1 then
                up (i, j)
                up_right (i, j)
                right (i, j)
            elsif j > 1 and j < LEN_Y and i = 1 then
                up (i, j)
                up_right (i, j)
                right (i, j)
                down_right (i, j)
                down (i, j)
            elsif i = 1 and j = LEN_Y then
                right (i, j)
                down_right (i, j)
                down (i, j)
            elsif i > 1 and i < LEN_X and j = LEN_Y then
                right (i, j)
                down_right (i, j)
                down (i, j)
                down_left (i, j)
                left (i, j)
            elsif i = LEN_X and j = LEN_Y then
                down (i, j)
                down_left (i, j)
                left (i, j)
            elsif i = LEN_X and j > 1 and j < LEN_Y then
                down (i, j)
                down_left (i, j)
                left (i, j)
                up_left (i, j)
                up (i, j)

            elsif i = LEN_X and j = 1 then
                left (i, j)
                up_left (i, j)
                up (i, j)
            elsif i > 1 and i < LEN_X and j = 1 then
                right (i, j)
                left (i, j)
                up_left (i, j)
                up (i, j)
                up_right (i, j)
            else
                up (i, j)
                up_right (i, j)
                right (i, j)
                down_right (i, j)
                down (i, j)
                down_left (i, j)
                left (i, j)
                up_left (i, j)
            end if
            if num_counter > 1 then
                tile (i, j) := "n" + intstr (mine_counter)
            end if
            num_counter := 0
        end if
    end for
end for

proc back
    for i : 0 .. 160 by 20
        for j : 0 .. 160 by 20
            drawbox (i + 30, j + 30, i + 50, j + 50, black)
            if not reveal (i div 20 + 1, j div 20 + 1) then
                drawfill (i + 40, j + 40, grey, black)
            end if
        end for
    end for
end back
back

proc revealing
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            if reveal (i, j) and tile (i, j) = "m" then
                drawfilloval (((i - 1) * 20) + 40, ((j - 1) * 20) + 40, 5, 5, black)
            elsif reveal (i, j) and tile (i, j) = "b" then 
                drawfill (((i - 1) * 20) + 40, ((j - 1) * 20) + 40, white, black)
            elsif reveal (i, j) and tile (i, j) (1) = "n" then
                Pic.Draw (num (strint (tile (i, j) (2))), ((i - 1) * 20) + 35, ((j - 1) * 20) + 35, picMerge)
            end if
        end for
    end for
end revealing



proc input
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            if mx >= ((i - 1) * 20) + 30 and mx < ((i - 1) * 20) + 50 and my >= ((j - 1) * 20) + 30 and my < ((j - 1) * 20) + 50 and button = 1 then
                reveal (i, j) := true
            end if
        end for
    end for
end input

loop
    Mouse.Where (mx, my, button)
    back
    input
    revealing
    View.Update
    cls
end loop


-----------------------------------
DemonWasp
Wed Mar 18, 2009 6:06 pm

RE:Need help for my minesweeper game
-----------------------------------
Think about how you would do this on pencil and paper. Get some graph paper, place some mines on it, and solve the problem manually. Either use that as the inspiration for how to solve the problem algorithmically, or tell us what you came up with, and we'll help you.

-----------------------------------
TheFerret
Wed Mar 18, 2009 6:14 pm

RE:Need help for my minesweeper game
-----------------------------------
Something that will help with this problem is recursion...

-----------------------------------
The_Bean
Wed Mar 18, 2009 6:36 pm

Re: Need help for my minesweeper game
-----------------------------------
He actually has it working somehow in that mess of stuff, he just messed up 2 simple things.


            if num_counter > 1 then 
                tile (i, j) := "n" + intstr (mine_counter) 

Should be

            if num_counter >= 1 then 
                tile (i, j) := "n" + intstr (num_counter) 


There is a much shorter and simpler way though.

-----------------------------------
Johnny19931993
Wed Mar 18, 2009 7:26 pm

Re: Need help for my minesweeper game
-----------------------------------

There is a much shorter and simpler way though.

really?! Can you teach me? Cuz this program I made confused myself

-----------------------------------
DemonWasp
Thu Mar 19, 2009 12:38 am

RE:Need help for my minesweeper game
-----------------------------------
You already know the locations of all of the mines (either because you've got them marked in a grid, or because you've got a list of all their locations). For each mine, just add 1 to all of the counters in the 8 neighbouring squares.

I'm confused as to how one would use recursion to solve this though - seems like a lot of effort for what amounts to a for-loop or two.

-----------------------------------
Johnny19931993
Thu Mar 19, 2009 6:46 pm

Re: Need help for my minesweeper game
-----------------------------------
I took your advice and modified part of the program that calculate the number on the tile into this


for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if tile (i, j) = "m" then
            if j + 1 < LEN_Y then
                if tile (i, j + 1) not= "m" then
                    num_counter (i, j + 1) += 1
                end if
            end if
            if i + 1 < LEN_X and j + 1 < LEN_Y then
                if tile (i + 1, j + 1) not= "m" then
                    num_counter (i + 1, j + 1) += 1
                end if
            end if
            if i + 1 < LEN_X then
                if tile (i + 1, j) not= "m" then
                    num_counter (i + 1, j) += 1
                end if
            end if
            if i + 1 < LEN_X and j - 1 > 0 then
                if tile (i + 1, j - 1) not= "m" then
                    num_counter (i + 1, j - 1) += 1
                end if
                if j - 1 > 0 then
                    if tile (i, j - 1) not= "m" then
                        num_counter (i, j - 1) += 1
                    end if
                end if
                if j + 1 < LEN_Y then
                    if tile (i, j + 1) not= "m" then
                        num_counter (i, j + 1) += 1
                    end if
                end if
                if i - 1 > 0 and j - 1 > 0 then
                    if tile (i - 1, j - 1) not= "m" then
                        num_counter (i - 1, j - 1) += 1
                    end if
                end if
                if i - 1 > 0 then
                    if tile (i - 1, j) not= "m" then
                        num_counter (i - 1, j) += 1
                    end if
                end if
                if i - 1 > 0 and j + 1 < LEN_Y then
                    if tile (i - 1, j + 1) not= "m" then
                        num_counter (i - 1, j + 1) += 1
                    end if
                end if
            end if
        end if
    end for
end for

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if num_counter (i, j) > 0 then
            tile (i, j) := "n" + intstr (num_counter (i, j))
        end if
    end for
end for


Instead of adding the number from the blank tiles, I changed it so it adds the number from the mine tiles
But something's still wrong...
Some tiles that are suppose to have a number in it apparently don't have a number

This is an example : 

http://i267.photobucket.com/albums/ii317/johnny19931993/Minesweeper_error.jpg

The 4 that i circle should be a 3
And the other circles are tiles that are suppose to have a number in it

-----------------------------------
DemonWasp
Fri Mar 20, 2009 1:05 am

RE:Need help for my minesweeper game
-----------------------------------
It looks to me like you have a misplaced end-if (based on the intenting). Press F2 to indent properly and check that it looks like you expected.

-----------------------------------
Johnny19931993
Fri Mar 20, 2009 2:50 pm

Re: Need help for my minesweeper game
-----------------------------------
Some numbers are still wrong though....

http://i267.photobucket.com/albums/ii317/johnny19931993/Minesweeper_error_2.jpg

-----------------------------------
DemonWasp
Fri Mar 20, 2009 2:55 pm

RE:Need help for my minesweeper game
-----------------------------------
Can you post your code as it exists now? I tried assembling your new method with your existing code, but you've made substantial other edits.

-----------------------------------
Johnny19931993
Fri Mar 20, 2009 5:09 pm

Re: Need help for my minesweeper game
-----------------------------------
Yes of course


setscreen ("graphics:240;240, title: Minesweeper, nobuttonbar, offscreenonly")
Mouse.ButtonChoose ("multibutton")
const LEN_X := 9
const LEN_Y := 9
var tile : array 1 .. LEN_X, 1 .. LEN_Y of string
var mine : int
var mine_counter := 0
var num : array 1 .. 8 of int
var reveal : array 1 .. LEN_X, 1 .. LEN_Y of boolean
var num_counter : array 1 .. LEN_X, 1 .. LEN_Y of int
var mx, my, button := 0

for i : 1 .. 8
    Font.Draw (intstr (i), 0, 0, Font.New ("mono:12"), i)
    num (i) := Pic.New (0, 0, 12, 12)
    cls
end for

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        tile (i, j) := "b"
        reveal (i, j) := false
        num_counter (i, j) := 0
    end for
end for

loop
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            randint (mine, 1, 100)
            if mine = 1 and mine_counter not= 10 then
                if tile (i, j) = "b" then
                    tile (i, j) := "m"
                    mine_counter += 1
                end if
            end if
        end for
    end for
    exit when mine_counter = 10
end loop


for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if tile (i, j) = "m" then
            if j + 1 < LEN_Y then
                if tile (i, j + 1) not= "m" then
                    num_counter (i, j + 1) += 1
                end if
            end if
            if i + 1 < LEN_X and j + 1 < LEN_Y then
                if tile (i + 1, j + 1) not= "m" then
                    num_counter (i + 1, j + 1) += 1
                end if
            end if
            if i + 1 < LEN_X then
                if tile (i + 1, j) not= "m" then
                    num_counter (i + 1, j) += 1
                end if
            end if
            if i + 1 < LEN_X and j - 1 > 0 then
                if tile (i + 1, j - 1) not= "m" then
                    num_counter (i + 1, j - 1) += 1
                end if
            end if
            if j - 1 > 0 then
                if tile (i, j - 1) not= "m" then
                    num_counter (i, j - 1) += 1
                end if
            end if
            if j + 1 < LEN_Y then
                if tile (i, j + 1) not= "m" then
                    num_counter (i, j + 1) += 1
                end if
            end if
            if i - 1 > 0 and j - 1 > 0 then
                if tile (i - 1, j - 1) not= "m" then
                    num_counter (i - 1, j - 1) += 1
                end if
            end if
            if i - 1 > 0 then
                if tile (i - 1, j) not= "m" then
                    num_counter (i - 1, j) += 1
                end if
            end if
            if i - 1 > 0 and j + 1 < LEN_Y then
                if tile (i - 1, j + 1) not= "m" then
                    num_counter (i - 1, j + 1) += 1
                end if
            end if
        end if
    end for
end for

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if num_counter (i, j) > 0 then
            tile (i, j) := "n" + intstr (num_counter (i, j))
        end if
    end for
end for

proc back
    for i : 0 .. (LEN_X - 1) * 20 by 20
        for j : 0 .. (LEN_Y - 1) * 20 by 20
            drawbox (i + 30, j + 30, i + 50, j + 50, black)
            if not reveal (i div 20 + 1, j div 20 + 1) then
                drawfill (i + 40, j + 40, grey, black)
            end if
        end for
    end for
end back
back

proc revealing
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            if reveal (i, j) and tile (i, j) = "m" then
                drawfilloval (((i - 1) * 20) + 40, ((j - 1) * 20) + 40, 5, 5, black)
            elsif reveal (i, j) and tile (i, j) = "b" then
                drawfill (((i - 1) * 20) + 40, ((j - 1) * 20) + 40, white, black)
            elsif reveal (i, j) and tile (i, j) (1) = "n" then
                Pic.Draw (num (strint (tile (i, j) (2))), ((i - 1) * 20) + 35, ((j - 1) * 20) + 35, picMerge)
            end if
        end for
    end for
end revealing



proc input
    for i : 1 .. LEN_X
        for j : 1 .. LEN_Y
            if mx >= ((i - 1) * 20) + 30 and mx < ((i - 1) * 20) + 50 and my >= ((j - 1) * 20) + 30 and my < ((j - 1) * 20) + 50 and button = 1 then
                reveal (i, j) := true
            end if
        end for
    end for
end input

loop
    Mouse.Where (mx, my, button)
    back
    input
    revealing
    View.Update
    cls
end loop


-----------------------------------
copthesaint
Sat Mar 21, 2009 8:25 am

RE:Need help for my minesweeper game
-----------------------------------
I haven't really tried to slove this problem but I know if you were to redo your program, you may solve the problem. The problem I think is just in your math somewhere. So redoing the program may eliminate the problem. Don't just copy and paste if you do redo it because that won't solve any problems. Also it would be good to redo your program now while you only have  150 lines.

-----------------------------------
copthesaint
Sat Mar 21, 2009 8:42 am

Re: Need help for my minesweeper game
-----------------------------------
Hmm I think I found your problem... 

Look at this.

for i : 1 .. LEN_X
    for j : 1 .. LEN_Y
        if tile (i, j) = "m" then               /*1 If condition */
            if j + 1  0 then                      /*7 If condition */
                if tile (i - 1, j - 1) not= "m" then
                    num_counter (i - 1, j - 1) += 1
                end if
            end if
            if i - 1 > 0 then                   /*8 If condition */
                if tile (i - 1, j) not= "m" then
                    num_counter (i - 1, j) += 1
                end if
            end if
            if i - 1 > 0 and j + 1 