MineSweeper

sciwizeh 2 Tallied Votes 838 Views Share

I made this minesweeper game earlier this summer. It shows many things, including:
array use,
1D array to 2D array,
gridlayout,
changing the way a JButton works depending on mouse button used,
floodfill,
loops,
GUI.

slightly long, 382 lines, can probably be condensed.

There is one known bug that i cannot seem to fix: when a floodfill causes a win, and the OK button is clicked on the win dialog, it will automatically click a button on the new game, not a problem usually, but in games that are set to be large with a small amount of bombs, it can cause an infinite loop :( , if you see a fix please comment or PM me, thanks.

have fun.

import java.awt.* ;
import java.awt.event.* ;
import java.awt.geom.* ;
import javax.swing.* ;
import javax.swing.event.* ;
/**MineSweeper by SciWizEH*/
public class MineSweeper extends JFrame implements ActionListener ,
		MouseListener {
	int rows = 10 ;
	int cols = 10 ;
	int numMines = 10 ;
	GridLayout layout = new GridLayout ( rows , cols ) ;
	/*type[][] name = new type[rows][cols];
	 * type[x][y];
	 * is 1d
	 * type[] name = new type[rows*cols];
	 * type[(rows*y)+x];*/
	boolean [ ] mines = new boolean [ rows * cols ] ;
	boolean [ ] clickable = new boolean [ rows * cols ] ;
	boolean lost = false ;
	boolean won = false ;
	int [ ] numbers = new int [ rows * cols ] ;
	JButton [ ] buttons = new JButton [ rows * cols ] ;
	boolean [ ] clickdone = new boolean [ rows * cols ] ;
	JMenuItem newGameButton = new JMenuItem ( "new game" ) ;
	JMenuItem difficulty = new JMenuItem ( "options" ) ;
	JLabel mineLabel = new JLabel ( "mines: " + numMines + " marked: 0" ) ;
	JPanel p = new JPanel ( ) ;

	public MineSweeper ( ) {
		p.setLayout ( layout ) ;
		setupI ( ) ;
		for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
			p.add ( buttons [ i ] ) ;
		}
		JMenuBar mb = new JMenuBar ( ) ;
		JMenu m = new JMenu ( "file" ) ;
		newGameButton.addActionListener ( this ) ;
		m.add ( newGameButton ) ;
		difficulty.addActionListener ( this ) ;
		m.add ( difficulty ) ;
		mb.add ( m ) ;
		this.setJMenuBar ( mb ) ;
		this.add ( p ) ;
		this.add ( mineLabel , BorderLayout.SOUTH ) ;
		this.pack ( ) ;
		this.setVisible ( true ) ;
	}

	public void fillMines ( ) {
		int needed = numMines ;
		while ( needed > 0 ) {
			int x = ( int ) Math.floor ( Math.random ( ) * rows ) ;
			int y = ( int ) Math.floor ( Math.random ( ) * cols ) ;
			if ( ! mines [ ( rows * y ) + x ] ) {
				mines [ ( rows * y ) + x ] = true ;
				needed -- ;
			}
		}
	}

	public void fillNumbers ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				int cur = ( rows * y ) + x ;
				if ( mines [ cur ] ) {
					numbers [ cur ] = 0 ;
					continue ;
				}
				int temp = 0 ;
				boolean l = ( x - 1 ) >= 0 ;
				boolean r = ( x + 1 ) < rows ;
				boolean u = ( y - 1 ) >= 0 ;
				boolean d = ( y + 1 ) < cols ;
				int left = ( rows * ( y ) ) + ( x - 1 ) ;
				int right = ( rows * ( y ) ) + ( x + 1 ) ;
				int up = ( rows * ( y - 1 ) ) + ( x ) ;
				int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
				int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
				int down = ( rows * ( y + 1 ) ) + ( x ) ;
				int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
				int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;
				if ( u ) {
					if ( mines [ up ] ) {
						temp ++ ;
					}
					if ( l ) {
						if ( mines [ upleft ] ) {
							temp ++ ;
						}
					}
					if ( r ) {
						if ( mines [ upright ] ) {
							temp ++ ;
						}
					}
				}
				if ( d ) {
					if ( mines [ down ] ) {
						temp ++ ;
					}
					if ( l ) {
						if ( mines [ downleft ] ) {
							temp ++ ;
						}
					}
					if ( r ) {
						if ( mines [ downright ] ) {
							temp ++ ;
						}
					}
				}
				if ( l ) {
					if ( mines [ left ] ) {
						temp ++ ;
					}
				}
				if ( r ) {
					if ( mines [ right ] ) {
						temp ++ ;
					}
				}
				numbers [ cur ] = temp ;
			}
		}
	}

	public void setupI ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				mines [ ( rows * y ) + x ] = false ;
				clickdone [ ( rows * y ) + x ] = false ;
				clickable [ ( rows * y ) + x ] = true ;
				buttons [ ( rows * y ) + x ] = new JButton ( /*"" + ( x * y )*/) ;
				buttons [ ( rows * y ) + x ].setPreferredSize ( new Dimension (
						45 , 45 ) ) ;
				buttons [ ( rows * y ) + x ].addActionListener ( this ) ;
				buttons [ ( rows * y ) + x ].addMouseListener ( this ) ;
			}
		}
		fillMines ( ) ;
		fillNumbers ( ) ;
	}

	public void setupI2 ( ) {
		this.remove ( p ) ;
		p = new JPanel ( ) ;
		layout = new GridLayout ( rows , cols ) ;
		p.setLayout ( layout ) ;
		buttons = new JButton [ rows * cols ] ;
		mines = new boolean [ rows * cols ] ;
		clickdone = new boolean [ rows * cols ] ;
		clickable = new boolean [ rows * cols ] ;
		numbers = new int [ rows * cols ] ;
		setupI ( ) ;
		for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
			p.add ( buttons [ i ] ) ;
		}
		this.add ( p ) ;
		this.pack ( ) ;
		fillMines ( ) ;
		fillNumbers ( ) ;
	}

	public void setup ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				mines [ ( rows * y ) + x ] = false ;
				clickdone [ ( rows * y ) + x ] = false ;
				clickable [ ( rows * y ) + x ] = true ;
				buttons [ ( rows * y ) + x ].setEnabled ( true ) ;
				buttons [ ( rows * y ) + x ].setText ( "" ) ;
			}
		}
		fillMines ( ) ;
		fillNumbers ( ) ;
		lost = false ;
		mineLabel.setText ( "mines: " + numMines + " marked: 0" ) ;
	}

	public static void main ( String [ ] args ) {
		new MineSweeper ( ) ;
	}

	public void actionPerformed ( ActionEvent e ) {
		if ( e.getSource ( ) == difficulty ) {
			rows = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
					this , "Rows" , "Rows" , JOptionPane.PLAIN_MESSAGE , null ,
					null , 10 ) ) ;
			cols = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
					this , "Columns" , "Columns" , JOptionPane.PLAIN_MESSAGE ,
					null , null , 10 ) ) ;
			numMines = Integer.parseInt ( ( String ) JOptionPane
					.showInputDialog ( this , "Mines" , "Mines" ,
							JOptionPane.PLAIN_MESSAGE , null , null , 10 ) ) ;
			setupI2 ( ) ;
		}
		if ( ! won ) {
			for ( int x = 0 ; x < rows ; x ++ ) {
				for ( int y = 0 ; y < cols ; y ++ ) {
					if ( e.getSource ( ) == buttons [ ( rows * y ) + x ]
							&& ! won && clickable [ ( rows * y ) + x ] ) {
						doCheck ( x , y ) ;
						break ;
					}
				}
			}
		}
		if ( e.getSource ( ) == newGameButton ) {
			setup ( ) ;
			won = false ;
			return ;

		}
		checkWin ( ) ;
	}

	public void mouseEntered ( MouseEvent e ) {

	}

	public void mouseExited ( MouseEvent e ) {

	}

	public void mousePressed ( MouseEvent e ) {
		if ( e.getButton ( ) == 3 ) {
			int n = 0 ;
			for ( int x = 0 ; x < rows ; x ++ ) {
				for ( int y = 0 ; y < cols ; y ++ ) {
					if ( e.getSource ( ) == buttons [ ( rows * y ) + x ] ) {
						clickable [ ( rows * y ) + x ] = ! clickable [ ( rows * y )
								+ x ] ;
					}
					if ( ! clickdone [ ( rows * y ) + x ] ) {
						if ( ! clickable [ ( rows * y ) + x ] ) {
							buttons [ ( rows * y ) + x ].setText ( "X" ) ;
							n ++ ;
						} else {
							buttons [ ( rows * y ) + x ].setText ( "" ) ;
						}
						mineLabel.setText ( "mines: " + numMines + " marked: "
								+ n ) ;
					}
				}
			}
		}
	}

	public void mouseReleased ( MouseEvent e ) {

	}

	public void mouseClicked ( MouseEvent e ) {

	}

	public void doCheck ( int x , int y ) {
		int cur = ( rows * y ) + x ;
		boolean l = ( x - 1 ) >= 0 ;
		boolean r = ( x + 1 ) < rows ;
		boolean u = ( y - 1 ) >= 0 ;
		boolean d = ( y + 1 ) < cols ;
		int left = ( rows * ( y ) ) + ( x - 1 ) ;
		int right = ( rows * ( y ) ) + ( x + 1 ) ;
		int up = ( rows * ( y - 1 ) ) + ( x ) ;
		int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
		int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
		int down = ( rows * ( y + 1 ) ) + ( x ) ;
		int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
		int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

		clickdone [ cur ] = true ;
		buttons [ cur ].setEnabled ( false ) ;
		if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && ! won ) {
			if ( u && ! won ) {
				if ( ! clickdone [ up ] && ! mines [ up ] ) {
					clickdone [ up ] = true ;
					buttons [ up ].doClick ( ) ;
				}
				if ( l && ! won ) {
					if ( ! clickdone [ upleft ] && numbers [ upleft ] != 0
							&& ! mines [ upleft ] ) {
						clickdone [ upleft ] = true ;
						buttons [ upleft ].doClick ( ) ;
					}
				}
				if ( r && ! won ) {
					if ( ! clickdone [ upright ] && numbers [ upright ] != 0
							&& ! mines [ upright ] ) {
						clickdone [ upright ] = true ;
						buttons [ upright ].doClick ( ) ;
					}
				}
			}
			if ( d && ! won ) {
				if ( ! clickdone [ down ] && ! mines [ down ] ) {
					clickdone [ down ] = true ;
					buttons [ down ].doClick ( ) ;
				}
				if ( l && ! won ) {
					if ( ! clickdone [ downleft ] && numbers [ downleft ] != 0
							&& ! mines [ downleft ] ) {
						clickdone [ downleft ] = true ;
						buttons [ downleft ].doClick ( ) ;
					}
				}
				if ( r && ! won ) {
					if ( ! clickdone [ downright ]
							&& numbers [ downright ] != 0
							&& ! mines [ downright ] ) {
						clickdone [ downright ] = true ;
						buttons [ downright ].doClick ( ) ;
					}
				}
			}
			if ( l && ! won ) {
				if ( ! clickdone [ left ] && ! mines [ left ] ) {
					clickdone [ left ] = true ;
					buttons [ left ].doClick ( ) ;
				}
			}
			if ( r && ! won ) {
				if ( ! clickdone [ right ] && ! mines [ right ] ) {
					clickdone [ right ] = true ;
					buttons [ right ].doClick ( ) ;
				}
			}
		} else {
			buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
			if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
				buttons [ cur ].setText ( "" ) ;
			}
		}
		if ( mines [ cur ] && ! won ) {
			buttons [ cur ].setText ( "0" ) ;
			doLose ( ) ;
		}
	}

	public void checkWin ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				int cur = ( rows * y ) + x ;
				if ( ! clickdone [ cur ] ) {
					if ( mines [ cur ] ) {
						continue ;
					} else {
						return ;
					}
				}
			}
		}

		doWin ( ) ;
	}

	public void doWin ( ) {
		if ( ! lost && ! won ) {
			won = true ;
			JOptionPane.showMessageDialog ( null ,
					"you win!\nstarting a new game" , "you lose" ,
					JOptionPane.INFORMATION_MESSAGE ) ;
			newGameButton.doClick ( ) ;
		}
	}

	public void doLose ( ) {
		if ( ! lost && ! won ) {
			lost = true ;
			for ( int i = 0 ; i < rows * cols ; i ++ ) {
				if ( ! clickdone [ i ] ) {
					buttons [ i ].doClick ( 0 ) ;
				}
			}
			JOptionPane.showMessageDialog ( null ,
					"you lose!\nstarting a new game" , "you lose" ,
					JOptionPane.ERROR_MESSAGE ) ;
			setup ( ) ;
		}
	}
}
Alex Edwards 321 Posting Shark

