Posted: Wed Jul 25, 2007 11:26 pm Post subject: Minesweeper help
I have a working minesweeper game except for the one feature that is in the windows version. You know when you click a place that has empty spaces all around it shows all the empty places around it. How do I do that, I have researched pathfinding algorithms and have been thinking about ways to modify them. Any source is greatly appreciated.
Sponsor Sponsor
Saad
Posted: Thu Jul 26, 2007 2:53 am Post subject: RE:Minesweeper help
It isnt pathfinding. The algorithm is that for the current cell, if the number of mines around it is not 0 then halt and show the current block, If the value of the current block is > 0 then show the current cell, and for every cell around it call the same algorithm.
McKenzie
Posted: Thu Jul 26, 2007 7:16 am Post subject: Re: Minesweeper help
Try looking at the "flood-fill" algorithm, it is a very similar problem.
cavetroll
Posted: Thu Jul 26, 2007 11:38 am Post subject: Re: Minesweeper help
Thanks for the quick responses, and yes you were right I wasn't looking for pathfinding but I didn't know the proper term for what I was looking for. I looked up flood-fill algorithms and found how to do it. Again thanks for the response.
cavetroll
Posted: Thu Jul 26, 2007 12:17 pm Post subject: Re: Minesweeper help
Sorry I thought I had it but now I can't get the code to work, I am not sure why I tried to do it using recursion(http://en.wikipedia.org/wiki/Flood_fill) based on the first pseudo-code example. Here is the code,
code:
proc floodfill (nodex : int, nodey : int)
if squares (nodex, nodey, typ) not= 2 then
return
else
squares (nodex, nodey, state) := 2
for decreasing i : 1 .. -1
for ii : -1 .. 1
if nodex - i > 0 and nodex - i < 19 and nodey - ii > 0 and nodey - ii < 19 then
if i not= 0 and ii not= 0 then
floodfill (nodex - i, nodey - ii)
end if
end if
end for
end for
return
end if
end floodfill
but it isn't working. Any Ideas?
Aziz
Posted: Thu Jul 26, 2007 12:23 pm Post subject: RE:Minesweeper help
There's a recursive and iterative method. I can post more help later on, when I'm not so swamped at work.
Saad
Posted: Thu Jul 26, 2007 5:21 pm Post subject: RE:Minesweeper help
Cant diagnose based on the code you have, What error are you getting?
cavetroll
Posted: Thu Jul 26, 2007 7:08 pm Post subject: Re: Minesweeper help
No error messages the code just doesn't do what it is intended to do. Have you read the earlier posts? They explain what the code is supposed to do but it doesn't work. I am just trying to figure out where it went wrong.
Sponsor Sponsor
CodeMonkey2000
Posted: Thu Jul 26, 2007 8:35 pm Post subject: RE:Minesweeper help
How have you implemented your minesweeper game?
cavetroll
Posted: Fri Jul 27, 2007 12:34 am Post subject: Re: Minesweeper help
I can post the code if you want but it is very messy right now so I'd rather not, but basically I have an array(squares(1..18,1..18,1..3)) which stores the data(count, type, state) for every square. When the square is click the state value is changed to 2 if it is left-clicked and 3 if it is right-clicked. Then I draw accordingly. The code given is what I want to run if the square clicked has a count of 0. Post if this doesn't help.
Saad
Posted: Fri Jul 27, 2007 4:05 am Post subject: RE:Minesweeper help
That alogorithm seems right, only problem I can see is that every square will have set to 2. Since it only checks if that square is 2 because of this all squares will end up as 2.
You want to check the amount of mines around the current cell aswell. If its not= 0 then return
Aziz
Posted: Fri Jul 27, 2007 7:50 am Post subject: RE:Minesweeper help
I can see a major problem in your logic.
Why does your array have three dimensions? Array indices should represent position, not value. Then value is store in a position of an array. So it does not make sense to have a 3D array for Minesweeper. If a user clicks a square, it changes the state, which changes the position, not the value.
What you should do is have a 2D array to store the state. I'm assume the array values already hold whether the square holds a mine or not? So squares(x,y,s) is 0 for mine, 1 for clear?
There's to approaches you could make. Both involved store both the state and the mine/not-mine data in the array (actually, you COULD have parallel arrays, but I'm not even going to bring it up to do horribleness)
1:
The value store at a position (x,y) in the array would be an integer. 1,2,3 would be the state. a negative would represent a mine
So a state of 1 would be (I'm assuming) a non-clicked square the is empty. A square with state of -1 would be a non-clicked square that contains a mine.
2: Better, IMO
Declare a type like so:
code:
type block
record of
state : int
mine : boolean
end record
(at least i think thats the right syntax)
and have an array to store the blocks:
code:
var squares : array 1 .. 10, 1 .. 10 of block
for x : 1 .. 10
for y : 1 .. 10
squares(x,y).state = 1
squares(x,y).mine = false
end for
end for
cavetroll
Posted: Fri Jul 27, 2007 1:54 pm Post subject: Re: Minesweeper help
I think you misinterpreted what I said, if not I misinterpreted your message. I have 3 dimensions because the first 2 hold the x and y position on the grid. the second one stores state(whether it has been left or right clicked), count(how many mines are around this square), and type(whether it is a mine(1) or non-mine square(2)). These are accessed using the constants state, count, and typ. All squares start with the state value of 1(2 is left clicked, 3 is right clicked). the count value is different for each square.
Aziz
Posted: Fri Jul 27, 2007 2:01 pm Post subject: RE:Minesweeper help
Could you post your source code?
An array's indices should only represent position.
Having an array with indices (x, y, state) represents squares in terms of x,y and state positions
each state (1,2,3) is a different value. The line squares (nodex, nodey, state) := 2 is "set the square at x position nodex, y position nodey, and state position state to 2. It does not mean set the state of square x,y to 2.
Its a bit confounding, so please post your source code and I can better understand it.
cavetroll
Posted: Fri Jul 27, 2007 2:46 pm Post subject: Re: Minesweeper help
K here's the code,
code:
buttonchoose ("multibutton")
setscreen ("graphics:max,max")
const typ : int := 1
const count : int := 2
const state : int := 3
var xback, xfor, yback, yfor : int := 0
var font : int := Font.New ("Arial:20")
var mines : int := 0
var squares : array 1 .. 18, 1 .. 18, 1 .. 3 of int
var x, y, bud, btn : int
proc floodfill (nodex : int, nodey : int)
if squares (nodex, nodey, typ) not= 2 then
return
else
squares (nodex, nodey, state) := 2
for decreasing i : 1 .. -1
for ii : -1 .. 1
if nodex - i > 0 and nodex - i < 19 and nodey - ii > 0 and nodey - ii < 19 then
if i not= 0 and ii not= 0 then
floodfill (nodex - i, nodey - ii)
end if
end if
end for
end for
return
end if
end floodfill
loop
mines := 0
for i : 1 .. 18
for ii : 1 .. 18
squares (i, ii, count) := 0
if mines = 75 then
squares (i, ii, typ) := 2
else
squares (i, ii, typ) := Rand.Int (1, 6)
if squares (i, ii, typ) > 1 then
squares (i, ii, typ) := 2
end if
end if
if squares (i, ii, typ) = 1 then
mines += 1
end if
squares (i, ii, state) := 1
end for
end for
exit when mines = 75
end loop
for i : 1 .. 18
for ii : 1 .. 18
if squares (i, ii, typ) = 2 then
for t : -1 .. 1
for tt : -1 .. 1
if i + t > 0 and i + t < 19 and ii + tt > 0 and ii + tt < 19 then
if squares (i + t, ii + tt, typ) = 1 then
squares (i, ii, count) += 1
end if
if squares (i, ii, count) = 0 then
squares (i, ii, state) := 1
else
squares (i, ii, state) := 1
end if
end if
end for
end for
end if
end for
end for
loop
for i : 1 .. 18
for ii : 1 .. 18
drawfillbox (i * 25, ii * 25, i * 25 + 25, ii * 25 + 25, 29)
drawbox (i * 25, ii * 25, i * 25 + 25, ii * 25 + 25, 7)
if squares (i, ii, state) = 2 then
if squares (i, ii, typ) = 2 then
Font.Draw (intstr (squares (i, ii, count)), i * 25 + 5, ii * 25 + 2, font, 12)
else
drawfill (i * 25 + 5, ii * 25 + 5, 42, 7)
end if
end if
if squares (i, ii, state) = 3 then
drawfillbox (i * 25 + 5, ii * 25 + 5, i * 25 + 20, ii * 25 + 20, 42)
end if
end for
end for
buttonwait ("down", x, y, btn, bud)
if x >= 25 and x <= 18 * 25 + 25 and y >= 25 and y <= 18 * 25 + 25 and btn = 1 then
if squares (x div 25, y div 25, state) = 1 then
floodfill (x div 25, y div 25)
end if
end if
if x >= 25 and x <= 18 * 25 + 25 and y >= 25 and y <= 18 * 25 + 25 and btn = 3 then
if squares (x div 25, y div 25, state) = 1 then
squares (x div 25, y div 25, state) := 3
elsif squares (x div 25, y div 25, state) = 3 then
squares (x div 25, y div 25, state) := 1
end if
end if
end loop