import java.awt.*;
import java.io.*;
import java.net.URL;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.concurrent.*;
public class MineSweep
{
public static void main(String[] args)
{
JFrame frame = new MineFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class MineFrame extends JFrame
{
private JPanel buttonPanel;
private MinePanel mp;
private int rn,cn;
public static final int DEFAULT_WIDTH = 650;
public static final int DEFAULT_HEIGHT = 450;
public static final int DEFAULT_CN = 9;
public static final int DEFAULT_RN = 9;
public JLabel remainMine;
public JLabel mes;
private JComboBox cb;
public MineFrame()
{
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
setTitle("扫雷");
mp = new MinePanel(DEFAULT_CN,DEFAULT_RN,this);
mp.setMinenum(10);
mp.setRC(9,9);
buttonPanel = new JPanel();
add(mp,BorderLayout.CENTER);
mes = new JLabel("");
mes.setEnabled(false);
add(mes,BorderLayout.EAST);
cb = new JComboBox();
cb.setEditable(true);
cb.addItem("初级");
cb.addItem("中级");
cb.addItem("高级");
cb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int index = cb.getSelectedIndex();
System.out.println(index);
switch(index)
{
case 0:
mp.setMinenum(10);
mp.setRC(9,9);
break;
case 1:
mp.setMinenum(40);
mp.setRC(16,16);
break;
case 2:
mp.setMinenum(99);
mp.setRC(30,16);
break;
}
}
}
);
JButton showAll = new JButton("显示所有地雷");
showAll.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
mp.showMines();
}
}
);
buttonPanel.add(showAll);
JButton replay = new JButton("重新开始");
replay.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
mp.updateMines();
}
}
);
buttonPanel.add(replay);
buttonPanel.add(cb);
remainMine = new JLabel("剩余雷数:" +mp.getMinenum());
add(remainMine,BorderLayout.SOUTH);
add(buttonPanel,BorderLayout.NORTH);
}
}
class Pair
{
public Pair(int r,int c)
{
this.r = r;
this.c =c;
}
public int r;
public int c;
}
class MinePanel extends JPanel implements MouseListener
{
private int cn,rn;
private int minenum;
private Mine[][] mines;
private int hideMine = minenum;
private int ableMn ;
private MineFrame f;
private boolean over ;
private int w,h;
private boolean win;
public static ArrayList<Image> IMAGES = new ArrayList<Image>(12);
public MinePanel(int rn,int cn,MineFrame f)
{
IMAGES.add(new ImageIcon(getURL(".\\img\\0.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\1.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\2.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\3.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\4.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\5.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\6.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\7.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\8.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\mine.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\11.gif")).getImage());
IMAGES.add(new ImageIcon(getURL(".\\img\\12.gif")).getImage());
this.f = f;
this.rn = rn;
this.cn = cn;
this.ableMn = rn * cn;
addMouseListener(this);
updateMines();
}
public URL getURL(String file)
{
URL url =null;
try
{
url = this.getClass().getResource(file);
}
catch(Exception e)
{
e.printStackTrace();
}
return url;
}
public void decAbleMn()
{
ableMn --;
}
public int getAbleMn()
{
return ableMn;
}
public void decHideMine()
{
hideMine --;
}
public void incHideMine()
{
hideMine ++;
}
public int getHideMine()
{
return hideMine;
}
public void setMinenum(int n)
{
minenum = n;
}
public int getMinenum()
{
return minenum;
}
public void mousePressed(MouseEvent e)
{
if(!over)
{
int x = (int)e.getX();
int y = (int)e.getY();
int keyCode = e.getButton();
int c,r;
r = x/Mine.WIDTH;
c = y/Mine.HEIGHT;
switch(keyCode)
{
case MouseEvent.BUTTON1:
if(mines[r][c].getFlag() == false)
{
try
{
mines[r][c].setOpen();
decAbleMn();
if(mines[r][c].getImage() == 9)
{
over = true;
decHideMine();
showMines();
}
else if(mines[r][c].getImage() == 0)
{
if(getAbleMn() == rn * cn - minenum)
{
win = true;
}
openNear(r,c);
}
}
catch(Exception ex)
{
//e.printStackTrace();
}
repaint();
}
break;
case MouseEvent.BUTTON3:
if( mines[r][c].isOpen() == false || mines[r][c].getFlag() == true)
{
if(mines[r][c].getFlag() == true)
{
incHideMine();
mines[r][c].setFlag();
repaint();
}
else if(hideMine > 0)
{
mines[r][c].setFlag();
decHideMine();
repaint();
}
}
break;
}
}
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
private ArrayDeque<Pair> queue = new ArrayDeque<Pair>(20);
public void openNear(int r,int c)
{
int i,j;
i = r;
j = c;
for(int n = -1; n <= 1; n ++)
{
r = i + n;
if(r >= 0 && r <mines.length)
for(int k = -1; k <=1; k ++)
{
c = j + k;
if(c >= 0 && c < mines[r].length)
{
if(mines[r][c].isOpen() == false && mines[r][c].getImage() == 0)
{
mines[r][c].setOpen();
queue.add(new Pair(r,c));
}
else
{
if(mines[r][c].getFlag() ==true)
{
mines[r][c].setFlag();
incHideMine();
}
mines[r][c].setOpen();
}
}
}
}
for(i = 0 ;i < queue.size(); i ++)
{
Pair p = queue.poll();
openNear(p.r,p.c);
}
}
public void setRC(int rn,int cn)
{
this.rn = rn;
this.cn = cn;
updateMines();
repaint();
}
public void updateMines()
{
removeAll();
win = false;
over = false;
f.setSize((10 +rn) * 20,(cn + 10) * 20);
setSize(rn * Mine.HEIGHT,cn * Mine.WIDTH);
mines = new Mine[rn][cn];
for(int i = 0;i < mines.length;i ++)
for(int j = 0 ;j < mines[i].length; j ++)
{
mines[i][j] = new Mine(i,j);
}
int mn = getMinenum();
hideMine = mn;
for(int i = 0; i <mn;i ++)
{
int r,c;
do
{
r = (int)(Math.random() * rn);
c = (int)(Math.random() * cn);
}while(mines[r][c].getImage() == 9);
mines[r][c].setImage(9);
}
generateNum();
repaint();
}
public void generateNum()
{
int r,c;
for(int i = 0 ;i < mines.length;i ++)
for(int j = 0 ;j < mines[i].length; j ++)
if(mines[i][j].getImage() != 9)
{
int cnum = 0 ;
for(int n = -1; n <= 1; n ++)
{
r = i + n;
if(r >= 0 && r < mines.length)
for(int k = -1 ;k <=1; k ++)
{
c = j + k;
if(c >= 0 && c < mines[i].length)
{
if(mines[r][c].getImage() == 9)
cnum ++;
}
}
}
mines[i][j].setImage(cnum);
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int c = 0;
Graphics2D g2 = (Graphics2D) g;
for(int i = 0 ;i < mines.length; i ++)
for(int j = 0 ;j < mines[i].length; j ++)
{
g2.setColor(mines[i][j].getColor());
g2.draw(mines[i][j].getShape());
if(mines[i][j].getFlag() == true && mines[i][j].isOpen() == false)
g.drawImage(IMAGES.get(10),mines[i][j].getW(),mines[i][j].getH(),Mine.HEIGHT,Mine.WIDTH,this);
if(mines[i][j].isOpen()&& mines[i][j].getFlag() == false )
{
g.drawImage(IMAGES.get(mines[i][j].getImage()),mines[i][j].getW(),mines[i][j].getH() ,Mine.HEIGHT,Mine.WIDTH,this);
c ++;
}
}
f.remainMine.setText("剩余雷数:" + getHideMine() );
}
public void showMines()
{
removeAll();
for(int i = 0 ;i <mines.length; i ++)
for(int j = 0 ; j < mines[i].length; j ++)
{
if(mines[i][j].getImage() == 9)
{
if(mines[i][j].getFlag() == false)
mines[i][j].setOpen();
}
else
{
if(mines[i][j].getFlag() == true)
{
mines[i][j].setOpen();
mines[i][j].setFlag();
mines[i][j].setImage(11);
}
}
}
hideMine = 0;
repaint();
}
}
class Mine
{
private Rectangle2D rect = null;
public static final ImageIcon IMAGE = new ImageIcon("mine.gif");
public static final int HEIGHT = 20;
public static final int WIDTH = 20;
private boolean flag = false;
private boolean open = false;
public static final Color DEFAULT_COLOR = Color.BLACK;
private int image = 0;
private Color color;
private boolean isMine = false;
private int w,h;
public Mine(int r,int c)
{
this.w = r * HEIGHT;
this.h = c * HEIGHT;
rect = new Rectangle2D.Double(1.0D *r * HEIGHT,1.0D *c * WIDTH ,1.0D *HEIGHT,1.0D *WIDTH);
setColor(DEFAULT_COLOR);
}
public void setMine()
{
isMine = true;
}
public boolean isMine()
{
return isMine;
}
public void setColor(Color c)
{
this.color = c;
}
public Color getColor()
{
return color;
}
public void setOpen()
{
open = true;
}
public boolean isOpen()
{
return open;
}
public void setImage(int n)
{
image =n;
}
public int getImage()
{
return image;
}
public int getW()
{
return w;
}
public int getH()
{
return h;
}
public void setFlag()
{
flag = !flag;
}
public boolean getFlag()
{
return flag;
}
public Shape getShape()
{
return rect;
}
}
|