Whoo O_O! Pretty fun XD

I can't seem to win! Right when I think I will, I end up landing on a mine XD

=)

crow91 0 Newbie Poster

is this code running? I can't find a right code for ordinary minesweeper code in Joption!!! plz help me!!! this is my e-mail <EMAIL SNIPPED>, pls email me!!!

EhLy 0 Newbie Poster

how can I fix the errors of your minesweeper in the Jcreator 4.50 ??

sciwizeh 62 Posting Pro in Training

how can I fix the errors of your minesweeper in the Jcreator 4.50 ??

I never used JCreater, I wrote this without code completion in BlueJ, it should compile. what errors are you getting?

peter_budo 2,532 Code tags enforcer Team Colleague Featured Poster

There is no error on compile, it is running, so far didn't seen bug reported by you ;)

201katara 0 Newbie Poster

Uhmm okay SO I FOUND A BUG! I changed the setting of the game to:

ROWS: 10
COLUMNS: 10
MINES: 1
(for fun :P)
The first two times it worked!

After you play it like the 4th time, the game starts to play by itself. So even if I don't click a location, the game automatically picks one and reveals the answer and a JWindow pops up saying "you win" and when you click ok to the new game, it again starts to play by itself. (AGAIN I NEVER CLICKED A LOCATION!) I'm not sure if the code was programmed to do this...
One thing- when this happens on my mac, the tiles are differently colored. Previously the tiles would be grayish black when I click it and it reveals the empty spaces around it, however when the computer plays by itself: the tiles are a vanilla/ white pearlish color.

