C#实现扫雷出炉
前阵子想用C#写个扫雷,检验一下学习一年多C#的功力如何。扫雷的基本实现很简单,动态生成控件,然后用Controls.Add添加到窗口中,用随机数布雷,处理Mouse事件...最麻烦的事情不过是在点到空白地带的时候需要实现一个FloodFill算法。
不过要实现一个十分接近Windows扫雷的版本,还是需要费一些周折的。首先需要找到资源文件,我是在百度知道上搜到的,或者从扫雷的资源文件里读取也可以。
其次,控件上的图像,要用gdi+画上去,如果使用picture_box去load image的话会很慢,点到大片空白的时候会有闪烁。
设计的时候也有一些技巧,把MineControl控件和Form的逻辑隔开,每个MineControl记录自己的状态,分别为: Initial(初始), Pressed(鼠标左键按住不放), Flag(插上小旗), QuestionMark(标记为问号), Unseal(翻开后) 。同时提供Press(), UnPress(), PutFlag(), Unseal() 这些操作。这样做的好处是,使原本复杂的判断变得简单,在Form中,只需要根据当前的鼠标事件调用这些操作即可,而这些操作本身会完成MineControl的状态转移,并显示出来。
鼠标的左右键处理也有些小技巧,好像以前在VB里,可以直接获得鼠标左右键当前的状态,用Mouse.Left|Mouse.Right来判断鼠标左右键同时按下的状况。但是C#的MouseDown事件中,只能知道当前鼠标按下的键是什么,因为每个键按下总有先后,在C#里,左右键同时按下会触发两次MouseDown事件。于是,需要设一个全局变量,记录鼠标左右键当前的状态。
最后,重写MineControl的Paint方法,用gdi+把icon画到窗口上。
附上源码
写本程序的时候参考了一下icebird的程序,附上链接:
http://www.cnblogs.com/Icebird/archive/2006/06/21/CSharpMine.html
这个实现比较完善,我的程序只实现了最基本的功能。不过自认为结构更清晰一些,欢迎大家拍砖~