Blue Flower

Sourcecode from my Minesweeper Clone

 

package mweeper;
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
 
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
 
 
public class mweeper extends JFrame implements Runnable {
 
    private JFrame     mainFrame ;
    private JPanel    mainPanel;
    
    private int boardX     = 15;
    private int boardY    = 15;
    private int bombs    = 35;
    private int bombsMarked;
    private int cleanFields;
    private int seconds;
    
    private boolean gameOver     = false;
    private boolean win         = false;
    
    private Map<Integer, Map<Integer, mweeperField>> boardMap;
    private Map<Integer,position> bombMap;
    private JPanel boardPanel;
    private JPanel headPanel;
    private JTextField bombsField;
    private JLabel infoLabel;
    private JTextField axisField;
    
    public mweeper() {
        
    }
    public mweeper(int size) {
        this.boardX = size;
        this.boardY = size;
        this.bombs = (this.boardX * 2);
    }
    
    @Override
    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                
                try {
                    UIManager.setLookAndFeel(  UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                
                mainFrame = new JFrame("MWeeeeeeper");
                
                int w = Toolkit.getDefaultToolkit().getScreenSize().width;
                int h = Toolkit.getDefaultToolkit().getScreenSize().height;
                
                int width     = (boardX * 23);
                int height     = (width + 40);
 
                mainFrame.setPreferredSize(new Dimension(width,height));
                mainFrame.setResizable(false);
                
                mainPanel = new JPanel(new BorderLayout());
                
                init();
                setPanel();
                
                mainFrame.add(mainPanel);
                mainFrame.setContentPane(mainFrame.getContentPane());
                mainFrame.pack();
                mainFrame.setLocationRelativeTo(null);
                mainFrame.setVisible(true);
            }
            });
    }
    
    private void init() {
        bombMap        = new HashMap<Integer, mweeper.position>();
        boardMap     = new HashMap<Integer, Map<Integer,mweeperField>>();
        bombsMarked = 0;
        cleanFields = (boardX * boardY) - bombs;
        seconds     = 0;
        for(int i = 1; i<= boardX; i++) {
            boardMap.put(i, new HashMap<Integer, mweeperField>());
            for(int j = 1; j <= boardY; j++) {
                boardMap.get(i).put(j, new mweeperField(i, j ));
            }
        }
        placeBombs();
    }
    
    private boolean placeBombs() {
        Random pX = new Random();
        Random pY = new Random();
        int bombCount = 0;
        while(bombCount < bombs) {
            int x = (1 + pX.nextInt( boardX ) );
            int y = (1 + pY.nextInt( boardY ) );
            if(!boardMap.get(x).get(y).isBomb() ) {
                boardMap.get(x).get(y).setBomb();
                bombCount++;
                bombMap.put(bombCount, new position(x, y));
            }
        }
        return true;
    }
    
    private void setPanel() {
        mainPanel.add(head(), BorderLayout.PAGE_START);
        mainPanel.add(board(), BorderLayout.CENTER);
    }
    
    private JPanel head() {
        headPanel = new JPanel();
        headPanel.setLayout(new BoxLayout(headPanel, BoxLayout.LINE_AXIS));
        
        JLabel bombLabel = new JLabel("Bombs");
        
        bombsField = new JTextField(4);
        bombsField.setEditable(true);
        bombsField.setText( String.valueOf(bombs));
        
        infoLabel = new JLabel("0/" + bombs);
        infoLabel.setFont(new Font("Arial", Font.BOLD, 14));
        
        JLabel axisLabel = new JLabel("X/Y");
        axisField = new JTextField(4);
        axisField.setEditable(true);
        axisField.setText( String.valueOf(boardX));
        
        JButton start = new JButton("Start");
        start.addActionListener( new mweeperAction(GameActions.START) );
        
        headPanel.add(bombLabel);
        headPanel.add(bombsField);
        
        headPanel.add(new JLabel("  "));
        
        headPanel.add(axisLabel);
        headPanel.add(axisField);
        headPanel.add(new JLabel("  "));
        headPanel.add(infoLabel);
        headPanel.add(start);
        return headPanel;
    }
    
    private JPanel board() {
        boardPanel = new JPanel();
        GridLayout gLayout = new GridLayout(boardX, boardY, 0, 0 );
        boardPanel.setLayout(gLayout);
        
        for( Integer x : boardMap.keySet()) {
            for(Integer y : boardMap.get(x).keySet()) {
                boardPanel.add( boardMap.get(x).get(y).getButton() );
            }
        }
        return boardPanel;
    }
    
    private void gameOver() {
        this.gameOver = true;
        for( Integer x : boardMap.keySet()) {
            for(Integer y : boardMap.get(x).keySet()) {
                boardMap.get(x).get(y).trigger();
            }
        }
    }
    
    public class mweeperField implements mousePerformer {
        private position     pos;
        private FieldStatus status             = FieldStatus.HIDE_UNMARKED;
        private boolean     isBomb             = false;
        private int         bombsAroundMe     = 0;
        private JButton     but;
        private boolean     isTriggered        = false;
        
        public mweeperField( int x, int y ) {
            this.pos = new position(x, y);
            init();
        }
        public mweeperField( position p ) {
            this.pos = p;
            init();
        }
        public void resetField() {
            status             = FieldStatus.HIDE_UNMARKED;
            isBomb             = false;
            bombsAroundMe     = 0;
            isTriggered     = false;
            but.setFont(new Font("Arial", Font.BOLD, 13));
            but.setBackground(Color.DARK_GRAY);
            but.setText(" ");
            but.setEnabled(true);
        }
        public void setBomb() {
            this.isBomb = true;
        }
        public boolean isBomb() {
            return isBomb;
        }
        private void init() {
            but = new JButton(" ");
            but.setMaximumSize(new Dimension(16, 16));
            but.setMinimumSize(new Dimension(16, 16));
            but.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
            but.setMargin(new Insets(0, 0, 0, 0));
            but.setBackground(Color.DARK_GRAY);
            but.addMouseListener(new mweeperMouseListener(this.pos, this));
            but.setFont(new Font("Arial", Font.BOLD, 14));
        }
        
        private void setButton() {
            switch(status) {
                case HIDE_MARKED:
                    //but.setForeground( new Color(224, 124, 168) );
                    but.setForeground( Color.RED);
                    but.setText("@");
                    but.setEnabled(true);
                    break;
                case HIDE_UNMARKED: 
                    but.setForeground(Color.BLACK);
                    but.setText(" ");
                    but.setEnabled(true);
                    break;
                case OPEN_NOBOMB: 
                    switch(this.bombsAroundMe) {
                        case 1: 
                        case 2:    but.setForeground(Color.BLUE);
                            break;
                        case 3:
                        case 4:    but.setForeground(Color.MAGENTA);
                            break;
                        case 5:
                        case 6:    but.setForeground(Color.RED);
                            break;
                        case 7:
                        case 8:    but.setForeground(Color.PINK);
                            break;
                    }
                    String butText = " ";
                    if(this.bombsAroundMe > 0) {
                        butText = String.valueOf(this.bombsAroundMe);
                    }
                    but.setEnabled(false);
                    but.setBackground(Color.LIGHT_GRAY);
                    
                    but.setText( butText );
                    break;
                    
                case OPEN_BOMB: // GAME OVER
                    if(win) {
                        but.setBackground(Color.GREEN);
                    }
                    but.setForeground(Color.BLACK);
                    but.setFont(new Font("Arial", Font.BOLD, 20));
                    but.setVerticalAlignment(SwingConstants.CENTER);
                    but.setHorizontalAlignment(SwingConstants.CENTER);
                    but.setText("*");
                    break;
            }
            but.validate();
            but.repaint();
            boardPanel.validate();
            boardPanel.repaint();
            mainPanel.repaint();
        }
        
        public JButton getButton() {
            return but;
        }
        
        /*
         +-----+-----+-----+
         | x-1 |  x  | x+1 |
         | y-1 | y-1 | y-1 |
         +-----+-----+-----+
         | x-1 | x/y | x+1 |
         |  y  |     |  y  |
         +-----+-----+-----+
         | x-1 |  x  | x+1 |
         | y+1 | y+1 | y+1 |
         +-----+-----+-----+
         */
        
        private void scan() {
            bombsAroundMe = 0;
            for(Integer k : pos.posAroundMe.keySet() ) {
                position p2 = pos.posAroundMe.get(k);
                if(boardMap.get(p2.x).get(p2.y).isBomb()) {
                    bombsAroundMe++;
                }
            }
        }
        
        public void trigger() {
            if(!isTriggered) {
                isTriggered = true;
                if(!isBomb) {
                    status =  FieldStatus.OPEN_NOBOMB ;
                    cleanFields--;
                }else {
                    status =  FieldStatus.OPEN_BOMB;
                }
                scan();
                setButton();
                if(bombsAroundMe == 0) {
                    // um mich herum triggern
                    for(Integer k : pos.posAroundMe.keySet() ) {
                        position p2 = pos.posAroundMe.get(k);
                        boardMap.get(p2.x).get(p2.y).trigger();
                    }
                }
                checkGameStatus();
            }            
        }
        
        private void checkGameStatus() {
            if( (cleanFields <= 0) &amp;&amp; ( bombsMarked == bombs )  ) {
                // WIN
                win = true;
                gameOver();
            }
        }
        
        @Override
        public void doClick(MouseEvent e, position pos) {
            switch(e.getButton()) {
                case 1:    //Links Klick = triggern wenn nich markiert und hide
                        if(this.status.equals(FieldStatus.HIDE_UNMARKED)){
                            if(this.isBomb) {
                                // GAME OVER =8-(
                                status = FieldStatus.OPEN_BOMB;
                                but.setBackground(Color.RED);
                                gameOver();
                            }else {
                                trigger();
                            }    
                        }
                    break;
                    
                case 3: // Rechtsklick
                    if(this.status.equals(FieldStatus.HIDE_UNMARKED)) {
                        // Mark Field
                        this.status = FieldStatus.HIDE_MARKED;
                        bombsMarked++;
                    }else if(this.status.equals(FieldStatus.HIDE_MARKED)){
                        // Umark Field
                        this.status = FieldStatus.HIDE_UNMARKED;
                        bombsMarked--;
                    }
                    setButton();
                    setInfoLabel();
                    checkGameStatus();
                    break;
            }
        }
    }
    
    private void setInfoLabel() {
        String t = bombsMarked + " / " + bombs;
        infoLabel.setText(t);;
        infoLabel.validate();
        infoLabel.repaint();
    }
    
    public class position {
        public int x = 0;
        public int y = 0;
        public Map<Integer, position> posAroundMe;
        public position(int x, int y) {
            this.x = x;
            this.y = y;
            posAroundMe = new HashMap<Integer, mweeper.position>();
            setPosAroundMe();
        }
        public position(int x, int y, boolean setPos) {
            posAroundMe = new HashMap<Integer, mweeper.position>();
            this.x = x;
            this.y = y;
        }
        private void setPosAroundMe() {
            int c = 1;
            for(int x2 = (x-1); x2 <= (x+1); x2++) {
                for(int y2 = (y-1); y2 <= (y+1); y2++) {
                    if( ((x2 != x) || (y2 != y)) &amp;&amp; ( x2>0 &amp;&amp; x2<=boardX &amp;&amp; y2>0 &amp;&amp; y2<=boardY ) ){
                        posAroundMe.put(c++, new position(x2, y2, false));
                    }
                }
            }
        }
    }
    
    public enum FieldStatus{
        HIDE_UNMARKED,
        HIDE_MARKED,
        OPEN_NOBOMB,
        OPEN_BOMB;
    }
    
    public enum GameActions{
        START;
    }
    
    public class mweeperAction extends AbstractAction{
        private GameActions gameAction;
        
        public mweeperAction(GameActions ga ) {
            this.gameAction    = ga;
        }
        
        @Override
        public void actionPerformed(ActionEvent ae) {
            switch(gameAction) {
            case START:
                    for( Integer x : boardMap.keySet()) {
                        for(Integer y : boardMap.get(x).keySet()) {
                            boardMap.get(x).get(y).resetField();;
                            boardMap.get(x).get(y).getButton().validate();
                            boardMap.get(x).get(y).getButton().repaint();;
                        }
                    }
                    int newBombCount = Integer.valueOf(bombsField.getText()) ;
                    if(newBombCount < 10) {
                        newBombCount = 10;
                    }
                    if(newBombCount > ((boardX * boardY)/2 ) ){
                        newBombCount = ((boardX * boardY)/2 ); 
                    }
                    bombs = newBombCount;
                    bombsField.setText(String.valueOf(bombs) );
                    cleanFields = (boardX * boardY) - bombs;
                    bombsMarked = 0;
                    win         = false;
                    
                    int newBoardX = Integer.valueOf( axisField.getText() );
                    if( (newBoardX != boardX) &amp;&amp; ( newBoardX <= 30 ) &amp;&amp; ( newBoardX >= 10) ) {
                        startNew(newBoardX);
                    }else {
                        axisField.setText(String.valueOf(boardX));
                    }
 
                    placeBombs();
                    boardPanel.validate();
                    boardPanel.repaint();
                    mainPanel.repaint();
                break;
            }
        }
    }
    
    public class mweeperMouseListener implements MouseListener{
        private position pos;
        mousePerformer performer;
        public mweeperMouseListener(position pos, mousePerformer acPerf) {
            this.pos = pos;
            this.performer = acPerf;
        }
        @Override
        public void mouseClicked(MouseEvent e) {
            this.performer.doClick(e , pos );
        }
        @Override
        public void mouseEntered(MouseEvent e) {}
        @Override
        public void mouseExited(MouseEvent e) {}
        @Override
        public void mousePressed(MouseEvent e) {}
        @Override
        public void mouseReleased(MouseEvent e) {}
    }
    
    public interface mousePerformer{
        public void doClick(MouseEvent e, position pos   );
    }
    public interface actionPerformer{
        public void doAction(ActionEvent ae, GameActions ga );
    }
    
    private void startNew(int newSize) {
        mainFrame.dispose();
        mainFrame.setVisible(false);
        mweeper mw = new mweeper(newSize);
        (new Thread(mw)).start();
    }
    
    public static void main(String[] args) {
        mweeper mw = new mweeper();
        (new Thread(mw)).start();
    }
 
}
Pin It