sciwizeh 62 Posting Pro in Training

Uhmm okay SO I FOUND A BUG! I changed the setting of the game to:

ROWS: 10
COLUMNS: 10
MINES: 1
(for fun :P)
The first two times it worked!

After you play it like the 4th time, the game starts to play by itself. So even if I don't click a location, the game automatically picks one and reveals the answer and a JWindow pops up saying "you win" and when you click ok to the new game, it again starts to play by itself. (AGAIN I NEVER CLICKED A LOCATION!) I'm not sure if the code was programmed to do this...
One thing- when this happens on my mac, the tiles are differently colored. Previously the tiles would be grayish black when I click it and it reveals the empty spaces around it, however when the computer plays by itself: the tiles are a vanilla/ white pearlish color.

this is a known issue, see the OP, last paragraph describes the exact issue your having, I have been unable to find a fix

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

It seems dangerous to have both an action listener and a mouse listener for the same button(s). I don't think there is any guarantee about the order in which these two listeners will be called, especially if there's a lot going on. Maybe the bug is caused by the action listener being executed before the mousePressed ???

sciwizeh 62 Posting Pro in Training

That may be true. But I dont believe the mouse listener code would interfere with the action listener code. Worth testing I suppose.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

May explain why a cell gets clicked after the action listener starts a new game?

