/* * SAD.java * * Created on May 2, 2003, 7:55 PM */ package games.mineseeker; /** * * @author walter */ public class SAD extends javax.swing.JFrame { static final javax.swing.ImageIcon [] icons = new javax.swing.ImageIcon [14]; static final int iEMPTY = 0; static final int iBLANK = 9; static final int iBOMB = 10; static final int iFLAG = 11; static final int iNOTBOMB = 12; static final int iNOTFLAG = 13; static final int NF = 30*16; static final int NM = 99; int [] fields = new int [NF]; int [] known = new int [NF]; /** Creates new form SAD */ public SAD() { java.util.Arrays.fill(icons,null); icons [iBLANK] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/blank.gif")); icons [iBOMB] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/bomb.gif")); icons [iEMPTY] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/empty.gif")); icons [iFLAG] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/flag.gif")); icons [iNOTBOMB] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/notBomb.gif")); icons [iNOTFLAG] = new javax.swing.ImageIcon(getClass().getResource("/games/mineseeker/notFlag.gif")); initComponents(); newGame(); } private void newGame() { java.util.Arrays.fill(fields,iEMPTY); java.util.Arrays.fill(known,iBLANK); int ml = NM; while (ml > 0) { int i = (int) (Math.random() * (double) NF); if (i >= 0 && i < NF && fields[i] == iEMPTY) { fields [i] = iBOMB; ml --; } } showKnown(); } private boolean isBomb(int i) { return i >= 0 && i < NF && fields[i] == iBOMB; } private boolean isFlag(int i) { return i >= 0 && i < NF && known[i] == iFLAG; } private boolean isBlank(int i) { return i >= 0 && i < NF && known[i] == iBLANK; } private static int [] nAll = new int [] { -31,-30,-29,-1,1,29,30,31 }; private static int [] nNoL = new int [] { -30,-29,1,30,31 }; private static int [] nNoR = new int [] { -31,-30,-1,29,30 }; private int neighbors(int i) { int n = 0; int [] nn; if (i % 30 == 0) { // no left neighbors nn = nNoL; } else if (i % 30 == 29) { // no right neigbors nn = nNoR; } else { nn = nAll; } for (int j = 0; j < nn.length; j ++) { if (isBomb(i+nn[j])) n ++; } return n; } private int flagsAround(int i) { int n = 0; int [] nn; if (i % 30 == 0) { // no left neighbors nn = nNoL; } else if (i % 30 == 29) { // no right neigbors nn = nNoR; } else { nn = nAll; } for (int j = 0; j < nn.length; j ++) { if (isFlag(i+nn[j])) n ++; } return n; } private int blanksAround(int i) { int n = 0; int [] nn; if (i % 30 == 0) { // no left neighbors nn = nNoL; } else if (i % 30 == 29) { // no right neigbors nn = nNoR; } else { nn = nAll; } for (int j = 0; j < nn.length; j ++) { if (isBlank(i+nn[j])) n ++; } return n; } private void showKnown() { getContentPane().removeAll(); for (int i = 0; i < NF; i ++) { javax.swing.JLabel lb; if (known [i]>=iBLANK) { lb = new javax.swing.JLabel(icons[known [i]]); } else { int n = neighbors(i); if (n>0) { lb = new javax.swing.JLabel(" "+n); lb.setForeground(java.awt.Color.RED); } else { lb = new javax.swing.JLabel(icons[iEMPTY]); } } lb.setName(Integer.toString(i)); getContentPane().add(lb); } pack(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents menuBar = new javax.swing.JMenuBar(); fileMenu = new javax.swing.JMenu(); miNewGame = new javax.swing.JMenuItem(); exitMenuItem = new javax.swing.JMenuItem(); helpMenu = new javax.swing.JMenu(); contentsMenuItem = new javax.swing.JMenuItem(); aboutMenuItem = new javax.swing.JMenuItem(); getContentPane().setLayout(new java.awt.GridLayout(16, 30)); setTitle("Search And Disarm"); addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { formMouseClicked(evt); } }); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); fileMenu.setText("File"); miNewGame.setText("New game"); miNewGame.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { miNewGameActionPerformed(evt); } }); fileMenu.add(miNewGame); exitMenuItem.setText("Exit"); exitMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { exitMenuItemActionPerformed(evt); } }); fileMenu.add(exitMenuItem); menuBar.add(fileMenu); helpMenu.setText("Help"); contentsMenuItem.setText("Contents"); contentsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { contentsMenuItemActionPerformed(evt); } }); helpMenu.add(contentsMenuItem); aboutMenuItem.setText("About"); aboutMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { aboutMenuItemActionPerformed(evt); } }); helpMenu.add(aboutMenuItem); menuBar.add(helpMenu); setJMenuBar(menuBar); pack(); }//GEN-END:initComponents private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed javax.swing.JOptionPane.showMessageDialog(this, "

