// file Mine.java /* Author: Peter Loeb Date: May, 2000 */ package com.palserv.mine; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; /** This is the applet which implements the game. @author Peter Loeb, April 2000 */ public class Mine extends JApplet { private JPanel wPanel = new JPanel(); private JPanel topPanel = new JPanel(); private JPanel fPanel = new JPanel(); private JButton fButton = new JButton(); private JPanel bord = new JPanel(); private boolean inAnApplet = true; private int hSiz = 8, wSiz = 8, nMine = 10; private String iBase = "/images/"; private ImageIcon[] fBut = new ImageIcon[4]; int rFig[] = {-1,-1,-1,0,0,1,1,1}; int cFig[] = {-1,0,1,-1,1,-1,0,1}; private boolean gamOver = true; private DigNums[] dNum = new DigNums[2]; private Timer gTim = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { dNum[1].increment(); } } ); private mBut[] butArray = new mBut[hSiz * wSiz]; void startTimer() { gTim.start(); } void stopTimer() { gTim.stop(); } mBut getBut(int ndx) { return butArray[ndx]; } int gethSiz() { return hSiz; } int getwSiz() { return wSiz; } boolean isOver() { return gamOver; } void gamOvr() { gamOver = true; gTim.stop(); boolean won = true; // see if open button has mine for (int i = 0; i < (hSiz * wSiz); i ++) { mBut tmb = butArray[i]; if (tmb.getbState() == 3 && tmb.isMine()) { won = false; break; } } if (!won) { setfBut(3); for (int i = 0; i < (hSiz * wSiz); i ++) { mBut tmb = butArray[i]; if (tmb.getbState() == 1) { if (!tmb.isMine()) { tmb.setbOpn(3); } } else { if (tmb.isMine() & tmb.getbState() != 3) { tmb.setbOpn(2); } } } } else { setfBut(2); } } /** This constructor overrides the default constructor. it is necessary because the program needs to differentiate between whether it runs as an applet or an application. This will be called at runtime if we are running as an applet. If we are running as an application, the other constructor is explicitly invoked from "main". It calls the "other" constructor with true to allow us to know that we are indeed in an applet. */ public Mine() { this(true); } /** This constructor allows us to know whether or not we are running in an applet. @param inApp boolean - answers the question "are we running in an applet? */ public Mine(boolean inApp) { inAnApplet = inApp; if (inAnApplet) { getRootPane().putClientProperty( "defeatSystemEventQueueCheck",Boolean.TRUE ); } } /** This method allows the applet to be used as an application. Note the call to the explicit constructor with the argument "false". */ public static void main(String args[]) { JFrame aFrame = new JFrame("Minesweeper"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); Mine myapp = new Mine(false); Container apane = myapp.makeContentPane(); aFrame.setContentPane(apane); aFrame.setSize(149,233); aFrame.pack(); aFrame.setVisible(true); } public void init() { setContentPane(makeContentPane()); } ImageIcon makeGif(String gName) { String iName = iBase + gName; return new ImageIcon(getClass().getResource(iName)); } private Container makeContentPane() { fBut[0] = makeGif("fnew.gif"); fBut[1] = makeGif("fbdn.gif"); fBut[2] = makeGif("fwin.gif"); fBut[3] = makeGif("flose.gif"); fButton.setIcon(fBut[0]); dNum[0] = new DigNums(10,this); dNum[0].init(); dNum[0].setDisp(nMine); dNum[1] = new DigNums(0,this); dNum[1].init(); dNum[1].setDisp(0); bord.setLayout(new GridLayout(wSiz,hSiz)); for (int row = 0; row < hSiz; row ++) { for (int col = 0; col < wSiz; col ++) { butArray[row * wSiz + col] = new mBut(row, col, this); bord.add(butArray[row * wSiz + col]); } } fButton.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { newGame(); } } ); fButton.setBorder( new EmptyBorder(0,0,0,0) // ) ); int mt = 5; bord.setBorder(new BevelBorder(BevelBorder.LOWERED)); Border bBord = bord.getBorder(); Border mBord = new EmptyBorder(0,mt,mt,mt); bord.setBorder(new CompoundBorder(mBord, bBord)); fPanel.setBorder(new BevelBorder(BevelBorder.RAISED)); fPanel.setLayout(new GridLayout(1,1)); fPanel.add(fButton); topPanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); Border bTop = topPanel.getBorder(); Border mTop = new EmptyBorder(mt,mt,mt,mt); topPanel.setBorder(new CompoundBorder(mTop, bTop)); topPanel.add(dNum[0]); topPanel.add(fPanel); topPanel.add(dNum[1]); wPanel.setBorder(new BevelBorder(BevelBorder.RAISED)); wPanel.setLayout(new BorderLayout()); wPanel.add("North",topPanel); wPanel.add("Center",bord); newGame(); return wPanel; } DigNums getMineCounter() { return dNum[0]; } DigNums getTimer() { return dNum[0]; } void setfBut(int setting) { fButton.setIcon(fBut[setting]); } private void newGame() { gamOver = false; gTim.stop(); setfBut(0); dNum[0].setDisp(nMine); dNum[1].setDisp(0); butArray[0].settStart(false); for (int i = 0; i < (wSiz * hSiz); i ++) { butArray[i].setbMine(false); } for (int i = 0; i < nMine; i ++) { int r = 0; boolean rFlag = true; while(rFlag) { r = (int)(Math.random() * wSiz * hSiz); if (butArray[r].isMine()) { continue; } butArray[r].setbMine(true); rFlag = false; } } for (int i = 0; i < (wSiz * hSiz); i ++) { butArray[i].mInit(); } } } // end of class Mine // ********************************************************** class mBut extends JButton { private int bRow; private int bCol; private int bNdx; private int bState; private boolean bMine; private int bValue; private Mine mm; private int[] aNdx = new int[8]; private int aSiz = 0; private int hSiz = 0; private int wSiz = 0; private int tSiz = 0; private static boolean gotImages = false; private static ImageIcon[] bGif = new ImageIcon[3]; private static ImageIcon[] bVal = new ImageIcon[9]; private static ImageIcon[] bOpn = new ImageIcon[4]; private static boolean timerStarted = false; void setbMine(boolean bm) { bMine = bm; } void settStart(boolean ts) { timerStarted = ts; } boolean isMine() { return bMine; } int getbValue() { return bValue; } int getbState() { return bState; } int getbNdx() { return bNdx; } mBut(int r, int c, Mine m) { bRow = r; bCol = c; mm = m; hSiz = mm.gethSiz(); wSiz = mm.getwSiz(); bNdx = bRow * hSiz + bCol; tSiz = hSiz * wSiz; bMine = false; if (!gotImages) { gotImages = true; for (int i = 0; i < 9; i ++) { bVal[i] = mm.makeGif("but"+i+".gif"); } bGif[0] = mm.makeGif("butclose.gif"); bGif[1] = mm.makeGif("butmark.gif"); bGif[2] = mm.makeGif("butques.gif"); bOpn[0] = mm.makeGif("buthit.gif"); bOpn[1] = mm.makeGif("butmiss.gif"); bOpn[2] = mm.makeGif("butmine.gif"); bOpn[3] = mm.makeGif("butx.gif"); } int a = 0; int ar = 0; int ac = 0; for (int i = 0; i < 8; i ++) { ar = r + mm.rFig[i]; if (ar < 0 | ar >= hSiz) continue; ac = c + mm.cFig[i]; if (ac < 0 | ac >= wSiz) continue; aNdx[a] = ar * hSiz + ac; a ++; } aSiz = a; setBorder(new EmptyBorder(0,0,0,0)); addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent me) { if (mm.isOver()) { return; } int mod = me.getModifiers(); if (mod == me.BUTTON1_MASK) { leftBut(true); } if (mod == me.BUTTON3_MASK) { rightBut(); } } public void mouseReleased(MouseEvent me) { if (mm.isOver()) { return; } int mod = me.getModifiers(); if (mod == me.BUTTON1_MASK) { leftButUp(); } } } ); } /* end of constructor */ void setbOpn(int o) { setIcon(bOpn[o]); } void rightBut() { // right button pressed if (!timerStarted) { mm.startTimer(); timerStarted = true; } if (bState == 3) { return; } if (bState == 0) { mm.getMineCounter().decrement(); } if (bState == 1) { mm.getMineCounter().increment(); } bState ++; bState %= 3; setIcon(bGif[bState]); if (bState == 1) { checkEog(); } } void leftButUp() { mm.setfBut(0); checkEog(); } void checkEog() { boolean gameOver = true; for (int i = 0; i < tSiz; i ++) { mBut tmb = mm.getBut(i); // if open button has mine then game over if (tmb.getbState() == 3) { if (tmb.isMine()) { break; } } else { // button is not opened if (tmb.isMine()) { if (!(tmb.getbState() == 1)) { gameOver = false; break; } } else { gameOver = false; break; } } } if (gameOver) { mm.gamOvr(); } } void leftBut(boolean notRecursive) { if (!timerStarted) { mm.startTimer(); timerStarted = true; } if (notRecursive) { mm.setfBut(1); } if (bState == 1) { mm.getMineCounter().increment(); } bState = 3; if (bMine) { setIcon(bOpn[0]); mm.gamOvr(); } else { if (bState == 1) { mm.getMineCounter().increment(); } setIcon(bVal[bValue]); if (bValue == 0) { // open all adjacent buttons for (int i = 0; i < aSiz; i ++) { mBut tmb = mm.getBut(aNdx[i]); if (tmb.getbState() != 0) { continue; } tmb.leftBut(false); } } } } void mInit() { setIcon(bGif[0]); bState = bValue = 0; if (bMine) { return; } for (int i = 0; i < aSiz; i ++) { if (mm.getBut(aNdx[i]).isMine()) { bValue ++; } } } } // end of class "mBut" // ***************************************************** class DigNums extends JPanel { private JLabel[] dNum = new JLabel[3]; private int[] sn = new int[3]; private int dispNum; private Mine mm; private static boolean gotImage = false; private static ImageIcon[] bNum = new ImageIcon[11]; DigNums(int dn, Mine m) { dispNum = dn; mm = m; if (!gotImage) { gotImage = true; for (int i = 0; i < 10; i ++) { bNum[i] = mm.makeGif("num"+i+".gif"); } bNum[10] = mm.makeGif("numm.gif"); } setBorder(new BevelBorder(BevelBorder.LOWERED)); } void init() { setLayout(new GridLayout(1,3)); for (int i = 0; i < 3; i ++) { dNum[i] = new JLabel(""); add(dNum[i]); } } void setDisp(int sd) { if (sd < 0) { dNum[0].setIcon(bNum[10]); dispNum = sd; sd *= -1; sd %= 100; sn[2] = sd % 10; sd -= sn[2]; sn[1] = sd / 10; for (int i = 1; i < 3; i ++) { dNum[i].setIcon(bNum[sn[i]]); } return; } sd %= 1000; dispNum = sd; sn[2] = sd % 10; sd -= sn[2]; sn[1] = sd % 100; sd -= sn[1]; sn[1] /= 10; sn[0] = sd % 1000; sn[0] /= 100; for (int i = 0; i < 3; i ++) { dNum[i].setIcon(bNum[sn[i]]); } } void increment() { dispNum ++; setDisp(dispNum); } void decrement() { dispNum --; setDisp(dispNum); } } // end of class "DigNums"