sciwizeh 62 Posting Pro in Training

within the action listener doClick() is called on a number of other buttons, in a basic implementation of recursive floodfill.
the problem is that one of the doClick's happens after the win dialog is shown, and new game started, it's a bug in the action listener itself I believe, but I couldn't decide how to floodfill without using doClick() to prevent the problem.
the mouseListener only does something if it's a right click, where an action listener on a button is strictly left click (as far as I'm aware). So they should not be interacting.

melindanoel17 0 Newbie Poster
 int temp = 0 ;
            boolean l = ( x - 1 ) >= 0 ;
            boolean r = ( x + 1 ) < rows ;
            boolean u = ( y - 1 ) >= 0 ;
            boolean d = ( y + 1 ) < cols ;
            int left = ( rows * ( y ) ) + ( x - 1 ) ;
            int right = ( rows * ( y ) ) + ( x + 1 ) ;
            int up = ( rows * ( y - 1 ) ) + ( x ) ;
            int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
            int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
            int down = ( rows * ( y + 1 ) ) + ( x ) ;
            int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
            int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

            what does this code above do>?
NormR1 563 Posting Sage Team Colleague

Defines 13 variables and assigns them values.

sciwizeh 62 Posting Pro in Training

Defines 13 variables and assigns them values.

To be more specific it gets the indices of the buttons to the direction of the current button, the index of a button is it's y coordinate multiplied by rows plus the x (this is actually a misnmer it should be multiplied by the columns but I wasn't thinking when i initially wrote the code)

melindanoel17 0 Newbie Poster
if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && 
        ! won ) {
            if ( u && ! won ) {
                if ( ! clickdone [ up ] && ! mines [ up ] ) {
                    clickdone [ up ] = true ;
                    buttons [ up ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ upleft ] && numbers [ upleft 
                    ] != 0
                    && ! mines [ upleft ] ) {
                        clickdone [ upleft ] = true ;
                        buttons [ upleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ upright ] && numbers [ 
                        upright ] != 0
                    && ! mines [ upright ] ) {
                        clickdone [ upright ] = true ;
                        buttons [ upright ].doClick ( ) ;
                    }
                }
            }
            if ( d && ! won ) {
                if ( ! clickdone [ down ] && ! mines [ down ] ) {
                    clickdone [ down ] = true ;
                    buttons [ down ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ downleft ] && numbers 
                    [ downleft ] != 0
                    && ! mines [ downleft ] ) {
                        clickdone [ downleft ] = true ;
                        buttons [ downleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ downright ]
                    && numbers [ downright ] != 0
                    && ! mines [ downright ] ) {
                        clickdone [ downright ] = true ;
                        buttons [ downright ].doClick ( ) ;
                    }
                }
            }
            if ( l && ! won ) {
                if ( ! clickdone [ left ] && ! mines [ left ] ) {
                    clickdone [ left ] = true ;
                    buttons [ left ].doClick ( ) ;
                }
            }
            if ( r && ! won ) {
                if ( ! clickdone [ right ] && ! mines [ right ] ) {
                    clickdone [ right ] = true ;
                    buttons [ right ].doClick ( ) ;
                }
            }
        } else {
            buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
            if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
                buttons [ cur ].setText ( "" ) ;
            }
        }
        if ( mines [ cur ] && ! won ) {
            buttons [ cur ].setText ( "0" ) ;
            Lose ( ) ;
        }
    }


all thats confusing whaT DOES IT DO
melindanoel17 0 Newbie Poster

how can i somehow add a timer for this game?

sciwizeh 62 Posting Pro in Training

Adding a timer would require a new thread a new label, and an addition to the win/loose conditions.

The code you quoted above is the code that checks what the box the user clicked on, and if it's a 0 number it clicks the squares around that box in a recursive way, leading to a filling algorithm.

melindanoel17 0 Newbie Poster

how and where do you "thread a new label"?

sorry for all the questions this game is jst so cool!

sciwizeh 62 Posting Pro in Training

I've altered the code slightly this adds a timer to the bottom I'll leave it to you to find the differences.

