免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3967 | 回复: 5
打印 上一主题 下一主题

swing练习系列2 -- Mine挖雷(源代码) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-19 09:58 |只看该作者 |倒序浏览
包含部分注释。
这段代码比较粗糙,只包含简单挖雷游戏规则。
操作:
1,点“开始”后开始。
2,左键点击未知区域,则作为无雷展开。
3。右键点击未知区域,标记有雷。
4。左键点击已知无雷区,则辅助计算周围情况。(简单情形)

有兴趣的可以C&P测试下,Thanks for any comment!


  1. /*
  2. * Created on 2006-6-2
  3. *
  4. */
  5. package com.ftinternet;

  6. import java.awt.BorderLayout;
  7. import java.awt.Color;
  8. import java.awt.FlowLayout;
  9. import java.awt.GridLayout;
  10. import java.awt.Point;
  11. import java.awt.event.MouseAdapter;
  12. import java.awt.event.MouseEvent;
  13. import java.util.HashMap;
  14. import java.util.Random;

  15. import javax.swing.JButton;
  16. import javax.swing.JFrame;
  17. import javax.swing.JLabel;
  18. import javax.swing.JPanel;

  19. /**
  20. * @author 色到压根儿疼
  21. *
  22. * TODO To change the template for this generated type comment go to
  23. * Window - Preferences - Java - Code Style - Code Templates
  24. */

  25. class MineButton extends JButton {
  26.        
  27.         private static final long serialVersionUID = -2004966127695755657L;

  28.         public static final int MINE_BUTTON_WIDTH = 220;
  29.         public static final boolean MINESTATUS_MINED        = true;
  30.         public static final boolean MINESTATUS_ACTIVE        = false;
  31.        
  32.         private int XPos = 0;
  33.         private int YPos = 0;
  34.         public boolean MineStatus = MINESTATUS_ACTIVE;
  35.         private int MineCount = -1;
  36.         private boolean Suspected = false;
  37.        
  38.         public MineButton(int XPos, int YPos) {
  39.                 this.XPos = XPos;
  40.                 this.YPos = YPos;
  41.                
  42.                 setSize(MINE_BUTTON_WIDTH, MINE_BUTTON_WIDTH);
  43.                 SetSuspected(false);
  44.         }
  45.        
  46.         public int GetXPos() { return XPos; }
  47.         public int GetYPos() { return YPos; }
  48.        
  49.         public boolean IsSuspected()
  50.         {
  51.                 return Suspected;
  52.         }

  53.         public void SetSuspected(boolean IsSuspect)
  54.         {
  55.                 Suspected = IsSuspect;
  56.                 if (!Suspected) setText("   ");
  57.                 else setText("x");
  58.         }
  59.        
  60.         public boolean IsMined() {
  61.                 return MineStatus == MINESTATUS_MINED;
  62.         }
  63.        
  64.         public void SetMine() {
  65.                 MineStatus = MINESTATUS_MINED;
  66.         }
  67.        
  68.         public void Reset() {
  69.                 MineStatus = MINESTATUS_ACTIVE;
  70.                 SetSuspected(false);
  71.                 MineCount = -1;
  72.                 setBackground(Color.lightGray);
  73.                 setForeground(Color.black);
  74.         }
  75.        
  76.         public void setMineCount(int mine) {
  77.                 MineCount = mine;
  78.                 setBackground(Color.white);
  79.                 switch (MineCount)
  80.                 {
  81.                 case 1:
  82.                         setForeground(Color.blue);
  83.                         break;
  84.                 case 2:
  85.                         setForeground(Color.green);
  86.                         break;
  87.                 case 3:
  88.                         setForeground(Color.darkGray);
  89.                         break;
  90.                 case 4:
  91.                         setForeground(Color.cyan);
  92.                         break;
  93.                 case 5:
  94.                         setForeground(Color.magenta);
  95.                         break;
  96.                 case 6:
  97.                         setForeground(Color.orange);
  98.                         break;
  99.                 case 7:
  100.                         setForeground(Color.red);
  101.                         break;
  102.                 }
  103.         }
  104.        
  105.         public int getMineCount() { return MineCount; }
  106. }

  107. public class TestMine extends JFrame {
  108.         private static final long serialVersionUID = -3295523726245939815L;

  109.         private static Point[] AroundPoint = {
  110.                 new Point(-1, -1), new Point(0, -1), new Point(1, -1),
  111.                 new Point(-1,  0),                   new Point(1,  0),
  112.                 new Point(-1,  1), new Point(0,  1), new Point(1,  1)
  113.         };

  114.         private HashMap<String, MineButton> MineList = new HashMap<String, MineButton>();
  115.         private int MineMapWidth = 0;
  116.         private int MineMapHeight = 0;
  117.         private int MineMapCount = 0;
  118.         private boolean GameActive = false;
  119.        
  120.         JPanel pnlControl = new JPanel();
  121.         JPanel pnlView = new JPanel();
  122.         JLabel lbMineLeft = new JLabel("");
  123.         JLabel lbMineOver = new JLabel("Game Over");
  124.        
  125.         private String GetMineCode(int width, int height)
  126.         {
  127.                 return "M" + width + "-" + height;
  128.         }
  129.        
  130.         private MineButton GetMineButton(int XPos, int YPos)
  131.         {
  132.                 if (MineList.containsKey(GetMineCode(XPos, YPos)))
  133.                         return (MineButton) MineList.get(GetMineCode(XPos, YPos));
  134.                 else
  135.                         return null;
  136.         }
  137.        
  138.         private MineButton GetMineButton(int Index) {
  139.                 return GetMineButton(Index % MineMapWidth, Index / MineMapWidth);
  140.         }
  141.        
  142.         private void ResetMineMap()
  143.         {
  144.                 for (int i = 0; i < MineMapWidth * MineMapHeight; i++)
  145.                         GetMineButton(i).Reset();
  146.         }
  147.        
  148.         private void InitMineMap()
  149.         {
  150.                 Random rand = new Random();
  151.                
  152.                 int rCount = MineMapCount;
  153.                 ResetMineMap();
  154.                 while (rCount > 0)
  155.                 {
  156.                         int rPos = rand.nextInt(MineMapWidth * MineMapHeight);
  157.                         MineButton mbTemp = GetMineButton(rPos);
  158.                         if ((mbTemp == null) || mbTemp.IsMined()) continue;
  159.                         mbTemp.SetMine();
  160.                        
  161.                         rCount--;
  162.                 }
  163.                
  164.                 lbMineLeft.setText("" + MineMapCount);
  165.                 GameActive = true;
  166.                 pnlView.setEnabled(true);
  167.                 lbMineOver.setVisible(false);
  168.         }
  169.        
  170.         private void GameOver(boolean Active)
  171.         {
  172.                 GameActive = false;
  173.                 pnlView.setEnabled(false);
  174.                
  175.                 if (Active) lbMineOver.setForeground(Color.green);
  176.                 else lbMineOver.setForeground(Color.red);
  177.                 lbMineOver.setVisible(true);
  178.                
  179.                 repaint();
  180.         }
  181.        
  182.         /**
  183.          * 检查mbTemp1,mbTemp2是否相邻
  184.          * @param mbTemp1
  185.          * @param mbTemp2
  186.          * @return
  187.          */
  188.         protected boolean IsNeighbor(MineButton mbTemp1, MineButton mbTemp2) {
  189.                 return (mbTemp1 != null) && (mbTemp2 != null)
  190.                 && Math.abs(mbTemp1.GetXPos() - mbTemp2.GetXPos()) + Math.abs(mbTemp1.GetYPos()  - mbTemp1.GetYPos()) == 1;
  191.         }
  192.        
  193.         /**
  194.          * 检查mbTemp1是否在mbTemp2在周围
  195.          * @param mbTemp1
  196.          * @param mbTemp2
  197.          * @return
  198.          */
  199.         protected boolean IsAround(MineButton mbTemp1, MineButton mbTemp2) {
  200.                 return (mbTemp1 != null) && (mbTemp2 != null)
  201.                 && (Math.abs(mbTemp1.GetXPos() - mbTemp2.GetXPos()) < 2) && (Math.abs(mbTemp1.GetYPos() - mbTemp2.GetYPos()) < 2);
  202.         }

  203.         private boolean CheckPosition(int XPos, int YPos)
  204.         {
  205.                 MineButton mbMine = GetMineButton(XPos, YPos);
  206.                 return ((mbMine != null) && mbMine.IsMined());
  207.         }
  208.        
  209.         private int GetMineAround(int XPos, int YPos)
  210.         {
  211.                 int Mines = 0;

  212.                 for (int i = 0; i < AroundPoint.length; i++)
  213.                         if (CheckPosition(XPos + AroundPoint[i].x, YPos + AroundPoint[i].y)) Mines++;
  214.                
  215.                 return Mines;
  216.         }
  217.        
  218.         /**
  219.          * 从(XPos, YPos)向周围扩展
  220.          * @param XPos
  221.          * @param YPos
  222.          */
  223.         private void ExplorMine(int XPos, int YPos)
  224.         {
  225.                 MineButton mbMine = GetMineButton(XPos, YPos);
  226.                 if ((mbMine == null) || (mbMine.getMineCount() > -1) || mbMine.IsSuspected()) return;
  227.                
  228.                 mbMine.setMineCount(GetMineAround(XPos, YPos));
  229.                 if (mbMine.getMineCount() > 0)
  230.                         mbMine.setText("" + mbMine.getMineCount());
  231.                 else {
  232.                         for (int i = 0; i < AroundPoint.length; i++)
  233.                                 ExplorMine(XPos + AroundPoint[i].x, YPos + AroundPoint[i].y);
  234.                 }
  235.         }
  236.        
  237.         /**
  238.          * 统计点(XPos, YPos)周围的情况
  239.          * @param XPos
  240.          * @param YPos
  241.          * @return Point.x 周围的嫌疑个数,Point.y周围的未知个数
  242.          */
  243.         private void CheckSuspectPosition(int XPos, int YPos, Point info)
  244.         {
  245.                 MineButton mbTemp = GetMineButton(XPos, YPos);
  246.                 if (mbTemp == null) return;
  247.                
  248.                 if (mbTemp.IsSuspected()) info.x++;
  249.                 else if (mbTemp.getMineCount() < 0) info.y++;
  250.         }

  251.         private Point CalculatePositionAround(int XPos, int YPos)
  252.         {
  253.                 Point around = new Point();
  254.                
  255.                 for (int i = 0; i < AroundPoint.length; i++)
  256.                         CheckSuspectPosition(XPos + AroundPoint[i].x, YPos + AroundPoint[i].y, around);
  257.                 return around;
  258.         }
  259.        
  260.         /**
  261.          * 从(XPos, YPos)处展开周围所有未探测的点都被认为非雷
  262.          * @param XPos
  263.          * @param YPos
  264.          */
  265.         private void FlashPosition(int XPos, int YPos)
  266.         {
  267.                 MineButton mbTemp = GetMineButton(XPos, YPos);
  268.                 if ((mbTemp == null) || mbTemp.IsSuspected()) return;
  269.                
  270.                 if (mbTemp.getMineCount() < 0) {
  271.                         if (mbTemp.IsMined())
  272.                         {
  273.                                 mbTemp.setText("x");
  274.                                 mbTemp.setBackground(Color.RED);
  275.                                 GameOver(false);
  276.                         }
  277.                         else
  278.                                 ExplorMine(XPos, YPos);
  279.                 }
  280.         }
  281.        
  282.         /**
  283.          * see also FlashPosition(int XPos, int YPos)
  284.          * @param mbSender
  285.          */
  286.         private void FlashPositionAround(MineButton mbSender)
  287.         {
  288.                 FlashPositionAround(mbSender.GetXPos(), mbSender.GetYPos());
  289.         }
  290.        
  291.         private void FlashPositionAround(int XPos, int YPos)
  292.         {
  293.                 for (int i = 0; i < AroundPoint.length; i++)
  294.                         FlashPosition(XPos + AroundPoint[i].x, YPos + AroundPoint[i].y);
  295.         }
  296.        

  297.         private void CalculatePosition(MineButton mbSender)
  298.         {
  299.                 /**
  300.                  *  计算(XPos, YPos) 附近雷的情况
  301.                  */
  302.                 if (mbSender == null) return;
  303.                
  304.                 Point around = CalculatePositionAround(mbSender.GetXPos(), mbSender.GetYPos());
  305.                
  306.                 /** (XPos, YPos)周围雷已全部发现 */
  307.                 if (around.x == mbSender.getMineCount())
  308.                         FlashPositionAround(mbSender);
  309.         }
  310.        
  311.         private boolean FindAllMine() {
  312.                 int safemines = 0;
  313.                 for (int i = 0; i < MineMapWidth * MineMapHeight; i++)
  314.                         if (GetMineButton(i).getMineCount() > -1) safemines++;
  315.                 return (safemines + MineMapCount) == MineMapWidth * MineMapHeight;
  316.         }
  317.                
  318.         public TestMine() {
  319.                 this(9, 9, 10);
  320.         }
  321.        
  322.         public TestMine(int Width, int Height, int Mines) {
  323.                 setDefaultCloseOperation(EXIT_ON_CLOSE);
  324.                
  325.                 MineMapWidth = Width < 9 ? 9 : Width;
  326.                 MineMapHeight = Height < 9 ? 9 : Height;
  327.                 MineMapCount = 2 * Mines > MineMapWidth * MineMapHeight
  328.                                         ? MineMapWidth * MineMapHeight / 2
  329.                                         : Mines;
  330.                
  331.                 getContentPane().add(pnlControl, BorderLayout.NORTH);
  332.                 pnlControl.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 2));
  333.                
  334.                 JButton bRestart = new JButton("开 始");
  335.                 pnlControl.add(lbMineLeft);
  336.                
  337.                 bRestart.addMouseListener(new MouseAdapter() {
  338.                         public void mouseClicked(MouseEvent ae) {
  339.                                 InitMineMap();
  340.                         }
  341.                         });
  342.                 pnlControl.add(bRestart);
  343.                 pnlControl.add(lbMineOver);
  344.                
  345.                 pnlView.setSize(MineButton.MINE_BUTTON_WIDTH * MineMapWidth, MineButton.MINE_BUTTON_WIDTH * MineMapHeight);
  346.                 getContentPane().add(pnlView, BorderLayout.CENTER);
  347.                 pnlView.setLayout(new GridLayout(MineMapHeight, MineMapWidth));
  348.                
  349.                 for (int h = 0; h < MineMapHeight; h++)
  350.                         for (int w = 0; w < MineMapWidth; w++)
  351.                         {
  352.                                 MineButton mbMine = new MineButton(w, h);
  353.                                 pnlView.add(mbMine);
  354.                                 MineList.put(GetMineCode(w, h), mbMine);
  355.                                 mbMine.addMouseListener(new MouseAdapter() {
  356.                                                 public void mouseClicked(MouseEvent ae) {
  357.                                                         if (!GameActive) return;
  358.                                                         MineButton mbSender = (MineButton) ae.getSource();
  359.                                                        
  360.                                                         if (ae.getButton() == MouseEvent.BUTTON1) {
  361.                                                                 if (mbSender.IsSuspected()) return;
  362.                                                                 if (mbSender.getMineCount() != -1) {
  363.                                                                         CalculatePosition(mbSender);
  364.                                                                 }
  365.                                                                 else if (mbSender.IsMined()) {
  366.                                                                         mbSender.setText("x");
  367.                                                                         mbSender.setBackground(Color.RED);
  368.                                                                         GameOver(false);
  369.                                                                         return;
  370.                                                                 }
  371.                                                                 else
  372.                                                                         ExplorMine(mbSender.GetXPos(), mbSender.GetYPos());
  373.                                                         }
  374.                                                        
  375.                                                         if (ae.getButton() == MouseEvent.BUTTON3) {
  376.                                                                 if (mbSender.getMineCount() > -1) return;
  377.                                                                
  378.                                                                 mbSender.SetSuspected(!mbSender.IsSuspected());
  379.                                                                 if (mbSender.IsSuspected())
  380.                                                                         lbMineLeft.setText("" + (Integer.parseInt(lbMineLeft.getText()) - 1));
  381.                                                                 else
  382.                                                                         lbMineLeft.setText("" + (Integer.parseInt(lbMineLeft.getText()) + 1));
  383.                                                         }
  384.                                                         if (FindAllMine()) GameOver(true);
  385.                                                 }
  386.                                         });
  387.                         }
  388.                
  389.                 InitMineMap();
  390.                
  391.                 this.setTitle("扫雷:雷区----" + MineMapWidth + "x" + MineMapHeight + ":" + MineMapCount);
  392.                 pack();
  393.         }
  394.        
  395.         public static void main(String[] args) {
  396.                 TestMine tm = new TestMine(9, 9, 10);
  397.                 tm.setVisible(true);
  398.         }
  399. }

复制代码

论坛徽章:
1
天秤座
日期:2013-11-07 18:39:20
2 [报告]
发表于 2007-07-19 10:05 |只看该作者
不错,就是在Eclipse下跑,有的地方有些乱码。

论坛徽章:
0
3 [报告]
发表于 2007-07-19 16:54 |只看该作者
汉字?注释?

有可能是C&P时的问题。

论坛徽章:
1
天秤座
日期:2013-11-07 18:39:20
4 [报告]
发表于 2007-07-19 17:21 |只看该作者
是题头处的两个文字,显示为??

论坛徽章:
0
5 [报告]
发表于 2007-10-28 01:21 |只看该作者
改 那個aroundpoint 到aroundpoint 就好了, 改code也不行... 我怕你路還是很長.

论坛徽章:
0
6 [报告]
发表于 2007-10-30 20:03 |只看该作者
没有乱码^_^
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP