国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

掃雷外掛的設計與實現(二)

2019-11-18 18:01:44
字體:
來源:轉載
供稿:網友

有了前述的數據,編寫接口層似乎已經不成問題了。現在來構思一下程序運行的過程。說句實話,那種對于某種變化實時作出響應的程序,一般都用什么方法編成,本人并不很了解,推測無非是兩種思想,一種是用一個線程不斷地對這個變化進行檢查,發現改變則動作;另一種是注冊一個類似于鉤子的東西,用回調函數來處理。無疑第二種方式要更節省系統資源,只是難在本人對Windows的鉤子掌握的還一塌糊涂。若換了個高手,無疑應該用這種方式,而我卻只有望著Spy++中迅速滾動的消息發呆的份。也許等我學好了鉤子之后,會寫個0.2版,而在0.1版中我已經決定了使用丑陋的反復檢查的方式。于是,用了一個TTimer控件,定時間隔設在了30左右,用它的OnTimer事件來進行一次檢查和反饋操作。時間間隔是反復試驗確定的,太小,會很占CPU,太大則反應會變慢。

這樣,運行過程已經確定下來:

OnTimer事件->判斷當前可否進行操作->取得整個雷區當前狀況->用算法進行分析->反饋操作

所謂不可進行操作的時候,無非是指:根本沒有掃雷窗口,或者窗口部分被遮擋(此時無法取得正確的像素值),或者掃雷游戲沒有開始。

在我的代碼中,OnTimer事件處理過程的核心就是如下簡單的幾句:

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

if GetMineWindow then
begin
    FetchCells;
    AnalyzeCells;
    OperateCells;
end;

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

其中:
GetMineWindow函數返回一個Boolean值,表示可否進行操作。如果可以,同時將關于掃雷窗口的一些參數存放進全局變量中。
FetchCells過程取得整個雷區所有方塊的信息,填入輸入緩沖區。
AnalyzeCells過程對輸入緩沖區中的數據進行分析,將反饋操作填入輸出緩沖區。
OperateCells過程根據輸出緩沖區中的數據對掃雷窗口進行反饋操作。

上述輸入緩沖區和輸出緩沖區,各是一個二維數組,直觀地對應了掃雷窗口上的每一個方塊。前者保存每個方塊的當前狀態供分析,后者保存分析完畢后,將要實施到每一個方塊的操作。雷區的寬和高都不是固定的,而這兩個二維數組,則無論何時都要能夠保存所有方塊的信息。這時有兩個選擇,一是定義足以容下最大情況的靜態數組,二是使用動態數組。為了簡單,我采用了前者,畢竟最大情況也不是大得難以忍受。這樣,還需要一對整型變量保存實際雷區的寬和高。

現在可以來看一下全部需要的全局常量,變量和類型:

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

const
  MINE_WINDOW_TITLE = '掃雷';     //窗口標題,供尋找掃雷窗口用

  //以下四個,為雷區四邊到窗口客戶區四邊的距離
  TOP_MARGIN = 55;                //上邊距
  BOTTOM_MARGIN = 8;              //下邊距
  LEFT_MARGIN = 12;               //左邊距
  RIGHT_MARGIN = 8;               //右邊距

  CELL_WIDTH = 16;                //每個方塊寬度
  CELL_HEIGHT = 16;               //每個方塊高度

  MAX_COLUMN_COUNT = 30;          //雷區最大可能的列數
  MAX_ROW_COUNT = 24;             //雷區最大可能的行數

type
  //每個方塊的可能狀態,包括0~8的數字(0不顯示),未知的,已插旗標記為雷的,和標記問號的
  TCellState = (cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, cs8, csUnknown, csMarked, csPossible);

  //TCellState的集合類型,供分析算法使用
  TCellStates = set of TCellState;

  //對每個方塊的操作種類,包括無操作,左鍵單擊,右鍵單擊,左右鍵同時單擊,和右鍵雙擊(用于將問號標記成旗)
  TOperation = (opNone, opLeftClick, oPRightClick, opBothClick, opRightDoubleClick);

var
  MineWnd: HWND;                  //保存掃雷窗口的句柄
  MineDC: HDC;                    //保存掃雷窗口的設備上下文

  //雷區的實際寬度和高度(方塊數)
  AreaWidth: Integer
  AreaHeight: Integer;

  //輸入緩沖區
  Cells: array[0..MAX_COLUMN_COUNT-1, 0..MAX_ROW_COUNT-1] of TCellState;

  //輸出緩沖區
  Operations: array[0..MAX_COLUMN_COUNT-1, 0..MAX_ROW_COUNT-1] of TOperation;

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


上一篇:從DBGrid,StringGrid導出Excel

下一篇:關于SQLDMO的使用

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 襄城县| 罗平县| 云安县| 东乌珠穆沁旗| 金山区| 台北县| 正蓝旗| 长治市| 岳普湖县| 浙江省| 伊川县| 通化市| 青神县| 桓台县| 富阳市| 正镶白旗| 吐鲁番市| 监利县| 古丈县| 和田市| 盐池县| 兴仁县| 隆子县| 武冈市| 惠安县| 湖州市| 治多县| 吴江市| 安新县| 铅山县| 阜平县| 岳西县| 永昌县| 崇阳县| 云梦县| 墨玉县| 黄龙县| 富源县| 英吉沙县| 台北市| 怀远县|