棋盘覆盖V1.0

      什么是棋盘覆盖, 棋盘覆盖是用4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格外的所有方格,且任何2个L型骨牌不得重叠覆盖。对,就这么简单!这是我在大学算法里面学分治算法时学的一个实例应用,正好为了学习这个算法以及练笔一下JAVA SWING(主要原因是为别人写的毕业设计),在大学期间弄的这么一个东西。
      首先贴一下最终结果图吧:

 1

从界面不难看出,有棋盘、棋盘上的方格、骨牌(4种)等。

 

1、棋盘(ChessPanel):棋盘用了一个JPanel来表示,而棋盘是由一个个的方格(ChessBox)组成的,这个方格将在下面讲到。ChessPanel中主要干的事情就是:

        A.初始化特殊方格:

 

       B.初始化棋盘;同上,这里写的时候有点重复代码,当时没有考虑到,刚看的时候发现,呵呵。

       C.实现paintComponent方法,画棋盘。这里也就是画线,由这些线分割成的方格就是棋盘,其中每个方格有自己的颜色属性等。

 

2、棋盘上的方格(ChessBox):就是上面用到的ChessBox,ChessBox里面没有上面逻辑代码,它只有几个属性:颜色、是否被覆盖、大小(这个多余,因为大小都一样了)。

 

3、骨牌(4种)(DominoPanel):这个类比较复杂,可能是设计不好的原因吧,这个类比较庞大,有快700行了。DominoPanel也是有ChessBox组成,一个DominoPanel有4个Chessbox组成,4种就需要4*4=16个ChessBox组成了。4种骨牌定义如下:

2

下面是构造一种形状的骨牌:通过style & key的与的结果来给骨牌(4个ChessBox)着色,得到最终的骨牌的样式。

 

      其次就是鼠标拖动骨牌的效果,这种效果很容易,添加当鼠标按下及鼠标拖动事件,当鼠标按下时记录此时鼠标的坐标x、y,当鼠标拖动此骨牌且并未松开鼠标时(即在拖动鼠标事件方法里),设置此骨牌位置如下(panel为骨牌的一个引用对象,骨牌类继承的是一个JPanel):
setLocation(panel.getX() + e.getX() - x, panel.getY() + e.getY() - y);
这样即可实现骨牌跟随着鼠标走的简单效果,然后在设置一下拖动时的外观,即可实现游戏中的效果,非常容易理解。

 

      然后就是实现DominoPanel的paintComponent方法:这里有一个拖动时的外观(有小边框)和其他情况时的外观。

 

        最后就是一些细节的处理,1、拖动骨牌(骨牌是一个JPanel,这个东西是方块),所以需要判断如果鼠标在颜色为null地方是拖不动的;2、只有鼠标在棋盘内部才显示边框;3、鼠标拖动骨牌在棋盘内部释放时,骨牌一定要放到正好用线条标好的4个ChessBox里的棋盘上,不能拖到哪放到哪,那样就是乱放了;4、排行榜的实现;5、错误提示;6、自动演示(自动演示时,直接用的直线方程让骨牌直线走到该走的位置的)等。这些请见代码,这里就不多说了。

 

        好了,从界面上看出来的东西也总结的差不多了,下面就是蛮重要的算法了,我认为算法可以优化,但是当时限于水平有限就没有再在这上面纠结了,希望大虾们可以帮俺看看,谢谢。算法就四个字:分而治之。懂了就懂了,不懂还是不懂。多说无益,算法如下(游戏中源码,未改动):主要在这里面做的事情就是记录正确的走法,定义一个HashMap来存储正确的走法(通过遍历棋盘覆盖主算法),其中Key存储手工走动时的左上角顶点,Value存储拖动的骨牌的样式(四种中的一种),这样即可实现当拖动骨牌时,根据存储过的走法(HashMap存储个人觉得非常合适,而且效率也非常不错,需要注意的是HashMap中的put方法的使用场合),判断走法是否正确,并给予相关提示,还有就是自动演示部分,这里用到的是Robot。

       

 

      算法部分总结就此打住,如果不明白的可以Google,我自己也是。下面是一个计时的东西,之前写的时候不知道JAVA里面有没有专门计时的,所以就自己用了一个Sleep做了这个计时,很简单,另起一个线程(防止界面卡住),在这个线程里面做的事情就是分、秒、毫秒的++操作,具体代码很容易。

 

      好了,基本差不多了,界面UI部分就不说了,全部JAVA SWING,因为现在工作了,用的是.net,SWING这方面也忘了差不多了,所以还需要复习一下才能那啥,哈哈。最后上几张图还是有必要的,有图有真相。实在的,虽然很简单的一个东西,写的时候还是考虑很多的细节部分的。

3

4

5
6

 

源码下载地址:http://download.csdn.net/source/2545075

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值