The story.


"+ "It is the year "+(java.util.Calendar.getInstance().get(java.util.Calendar.YEAR)+1)+".
"+ "All the world has succumbed to the Evil Bogus Gater. The Internet consists only of machines running
"+ "UnmentionableWare(tm).

"+ "You, hidden far away and equiped with only a PDA, are all which is left of the free world.

"+ "In a desparate attempt you manage to override the PDA's UnmentionableWare(tm) with an old version of
"+ "a truly free OS. The last change you have to is play a certain game on each of the corrupted machines
"+ "around the world. In its normal form this is impossible: the cunning Evil Bogus Gater has, as always,
"+ "provided insufficient information to solve the problem.

"+ "But this FREE version of the game at least helps you by applying the information you DO have
"+ "to solve the problem as far as possible.
"+ "A concept so utterly foreign to the Evil Bogus Gater, you might actually succeed against all odds!

"+ "" ); }//GEN-LAST:event_aboutMenuItemActionPerformed private void contentsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_contentsMenuItemActionPerformed javax.swing.JOptionPane.showMessageDialog(this, "

" ); }//GEN-LAST:event_contentsMenuItemActionPerformed private void miNewGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miNewGameActionPerformed newGame(); }//GEN-LAST:event_miNewGameActionPerformed private boolean addToKnown(int i) throws Exception { if (i<0 || i >= NF || known[i]!=iBLANK) return false; known[i]=fields[i]; if (known[i]==iBOMB) { throw new Exception("Killed by AI!"); } return true; } private boolean setFlag(int i) { if (i<0 || i >= NF || known[i]!=iBLANK) return false; known[i]=iFLAG; return true; } private void solve() throws Exception { for (int i = 0; i < NF; i ++) { if (known [i] != iBLANK && known [i] != iFLAG && (neighbors(i) - flagsAround(i) == 0)) { boolean c = false; int [] nn; if (i % 30 == 0) { // no left neighbors nn = nNoL; } else if (i % 30 == 29) { // no right neigbors nn = nNoR; } else { nn = nAll; } for (int j = 0; j < nn.length; j ++) { if (addToKnown(i+nn[j])) c = true; } if (c) solve(); } } for (int i = 0; i < NF; i ++) { if (known [i] != iBLANK && known [i] != iFLAG && (neighbors(i) - flagsAround(i) == blanksAround(i))) { boolean c = false; int [] nn; if (i % 30 == 0) { // no left neighbors nn = nNoL; } else if (i % 30 == 29) { // no right neigbors nn = nNoR; } else { nn = nAll; } for (int j = 0; j < nn.length; j ++) { if (setFlag(i+nn[j])) c = true; } if (c) solve(); } } } /** Dead. * * Show errors and start new game. */ private void dead(String message) { for (int j = 0; j < NF; j ++) { if (known [j] == iFLAG && fields [j] != iBOMB) { known [j] = iNOTBOMB; } if (known [j] == iBLANK && fields [j] == iBOMB) { known [j] = iNOTFLAG; } } showKnown(); javax.swing.JOptionPane.showMessageDialog(this, "

"+message+"


You are dead.
"); newGame(); } private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked try { javax.swing.JLabel lb = (javax.swing.JLabel) findComponentAt(evt.getPoint()); // System.out.println(""+evt+" is " +lb+"\n"+lb.getName()); int i = Integer.valueOf(lb.getName()).intValue(); if (evt.getButton() == evt.BUTTON1) { known [i] = fields [i]; if (known [i] == iBOMB) { dead("You clicked on a bomb!"); return; } } else { known [i] = iFLAG; } try { solve(); } catch (Exception ex) { dead(ex.getMessage()); return; } showKnown(); } catch (Exception ex) { ex.printStackTrace(); } int n = 0; for (int i = 0; i < NF; i ++) { if (known [i] == iFLAG) n ++; } if (n == NM) { javax.swing.JOptionPane.showMessageDialog(this,"You Survived!"); newGame(); } }//GEN-LAST:event_formMouseClicked private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed exitForm (null); }//GEN-LAST:event_exitMenuItemActionPerformed /** Exit the Application */ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm try { System.exit(0); } catch (java.security.AccessControlException nope) { dispose (); } }//GEN-LAST:event_exitForm /** * @param args the command line arguments */ public static void main(String args[]) { new SAD().show(); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenu fileMenu; private javax.swing.JMenuItem exitMenuItem; private javax.swing.JMenuBar menuBar; private javax.swing.JMenuItem miNewGame; private javax.swing.JMenuItem aboutMenuItem; private javax.swing.JMenuItem contentsMenuItem; private javax.swing.JMenu helpMenu; // End of variables declaration//GEN-END:variables }