Python制作安卓游戲外掛

最近在玩一款背單詞的手機(jī)游戲-單詞英雄合冀,是一個(gè)將背單詞和卡牌游戲相結(jié)合的游戲,通過(guò)選擇正確的單詞意思進(jìn)行有效攻擊项贺,邊玩游戲就把單詞給背了君躺。
  游戲的界面是這樣的:

Paste_Image.png

  通過(guò)選擇單詞的意思進(jìn)行攻擊,選對(duì)了就正常攻擊开缎,選錯(cuò)了就象征性的攻擊一下棕叫。玩了一段時(shí)間之后琢磨可以做成自動(dòng)的,通過(guò)PIL識(shí)別圖片里的單詞和選項(xiàng)奕删,然后翻譯英文成中文意思俺泣,根據(jù)中文模糊匹配選擇對(duì)應(yīng)的選項(xiàng)。
  查找了N多資料以后開(kāi)始動(dòng)手,程序用到以下這些東西:
PIL       Python Imaging Library 大名鼎鼎的圖片處理模塊
pytesser     Python下用來(lái)驅(qū)動(dòng)tesseract-ocr來(lái)進(jìn)行識(shí)別的模塊
Tesseract-OCR  圖像識(shí)別引擎伏钠,用來(lái)把圖像識(shí)別成文字横漏,可以識(shí)別英文和中文,以及其它語(yǔ)言
autopy     Python下用來(lái)模擬操作鼠標(biāo)和鍵盤(pán)的模塊熟掂。

安裝步驟(win7環(huán)境):
  (1)安裝PIL缎浇,下載地址:http://www.pythonware.com/products/pil/,安裝Python Imaging Library 1.1.7 for Python 2.7赴肚。
  (2)安裝pytesser素跺,下載地址:http://code.google.com/p/pytesser/,下載解壓后直接放在
C:\Python27\Lib\site-packages下,在文件夾下建立pytesser.pth文件誉券,內(nèi)容為C:\Python27\Lib\site-packages\pytesser_v0.0.1
  (3)安裝Tesseract OCR engine指厌,下載:https://github.com/tesseract-ocr/tesseract/wiki/Downloads,下載Windows installer of tesseract-ocr 3.02.02 (including English language data)的安裝文件横朋,進(jìn)行安裝仑乌。
  (4)安裝語(yǔ)言包百拓,在https://github.com/tesseract-ocr/tessdata下載chi_sim.traineddata簡(jiǎn)體中文語(yǔ)言包琴锭,放到安裝的Tesseract OCR目標(biāo)下的tessdata文件夾內(nèi),用來(lái)識(shí)別簡(jiǎn)體中文衙传。
  (5)修改C:\Python27\Lib\site-packages\pytesser_v0.0.1下的pytesser.py的函數(shù)决帖,將原來(lái)的image_to_string函數(shù)增加語(yǔ)音選擇參數(shù)language,language='chi_sim'就可以用來(lái)識(shí)別中文蓖捶,默認(rèn)為eng英文地回。
改好后的pytesser.py:

"""OCR in Python using the Tesseract engine from Google
http://code.google.com/p/pytesser/
by Michael J.T. O'Kelly
V 0.0.1, 3/10/07"""

import Image
import subprocess
import util
import errors

tesseract_exe_name = 'tesseract' # Name of executable to be called at command line
scratch_image_name = "temp.bmp" # This file must be .bmp or other Tesseract-compatible format
scratch_text_name_root = "temp" # Leave out the .txt extension
cleanup_scratch_flag = True  # Temporary files cleaned up after OCR operation

def call_tesseract(input_filename, output_filename, language):
  """Calls external tesseract.exe on input file (restrictions on types),
  outputting output_filename+'txt'"""
  args = [tesseract_exe_name, input_filename, output_filename, "-l", language]
  proc = subprocess.Popen(args)
  retcode = proc.wait()
  if retcode!=0:
    errors.check_for_errors()

def image_to_string(im, cleanup = cleanup_scratch_flag, language = "eng"):
  """Converts im to file, applies tesseract, and fetches resulting text.
  If cleanup=True, delete scratch files after operation."""
  try:
    util.image_to_scratch(im, scratch_image_name)
    call_tesseract(scratch_image_name, scratch_text_name_root,language)
    text = util.retrieve_text(scratch_text_name_root)
  finally:
    if cleanup:
      util.perform_cleanup(scratch_image_name, scratch_text_name_root)
  return text

