/** * @(#)Minesweeper.java * It's be nice to have implemented high scores, but I ran out of time. * Loved to have tried using JAR file storage but again no time. * @author Michael Cecconet * @version 1.00 2007/6/5 */import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.util.Random;public class Minesweeper extends JFrame implements ActionListener, MouseListener { boolean gameOver = false; boolean startTime = false; Timer t = new Timer(1000, this);//Updates every second int timeTaken = 0;//In seconds //Tile System (Global) - Consists of an array of Tile Object that saves status, and a sister array of JLabels displaying the status. Tile[][] grid = new Tile[32][32]; JLabel[][] gridShow = new JLabel[grid.length][grid[0].length]; int xBound = 9; int yBound = 9; int mineCount = 10; int flagCount = 0; int topHighScore = 999; String playerName = ""; //Image Declarations (Global) public static ImageIcon baseTile = new ImageIcon("images/normal.png", "basic tile"); public static ImageIcon flagTile = new ImageIcon("images/flag.png", "flagged tile"); public static ImageIcon failTile = new ImageIcon("images/failflag.png", "flagged but not a mine tile"); public static ImageIcon mineTile = new ImageIcon("images/mine.png", "mine revealed tile"); public static ImageIcon icon = new ImageIcon("images/smiley.png", "Smiley Face"); public static ImageIcon[] mineImage = new ImageIcon[9]; //Menu Declarations (Global) JMenuItem j1 = new JMenuItem("New Game "); JMenuItem j2 = new JMenuItem("Beginner"); JMenuItem j3 = new JMenuItem("Intermediate"); JMenuItem j4 = new JMenuItem("Expert"); JMenuItem j5 = new JMenuItem("Best Times"); JMenuItem j6 = new JMenuItem("Exit"); JMenuItem j7 = new JMenuItem("About Minesweeper"); JMenu m1 = new JMenu("Game"); JMenu m2 = new JMenu("Info"); JMenuBar mb1 = new JMenuBar(); //Layout Declarations (Global) BorderLayout mainLayout = new BorderLayout(); GridLayout infoLayout = new GridLayout(1,3); GridLayout gameGrid = new GridLayout(yBound,xBound, 0, 0); JPanel informationPane = new JPanel(); JPanel gamePane = new JPanel(); //Component Declarations (Global) JButton gameStatus = new JButton("New Game :)"); JLabel theTime = new JLabel(timeTaken+"s"); JLabel flagSet = new JLabel(mineCount-flagCount+" Flags "); //Tile Class public class Tile { private boolean visibleStatus; private boolean containsMine; public boolean flagStatus; private int number; //Constructor public Tile(){ visibleStatus = false;//Hidden containsMine = false;//No Mine flagStatus = false;//No Flag number = 0; } //Initializes a Mine on this Space public void setMine(){ containsMine = true; } //Saves the Number of Mine Surronding public void setNumber(int getNumber){ number = getNumber; } //Called on Click public void setVisible(){ if (containsMine ==true){ gameOver = true; System.out.println("BOOM!"); } visibleStatus = true; } public void reset(){ visibleStatus = false;//Hidden containsMine = false;//No Mine flagStatus = false;//No Flag number = 0; } } //CreateAndShowGUI public Minesweeper(){ //Window Setup super("Minesweeper - RRXIII"); setSize(240,300); //setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Set Layout saveArrays(); Container mainWindow = getContentPane(); mainWindow.setLayout(mainLayout); //Set Action Commands (For multiple compenent usage) j1.setActionCommand("newGame"); //Set ActionListeners j1.addActionListener(this); j2.addActionListener(this); j3.addActionListener(this); j4.addActionListener(this); j5.addActionListener(this); j6.addActionListener(this); j7.addActionListener(this); //Component Stuff j5.setEnabled(false); m1.add(j1); m1.addSeparator(); m1.add(j2); m1.add(j3); m1.add(j4); m1.addSeparator(); m1.add(j6); m2.add(j5); m2.add(j7); mb1.add(m1); mb1.add(m2); setJMenuBar(mb1); //Reset tiles used for this game gameReset(xBound, yBound, mineCount); //Add in Content mainWindow.add(informationPane, BorderLayout.PAGE_START); mainWindow.add(gamePane, BorderLayout.CENTER); mainWindow.add( new JLabel(" "), BorderLayout.PAGE_END); mainWindow.add( new JLabel(" "), BorderLayout.LINE_START); mainWindow.add( new JLabel(" "), BorderLayout.LINE_END); setVisible(true); } //Handle Events public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (e.getActionCommand() == "newGame"){//New Game Same Settings gameReset(xBound, yBound, mineCount); }else if (source == j2){//New Game Beginner Settings xBound = 9; yBound = 9; mineCount = 10; setSize(xBound*20+20,yBound*28+40); gameReset(xBound, yBound, mineCount); }else if (source == j3){//New Game Intermediate Settings xBound = 16; yBound = 16; mineCount = 40; gameReset(xBound, yBound, mineCount); setSize(xBound*20+10,yBound*28+10); }else if (source == j4){//New Game Expert Settings xBound = 30; yBound = 16; mineCount = 99; setSize(xBound*20+10,yBound*28+10); gameReset(xBound, yBound, mineCount); }else if (source == j7){//Show About Minesweeper //JOptionPane.showMessageDialog(null, "Minesweeper v 1.0", "Developed by Michael Cecconet", "June 15, 2007"); showAll(); }else if (source == t){//Timer. if (gameOver == false){ timeTaken ++; theTime.setText(timeTaken+"s"); }else{ t.stop(); } }else if (source == t && gameOver == true){//GameOver Display all mines piggybacks with the timer (Probably more efficent way to accomplish this but I'll worry about it later.) for (int x = 0; x < xBound; x++){ for (int y = 0; y < yBound; y++){ if (grid[x][y].containsMine == true){ grid[x][y].setVisible(); } } } } //All Events will update the window. repaint(); validate(); } //Mouse Handling Events public void mouseClicked(MouseEvent e){ boolean winConditions = true; if ((e.getModifiers() & InputEvent.BUTTON1_MASK)== InputEvent.BUTTON1_MASK){ //System.out.println("Left Mouse Clicked "+ e.getComponent()); for (int x = 0; x < xBound; x++){ for (int y = 0; y < yBound; y++){ if ( e.getComponent() == gridShow[x][y] && grid[x][y].flagStatus == false && grid[x][y].visibleStatus == false && gameOver == false){ if (grid[x][y].containsMine == true){ revealMines(); } reveal(x,y); repaint(); //validate(); } if (grid[x][y].visibleStatus == false && grid[x][y].containsMine == false){ winConditions = false; } } } if (winConditions == true){ t.stop(); gameStatus.setText("You won! :D"); gameOver = true; if (timeTaken < topHighScore ){ topHighScore = timeTaken; } } }else if((e.getModifiers() & InputEvent.BUTTON2_MASK)== InputEvent.BUTTON2_MASK){ //System.out.println("Middle Mouse Clicked "); }else if((e.getModifiers() & InputEvent.BUTTON3_MASK)== InputEvent.BUTTON3_MASK){ flagCount = 0; for (int x = 0; x < xBound; x++){// Get Flag Count (Changing on Mouse gives to inconsitent results better to count and waste memory than to be off.) for (int y = 0; y < yBound; y++){ if (grid[x][y].flagStatus == true){ flagCount +=1; } } } flagSet.setText((mineCount-flagCount+1)+" Flags "); //System.out.println("Right Mouse Clicked "); for (int x = 0; x < xBound; x++){ for (int y = 0; y < yBound; y++){ if ( e.getComponent() == gridShow[x][y] && grid[x][y].visibleStatus == false){ if (grid[x][y].flagStatus == true ){ grid[x][y].flagStatus = false; gridShow[x][y].setIcon(baseTile); }else if (grid[x][y].flagStatus == false && flagCount < mineCount){ grid[x][y].flagStatus = true; gridShow[x][y].setIcon(flagTile); } } } } } if (startTime == false){ t.start(); } } public void mouseEntered(MouseEvent e){ } public void mouseExited(MouseEvent e){ } public void mousePressed(MouseEvent e){ } public void mouseReleased(MouseEvent e){ } //Game Methods //Defines all the settings for a new game. public void gameReset(int xBound, int yBound, int mineCount){ int tempX, tempY; int tempMineCount = 0; Random generator = new Random(); for (int x = 0; x < xBound; x++){ for (int y = 0; y < yBound; y++){ grid[x][y].reset(); gridShow[x][y].setIcon( baseTile); } } for (int i = 0; i < mineCount; i ++){ do{ tempX = generator.nextInt(xBound); tempY = generator.nextInt(yBound); } while (grid[tempX][tempY].containsMine == true); grid[tempX][tempY].setMine(); //System.out.println(tempX+", "+tempY); } //Set the Number of mines for all spaces. (Egad, 4 nested for loops, good thing it only runs on creation of a new game) for (int x = 0; x < xBound; x++){ for (int y = 0; y < yBound; y++){ if (grid[x][y].containsMine == false){ for (int xi = 0; xi < 3; xi ++){ for (int yi = 0; yi < 3; yi ++){ if ((x+xi-1) >= 0 && ((x+xi-1) <= xBound-1) && (y+yi-1) >= 0 && ((y+yi-1) <= yBound-1)){ if (grid[x+xi-1][y+yi-1].containsMine == true){ tempMineCount ++; } } } } grid[x][y].setNumber(tempMineCount); tempMineCount = 0; } } } gameGrid = new GridLayout(yBound,xBound, 0, 0); flagCount = 0; //Refresh Information JPanel informationPane.removeAll(); gameStatus.addActionListener(this); gameStatus.setActionCommand("newGame"); gameStatus.setText("New Game :)"); flagSet.setText(mineCount-flagCount+" Flags "); informationPane.add(flagSet); informationPane.add(gameStatus); informationPane.add(theTime); //Refresh Game JPanel gamePane.removeAll(); gamePane.setLayout(gameGrid); for (int y = 0; y < yBound; y++){ for (int x = 0; x < xBound; x++){ gamePane.add(gridShow[x][y]); } } //Timer Reset startTime = false; timeTaken = 0; t.restart(); t.stop(); gameOver = false; } //Reveal Tile Method public void reveal(int x, int y){ grid[x][y].setVisible(); gridShow[x][y].setIcon(mineImage[grid[x][y].number]); if (grid[x][y].containsMine == true){ gameStatus.setText("Game Over :("); gridShow[x][y].setIcon(mineTile); } else { if (grid[x][y].number == 0){ for (int xi = 0; xi < 3; xi ++){ for (int yi = 0; yi < 3; yi ++){ if ((x+xi-1) >= 0 && ((x+xi-1) <= xBound-1) && (y+yi-1) >= 0 && ((y+yi-1) <= yBound-1)){ if (grid[x+xi-1][y+yi-1].number == 0 && grid[x+xi-1][y+yi-1].visibleStatus == false){ System.out.println("Revealing : "+(x-1+xi)+", "+(y-1+yi)); reveal((x-1+xi),(y-1+yi)); } grid[x-1+xi][y-1+yi].setVisible(); gridShow[x-1+xi][y-1+yi].setIcon(mineImage[grid[x-1+xi][y-1+yi].number]); } } } } } } //Reveal Mine Method (Called before GameOver) public void revealMines(){ for (int y = 0; y < yBound; y++){ for (int x = 0; x < xBound; x++){ if (grid[x][y].containsMine == true && grid[x][y].flagStatus == false){ gridShow[x][y].setIcon(mineTile); }else if (grid[x][y].containsMine == false && grid[x][y].flagStatus == true) gridShow[x][y].setIcon(failTile); } } repaint(); } //Fights the evil powers that be that prevent declaring array elements globally. public void saveArrays(){ mineImage[0] = new ImageIcon("images/blank.png", "0 mines surronding"); mineImage[1] = new ImageIcon("images/1.png", "1 mine surronding"); mineImage[2] = new ImageIcon("images/2.png", "2 mines surronding"); mineImage[3] = new ImageIcon("images/3.png", "3 mines surronding"); mineImage[4] = new ImageIcon("images/4.png", "4 mines surronding"); mineImage[5] = new ImageIcon("images/5.png", "5 mines surronding"); mineImage[6] = new ImageIcon("images/6.png", "6 mines surronding"); mineImage[7] = new ImageIcon("images/7.png", "7 mines surronding"); mineImage[8] = new ImageIcon("images/8.png", "8 mines surronding"); //Trying to efficently manage memory as before I called a new object for every new game, now it uses the same objects but are reset. for (int x = 0; x < grid.length; x ++){ for (int y = 0; y < grid[0].length; y ++){ grid[x][y] = new Tile(); gridShow[x][y] = new JLabel(); gridShow[x][y].addMouseListener(this); } } } //Debug Method - Show All Squares public void showAll(){ gamePane.removeAll(); for (int y = 0; y < yBound; y++){ for (int x = 0; x < xBound; x++){ if (grid[x][y].containsMine == false){ gridShow[x][y].setIcon(mineImage[grid[x][y].number]); //gridShow[x][y].setText(x+", "+y); gamePane.add(gridShow[x][y]); }else if (grid[x][y].containsMine == true){ gridShow[x][y].setIcon(flagTile); gamePane.add(gridShow[x][y]); } } } } //Main Method public static void main(String[] args){ System.out.println("Check"); Minesweeper game = new Minesweeper(); } }