扫雷外挂的设计与实现(五)

缥缈星空a

缥缈星空a

2016-02-19 19:56

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的扫雷外挂的设计与实现(五)教程,一起来看看吧!超容易上手~

  如前所述,算法层的实现,不外乎两种操作:1。如果一个方块的数值等于周围未挖开的方块数目,则把周围所有方块标记为雷;2。如果一个方块的数值等于周围已经标记为雷的方块个数,则在该块上同时单击左右键。实际上,这只是最简单的两种判断(简单到甚至不该称之为“判断”,而只是例行公事而已),而比这更复杂的分析判断还可以有很多,但现在我们追求的是程序的简单易懂,而且,就这两种最简单的判断,已经可以达到很好的效果了,在实际中它们绝对占到了扫雷所用时间的一大多半。更高级的判断,在扫雷外挂的0.2版本里也已经实现了,但在此处若要加以叙述,不免还要大幅增加篇幅。

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  就来看这个最简单的算法:

  =================================================================

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  //根据Cells中的数据进行判断,把适当的操作填入Operations中
  procedure AnalyzeCells;
  var
    i, j: Integer;
    neighborCount: Integer;      //保存一个方块周围未挖开的方块的数目
  begin
    //首先清空输出缓冲区
    for i:=0 to AreaWidth-1 do
    for j:=0 to AreaHeight-1 do
      Operations[i, j] := opNone;
    //扫描输入缓冲区,执行两种最简单的判断
    for i:=0 to AreaWidth-1 do
    for j:=0 to AreaHeight-1 do
    begin
      //取得一个方块周围未挖开的方块的数目
      neighborCount := CountNeighbors(i, j, [csUnknown, csPossible]);
      //只有1~8的数字,并且周围存在未挖开的方块,这样的方块才有分析价值
      if (Cells[i, j]cs0) and (Cells[i, j]=cs8) and (neighborCount 0) then
        //第一种情况
        if neighborCount = Ord(Cells[i, j])-CountNeighbors(i, j, [csMarked]) then
          MarkAllNeighbors(i, j)
        //第二种情况
        else if Ord(Cells[i, j]) = CountNeighbors(i, j, [csMarked]) then
          Operations[i, j] := opBothClick;
    end;
  end;

  
  //将指定方块周围8个方块中,未挖开的,包括已标记问号的,都标记为雷。
  procedure MarkAllNeighbors(const x, y: Integer);
  var
    i,j: Integer;
  begin
    //扫描以某个坐标为中心的9个方块
    for i:=x-1 to x+1 do
    for j:=y-1 to y+1 do
    begin
      //去除中心块,并避免数组越界
      if ((i=x) and (j=y)) or (i0) or (i=AreaWidth) or (j0) or (j=AreaHeight) then
        Continue;
      //未挖开的空白则单击右键,未挖开的标问号的,则双击右键
      if Cells[i, j] = csUnknown then
          Operations[i, j] := opRightClick
      else if Cells[i, j] = csPossible then
          Operations[i, j] := opRightDoubleClick;
    end;
  end;

  
  //取得指定方块周围8个方块中等于任一个指定状态的方块的个数。
  function CountNeighbors(const x, y: Integer; const targetStates: TCellStates): Integer;
  var
    i,j: Integer;
  begin
    result := 0;
    //扫描以某个坐标为中心的9个方块
    for i:=x-1 to x+1 do
    for j:=y-1 to y+1 do
    begin
      //去除中心块,并避免数组越界
      if ((i=x) and (j=y)) or (i0) or (i=AreaWidth) or (j0) or (j=AreaHeight) then
        Continue;
      //计数指定状态的方块
      if Cells[i, j] in targetStates then
        Inc(result);
    end;
  end;
  =================================================================

  其中,由于枚举TCellState的常量位置的安排,Ord函数对cs0~cs8所取得的值正是0~8,即等于该方块的数值。这个算法可以算是中规中矩,没什么取巧的地方,因此应该不那么难懂。不错,至此扫雷外挂已经完全实现完毕。把上述所有函数和全局内容放在一个单元(可以是一个窗体)里,设好TTimer控件的间隔,就可以很理想的工作了。在外挂类程序的开发中,本例用到的也许是最“笨”的一种方法,但对于平面方格类游戏,其原理具有通用性。它不需对游戏底层数据、协议之类有什么了解,只需要了解游戏的屏幕图形就可以了。本例对于Windows窗口相关的某些API,也是一个较好的熟悉机会,对于初学者会有其意义。这个例子本身并不是最完善的,了解了思想,每个人自可以做出更加完善的程序。比如,应用钩子,这会大幅度减少该程序占用的系统资源。

  几天时间终于写完了这堆文章,希望能给适当的人带来适当的收益。欢迎交流,信箱:euth@163.com


展开更多 61%)
分享
qqQQ
qzoneQQ空间
weibo微博

猜你喜欢

扫雷外挂的设计与实现(五)

编程语言 网络编程
扫雷外挂的设计与实现(五)

扫雷外挂的设计与实现(一)

编程语言 网络编程
扫雷外挂的设计与实现(一)

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

扫雷外挂的设计与实现(二)

编程语言 网络编程
扫雷外挂的设计与实现(二)

扫雷外挂的设计与实现(四)

编程语言 网络编程
扫雷外挂的设计与实现(四)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

扫雷外挂的设计与实现(三)

编程语言 网络编程
扫雷外挂的设计与实现(三)

C# 游戏外挂实现核心代码

编程语言 网络编程
C# 游戏外挂实现核心代码

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

ORLAND.DATA.ORACLE不匹配错误

ORLAND.DATA.ORACLE不匹配错误

Dreamweaver CS3集成Spry效果试用

Dreamweaver CS3集成Spry效果试用
下拉加载更多内容 ↓