def image_file_to_string(filename, cleanup = cleanup_scratch_flag, graceful_errors=True, language = "eng"):
  """Applies tesseract to filename; or, if image is incompatible and graceful_errors=True,
  converts to compatible format and then applies tesseract.  Fetches resulting text.
  If cleanup=True, delete scratch files after operation."""
  try:
    try:
      call_tesseract(filename, scratch_text_name_root, language)
      text = util.retrieve_text(scratch_text_name_root)
    except errors.Tesser_General_Exception:
      if graceful_errors:
        im = Image.open(filename)
        text = image_to_string(im, cleanup)
      else:
        raise
  finally:
    if cleanup:
      util.perform_cleanup(scratch_image_name, scratch_text_name_root)
  return text
  

if __name__=='__main__':
  im = Image.open('phototest.tif')
  text = image_to_string(im)
  print text
  try:
    text = image_file_to_string('fnord.tif', graceful_errors=False)
  except errors.Tesser_General_Exception, value:
    print "fnord.tif is incompatible filetype.  Try graceful_errors=True"
    print value
  text = image_file_to_string('fnord.tif', graceful_errors=True)
  print "fnord.tif contents:", text
  text = image_file_to_string('fonts_test.png', graceful_errors=True)
  print text

(6)安裝autopy,下載地址:https://pypi.python.org/pypi/autopy俊鱼,下載autopy-0.51.win32-py2.7.exe進(jìn)行安裝刻像,用來(lái)模擬鼠標(biāo)操作。

說(shuō)下程序的思路:
 1. 首先是通過(guò)模擬器在WINDOWS下執(zhí)行安卓的程序并闲,然后用PicPick進(jìn)行截圖细睡,將戰(zhàn)斗畫(huà)面中需要用到的區(qū)域進(jìn)行測(cè)量,記錄下具體在屏幕上的位置區(qū)域帝火,用圖中1來(lái)判斷戰(zhàn)斗是否開(kāi)始(保存下來(lái)用作比對(duì))溜徙,用2,3犀填,4蠢壹,5,6的區(qū)域抓取識(shí)別成文字九巡。

1485005-75900c16b01ca1f3.png

計(jì)算圖片指紋的程序:

    def get_hash(self, img):
        #計(jì)算圖片的hash值
        image = img.convert("L")
        pixels = list(image.getdata())
        avg = sum(pixels) / len(pixels)
        return "".join(map(lambda p : "1" if p > avg else "0", pixels))

圖片識(shí)別成字符:

    #識(shí)別出對(duì)應(yīng)位置圖像成字符图贸,把字符交給chose處理
    def getWordMeaning(self):
        pic_up = ImageGrab.grab((480,350, 480+300, 350+66))
        pic_aws1 = ImageGrab.grab((463,456, 463+362, 456+45))
        pic_aws2 = ImageGrab.grab((463,530, 463+362, 530+45))
        pic_aws3 = ImageGrab.grab((463,601, 463+362, 601+45))
        pic_aws4 = ImageGrab.grab((463,673, 463+362, 673+45))
        
        str_up = image_to_string(pic_up).strip().lower()
        
        #判斷當(dāng)前單詞和上次識(shí)別單詞相同,就不繼續(xù)識(shí)別
        if str_up <> self.lastWord:
            #如果題目單詞是英文,選項(xiàng)按中文進(jìn)行識(shí)別
            if str_up.isalpha():
                eng_up = self.dt[str_up].decode('gbk') if self.dt.has_key(str_up) else ''
                chs1 = image_to_string(pic_aws1, language='chi_sim').decode('utf-8').strip()
                chs2 = image_to_string(pic_aws2, language='chi_sim').decode('utf-8').strip()
                chs3 = image_to_string(pic_aws3, language='chi_sim').decode('utf-8').strip()
                chs4 = image_to_string(pic_aws4, language='chi_sim').decode('utf-8').strip()
                print str_up, ':', eng_up
                self.chose(eng_up, (chs1, chs2, chs3, chs4))
            #如果題目單詞是中文疏日,選項(xiàng)按英文進(jìn)行識(shí)別
            else:
                chs_up = image_to_string(pic_up, language='chi_sim').decode('utf-8').strip()
                eng1 = image_to_string(pic_aws1).strip()
                eng2 = image_to_string(pic_aws2).strip()
                eng3 = image_to_string(pic_aws3).strip()
                eng4 = image_to_string(pic_aws4).strip()
                
                e2c1 = self.dt[eng1].decode('gbk') if self.dt.has_key(eng1) else ''
                e2c2 = self.dt[eng2].decode('gbk') if self.dt.has_key(eng2) else ''
                e2c3 = self.dt[eng3].decode('gbk') if self.dt.has_key(eng3) else ''
                e2c4 = self.dt[eng4].decode('gbk') if self.dt.has_key(eng4) else ''
                print chs_up
                self.chose(chs_up, (e2c1, e2c2, e2c3, e2c4))
            self.lastWord = str_up
        return str_up

2. 對(duì)于1位置的圖片提前截一個(gè)保存下來(lái)乏盐,然后通過(guò)計(jì)算當(dāng)前畫(huà)面和保存下來(lái)的圖片的距離,判斷如果小于40的就表示已經(jīng)到了選擇界面制恍,然后識(shí)別2父能,3,4净神,5何吝,6成字符,判斷如果2位置識(shí)別成英文字符的鹃唯,就用2解析出來(lái)的英文在字典中獲取中文意思爱榕,然后再通過(guò)2的中文意思和3,4坡慌,5黔酥,6文字進(jìn)行匹配,匹配上漢字最多的就做選擇洪橘,如果匹配不上默認(rèn)返回最后一個(gè)跪者。之前本來(lái)考慮是用Fuzzywuzzy來(lái)進(jìn)行模糊匹配算相似度的,不過(guò)后來(lái)測(cè)試了下對(duì)于中文匹配的效果不好熄求,就改成按漢字單個(gè)進(jìn)行匹配計(jì)算相似度渣玲。
匹配文字進(jìn)行選擇:

    #根據(jù)傳入的題目和選項(xiàng)進(jìn)行匹配選擇
    def chose(self, g, chs_list):
        j, max_score = -1, 0
        same_list = None
        #替換掉題目里的特殊字符
        re_list = [u'~', u',', u'.', u';', u' ', u'a', u'V', u'v', u'i', u'n', u'【', u')', u'_', u'W', u'd', u'j', u'-', u't']
        for i in re_list:
            g = g.replace(i, '')
        print type(g)
        
        #判斷2個(gè)字符串中相同字符,相同字符最多的為最佳答案
        for i, chsWord in enumerate(chs_list):
            print type(chsWord)
            l = [x for x in g if x in chsWord and len(x)>0]
            score = len(l) if l else 0
            
            if score > max_score:
                max_score = score
                j = i
                same_list = l
        #如果沒(méi)有匹配上默認(rèn)選最后一個(gè)
        if j ==-1:
            print '1. %s; 2. %s; 3. %s; 4. %s; Not found choice.' % (chs_list[0], chs_list[1], chs_list[2], chs_list[3])
        else:
            print '1. %s; 2. %s; 3. %s; 4. %s; choice: %s' % (chs_list[0], chs_list[1], chs_list[2], chs_list[3], chs_list[j])
            for k, v in enumerate(same_list):
                print str(k) + '.' + v,
        order = j + 1
        self.mouseMove(order)
        return order

3.最后通過(guò)mouseMove調(diào)用autopy操作鼠標(biāo)點(diǎn)擊對(duì)應(yīng)位置進(jìn)行選擇弟晚。
程序運(yùn)行的錄像:
http://v.youku.com/v_show/id_XMTYxNTAzMDUwNA==.html
  程序完成后使用正常忘衍,因?yàn)閳D片識(shí)別準(zhǔn)確率和字典的問(wèn)題,正確率約為70%左右卿城,效果還是比較滿意枚钓。程序總體來(lái)說(shuō)比較簡(jiǎn)單,做出來(lái)也就是純粹娛樂(lè)一下瑟押,串聯(lián)使用了圖片識(shí)別搀捷、中文模糊匹配、鼠標(biāo)模擬操作勉耀,算是個(gè)簡(jiǎn)單的小外掛吧指煎,源程序和用到的文件如下:
http://git.oschina.net/highroom/My-Project/tree/master/Word%20Hero

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市便斥,隨后出現(xiàn)的幾起案子至壤,更是在濱河造成了極大的恐慌,老刑警劉巖枢纠,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件像街,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)镰绎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)脓斩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人畴栖,你說(shuō)我怎么就攤上這事随静。” “怎么了吗讶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵燎猛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我照皆,道長(zhǎng)重绷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任膜毁,我火速辦了婚禮昭卓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瘟滨。我一直安慰自己候醒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布室奏。 她就那樣靜靜地躺著火焰,像睡著了一般劲装。 火紅的嫁衣襯著肌膚如雪胧沫。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天占业,我揣著相機(jī)與錄音绒怨,去河邊找鬼。 笑死谦疾,一個(gè)胖子當(dāng)著我的面吹牛南蹂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播念恍,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼六剥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了峰伙?” 一聲冷哼從身側(cè)響起疗疟,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞳氓,沒(méi)想到半個(gè)月后策彤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年店诗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裹刮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庞瘸,死狀恐怖捧弃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情擦囊,我是刑警寧澤塔橡,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站霜第,受9級(jí)特大地震影響葛家,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泌类,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一癞谒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刃榨,春花似錦弹砚、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至苞轿,卻和暖如春茅诱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搬卒。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工瑟俭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人契邀。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓摆寄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親坯门。 傳聞我的和親對(duì)象是個(gè)殘疾皇子微饥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容