import java.awt.* ;
import java.awt.event.* ;
import java.awt.geom.* ;
import javax.swing.* ;
import javax.swing.event.* ;
import javax.swing.Timer;
/**MineSweeper by SciWizEH*/
public class MineSweeper extends JFrame implements ActionListener ,
        MouseListener {
    int rows = 10 ;
    int cols = 10 ;
    int numMines = 10 ;
    GridLayout layout = new GridLayout ( rows , cols ) ;
    /*type[][] name = new type[rows][cols];
     * type[x][y];
     * is 1d
     * type[] name = new type[rows*cols];
     * type[(rows*y)+x];*/
    boolean [ ] mines = new boolean [ rows * cols ] ;
    boolean [ ] clickable = new boolean [ rows * cols ] ;
    boolean lost = false ;
    boolean won = false ;
    int [ ] numbers = new int [ rows * cols ] ;
    JButton [ ] buttons = new JButton [ rows * cols ] ;
    boolean [ ] clickdone = new boolean [ rows * cols ] ;
    JMenuItem newGameButton = new JMenuItem ( "new game" ) ;
    JMenuItem difficulty = new JMenuItem ( "options" ) ;
    JLabel mineLabel = new JLabel ( "mines: " + numMines + " marked: 0" ) ;
    JPanel p = new JPanel ( ) ;
    long startTime;
    int flags = 0;
    Timer timer;
    public MineSweeper ( ) {
        p.setLayout ( layout ) ;
        setupI ( ) ;
        for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
            p.add ( buttons [ i ] ) ;
        }
        timer = new Timer(50,this);
        JMenuBar mb = new JMenuBar ( ) ;
        JMenu m = new JMenu ( "file" ) ;
        newGameButton.addActionListener ( this ) ;
        m.add ( newGameButton ) ;
        difficulty.addActionListener ( this ) ;
        m.add ( difficulty ) ;
        mb.add ( m ) ;
        startTime=System.currentTimeMillis();
        this.setJMenuBar ( mb ) ;
        this.add ( p ) ;
        this.add ( mineLabel , BorderLayout.SOUTH ) ;
        this.pack ( ) ;
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible ( true ) ;
        timer.start();
    }

    public void fillMines ( ) {
        int needed = numMines ;
        while ( needed > 0 ) {
            int x = ( int ) Math.floor ( Math.random ( ) * rows ) ;
            int y = ( int ) Math.floor ( Math.random ( ) * cols ) ;
            if ( ! mines [ ( rows * y ) + x ] ) {
                mines [ ( rows * y ) + x ] = true ;
                needed -- ;
            }
        }
    }

    public void fillNumbers ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                int cur = ( rows * y ) + x ;
                if ( mines [ cur ] ) {
                    numbers [ cur ] = 0 ;
                    continue ;
                }
                int temp = 0 ;
                boolean l = ( x - 1 ) >= 0 ;
                boolean r = ( x + 1 ) < rows ;
                boolean u = ( y - 1 ) >= 0 ;
                boolean d = ( y + 1 ) < cols ;
                int left = ( rows * ( y ) ) + ( x - 1 ) ;
                int right = ( rows * ( y ) ) + ( x + 1 ) ;
                int up = ( rows * ( y - 1 ) ) + ( x ) ;
                int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
                int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
                int down = ( rows * ( y + 1 ) ) + ( x ) ;
                int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
                int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;
                if ( u ) {
                    if ( mines [ up ] ) {
                        temp ++ ;
                    }
                    if ( l ) {
                        if ( mines [ upleft ] ) {
                            temp ++ ;
                        }
                    }
                    if ( r ) {
                        if ( mines [ upright ] ) {
                            temp ++ ;
                        }
                    }
                }
                if ( d ) {
                    if ( mines [ down ] ) {
                        temp ++ ;
                    }
                    if ( l ) {
                        if ( mines [ downleft ] ) {
                            temp ++ ;
                        }
                    }
                    if ( r ) {
                        if ( mines [ downright ] ) {
                            temp ++ ;
                        }
                    }
                }
                if ( l ) {
                    if ( mines [ left ] ) {
                        temp ++ ;
                    }
                }
                if ( r ) {
                    if ( mines [ right ] ) {
                        temp ++ ;
                    }
                }
                numbers [ cur ] = temp ;
            }
        }
    }

    public void setupI ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                mines [ ( rows * y ) + x ] = false ;
                clickdone [ ( rows * y ) + x ] = false ;
                clickable [ ( rows * y ) + x ] = true ;
                buttons [ ( rows * y ) + x ] = new JButton ( /*"" + ( x * y )*/) ;
                buttons [ ( rows * y ) + x ].setPreferredSize ( new Dimension (
                        45 , 45 ) ) ;
                buttons [ ( rows * y ) + x ].addActionListener ( this ) ;
                buttons [ ( rows * y ) + x ].addMouseListener ( this ) ;
            }
        }
        fillMines ( ) ;
        fillNumbers ( ) ;
        startTime=System.currentTimeMillis();
    }

    public void setupI2 ( ) {
        this.remove ( p ) ;
        p = new JPanel ( ) ;
        layout = new GridLayout ( rows , cols ) ;
        p.setLayout ( layout ) ;
        buttons = new JButton [ rows * cols ] ;
        mines = new boolean [ rows * cols ] ;
        clickdone = new boolean [ rows * cols ] ;
        clickable = new boolean [ rows * cols ] ;
        numbers = new int [ rows * cols ] ;
        setupI ( ) ;
        for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
            p.add ( buttons [ i ] ) ;
        }
        this.add ( p ) ;
        this.pack ( ) ;
        fillMines ( ) ;
        fillNumbers ( ) ;
        startTime=System.currentTimeMillis();
    }

    public void setup ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                mines [ ( rows * y ) + x ] = false ;
                clickdone [ ( rows * y ) + x ] = false ;
                clickable [ ( rows * y ) + x ] = true ;
                buttons [ ( rows * y ) + x ].setEnabled ( true ) ;
                buttons [ ( rows * y ) + x ].setText ( "" ) ;
            }
        }
        fillMines ( ) ;
        fillNumbers ( ) ;
        lost = false ;
        startTime=System.currentTimeMillis();
        updateLabel();
    }

    public static void main ( String [ ] args ) {
        new MineSweeper ( ) ;
    }

    public void actionPerformed ( ActionEvent e ) {
        if(e.getSource()==timer){
            updateLabel();
            return;
        }
        if ( e.getSource ( ) == difficulty ) {
            rows = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
                    this , "Rows" , "Rows" , JOptionPane.PLAIN_MESSAGE , null ,
                    null , 10 ) ) ;
            cols = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
                    this , "Columns" , "Columns" , JOptionPane.PLAIN_MESSAGE ,
                    null , null , 10 ) ) ;
            numMines = Integer.parseInt ( ( String ) JOptionPane
                    .showInputDialog ( this , "Mines" , "Mines" ,
                            JOptionPane.PLAIN_MESSAGE , null , null , 10 ) ) ;
            setupI2 ( ) ;
        }
        if ( ! won ) {
            for ( int x = 0 ; x < rows ; x ++ ) {
                for ( int y = 0 ; y < cols ; y ++ ) {
                    if ( e.getSource ( ) == buttons [ ( rows * y ) + x ]
                            && ! won && clickable [ ( rows * y ) + x ] ) {
                        doCheck ( x , y ) ;
                        break ;
                    }
                }
            }
        }
        if ( e.getSource ( ) == newGameButton ) {
            setup ( ) ;
            won = false ;
            return ;

        }
        checkWin ( ) ;
        updateLabel();
    }

    public void mouseEntered ( MouseEvent e ) {

    }

    public void mouseExited ( MouseEvent e ) {

    }

    public void mousePressed ( MouseEvent e ) {
        if ( e.getButton ( ) == 3 ) {
            flags=0;
            for ( int x = 0 ; x < rows ; x ++ ) {
                for ( int y = 0 ; y < cols ; y ++ ) {
                    if ( e.getSource ( ) == buttons [ ( rows * y ) + x ] ) {
                        clickable [ ( rows * y ) + x ] = ! clickable [ ( rows * y )
                                + x ] ;
                    }
                    if ( ! clickdone [ ( rows * y ) + x ] ) {
                        if ( ! clickable [ ( rows * y ) + x ] ) {
                            buttons [ ( rows * y ) + x ].setText ( "X" ) ;
                            flags ++ ;
                        } else {
                            buttons [ ( rows * y ) + x ].setText ( "" ) ;
                        }
                    }
                }
            }
            updateLabel();
        }
    }

    private void updateLabel(){
        mineLabel.setText ( "mines: " + numMines + " marked: " + flags + " Time: " + (System.currentTimeMillis()-startTime)/1000 + "s ") ;
    }
    public void mouseReleased ( MouseEvent e ) {

    }

    public void mouseClicked ( MouseEvent e ) {

    }

    public void doCheck ( int x , int y ) {
        int cur = ( rows * y ) + x ;
        boolean l = ( x - 1 ) >= 0 ;
        boolean r = ( x + 1 ) < rows ;
        boolean u = ( y - 1 ) >= 0 ;
        boolean d = ( y + 1 ) < cols ;
        int left = ( rows * ( y ) ) + ( x - 1 ) ;
        int right = ( rows * ( y ) ) + ( x + 1 ) ;
        int up = ( rows * ( y - 1 ) ) + ( x ) ;
        int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
        int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
        int down = ( rows * ( y + 1 ) ) + ( x ) ;
        int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
        int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

        clickdone [ cur ] = true ;
        buttons [ cur ].setEnabled ( false ) ;
        if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && ! won ) {
            if ( u && ! won ) {
                if ( ! clickdone [ up ] && ! mines [ up ] ) {
                    clickdone [ up ] = true ;
                    buttons [ up ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ upleft ] && numbers [ upleft ] != 0
                            && ! mines [ upleft ] ) {
                        clickdone [ upleft ] = true ;
                        buttons [ upleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ upright ] && numbers [ upright ] != 0
                            && ! mines [ upright ] ) {
                        clickdone [ upright ] = true ;
                        buttons [ upright ].doClick ( ) ;
                    }
                }
            }
            if ( d && ! won ) {
                if ( ! clickdone [ down ] && ! mines [ down ] ) {
                    clickdone [ down ] = true ;
                    buttons [ down ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ downleft ] && numbers [ downleft ] != 0
                            && ! mines [ downleft ] ) {
                        clickdone [ downleft ] = true ;
                        buttons [ downleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ downright ]
                            && numbers [ downright ] != 0
                            && ! mines [ downright ] ) {
                        clickdone [ downright ] = true ;
                        buttons [ downright ].doClick ( ) ;
                    }
                }
            }
            if ( l && ! won ) {
                if ( ! clickdone [ left ] && ! mines [ left ] ) {
                    clickdone [ left ] = true ;
                    buttons [ left ].doClick ( ) ;
                }
            }
            if ( r && ! won ) {
                if ( ! clickdone [ right ] && ! mines [ right ] ) {
                    clickdone [ right ] = true ;
                    buttons [ right ].doClick ( ) ;
                }
            }
        } else {
            buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
            if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
                buttons [ cur ].setText ( "" ) ;
            }
        }
        if ( mines [ cur ] && ! won ) {
            buttons [ cur ].setText ( "0" ) ;
            doLose ( ) ;
        }
    }

    public void checkWin ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                int cur = ( rows * y ) + x ;
                if ( ! clickdone [ cur ] ) {
                    if ( mines [ cur ] ) {
                        continue ;
                    } else {
                        return ;
                    }
                }
            }
        }

        doWin ( ) ;
    }

    public void doWin ( ) {
        if ( ! lost && ! won ) {
            won = true ;
            JOptionPane.showMessageDialog ( null ,
                    "you win in " + (System.currentTimeMillis()-startTime)/1000 + " seconds!\nstarting a new game" , "you lose" ,
                    JOptionPane.INFORMATION_MESSAGE ) ;
            newGameButton.doClick ( ) ;
        }
    }

    public void doLose ( ) {
        if ( ! lost && ! won ) {
            lost = true ;
            for ( int i = 0 ; i < rows * cols ; i ++ ) {
                if ( ! clickdone [ i ] ) {
                    buttons [ i ].doClick ( 0 ) ;
                }
            }
            JOptionPane.showMessageDialog ( null ,
                    "you lose!\nstarting a new game" , "you lose" ,
                    JOptionPane.ERROR_MESSAGE ) ;
            setup ( ) ;
        }
    }
}
derpderpderp 0 Newbie Poster

thank u so much! im giving you credit for some code im using. one last question i think. any way to change the colors of any of this? like the grid or numbers or words etc? i thought itd be simple but i just cant figure it out

derpderpderp 0 Newbie Poster

thank u so much! im giving you credit for some code im using. one last question i think. any way to change the colors of any of this? like the grid or numbers or words etc? i thought itd be simple but i just cant figure it out

sciwizeh 62 Posting Pro in Training

look into the setForgroundColor(Color) method of Component for the text of the buttons, also setBackgroundColor(Color)

melindanoel17 0 Newbie Poster

is it possible to change the colors of the numbers or grid?

sciwizeh 62 Posting Pro in Training

insert buttons[i].setForgroundColor(Color.red) after 134 and import java.awt.Color to the top of the file see if that helps

melindanoel17 0 Newbie Poster

can i change the colors of anything in this game? like the numbers or the grid to make it look cooler?

melindanoel17 0 Newbie Poster

okayy thanks!

melindanoel17 0 Newbie Poster

it just said it cant find the variable "i"..

sciwizeh 62 Posting Pro in Training

( rows * y ) + x I wasn't paying attention use that instead of i

melindanoel17 0 Newbie Poster

now it says it cant find setforegroundcolor eventhough i input color at the top

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.