Android-數(shù)獨世界自動完成標(biāo)準(zhǔn)數(shù)獨的小腳本

最近從GP上翻出了之前玩的一款消磨時間的游戲“數(shù)獨世界” --le.lenovo.sudoku,登陸了GP賬號發(fā)現(xiàn)已經(jīng)取得了一些成就,但之前的記錄沒了,得從新開始玩。懶得費力的去重復(fù)完成之前關(guān)卡,于是想著怎么能自動填充數(shù)獨。

抱著試一試的態(tài)度,開始了研究。

一、反編譯

這款app做了混淆處理,和一些簡單的防反編譯的措施。正常的工具會失敗,得使用強力的反編譯工具才行。

1、去廣告

廣告挺多的,從splash activity、ResumeGameActivity、SudokuActivity等頁面都有廣告。查看了一下,是使用的Android原生廣告,并且程序打印了廣告的一些log出來。順著log可以找到關(guān)鍵地方,然后禁用掉。在AndroidManifest.xml中,也可以看到廣告activity的聲明,直接刪掉就好了。剩下可能殘留一些banner廣告,暫時留著吧,也給開發(fā)者留點收入。

2、分析頁面布局

游戲的主頁面是SudokuActivity,查看布局發(fā)現(xiàn),棋盤宮格的部分是自定義SuduPuzzleView,使用draw方法繪制出來。因為對Android不了解,沒想到什么辦法能夠識別這塊內(nèi)容。代碼中做了混淆,數(shù)獨的生成的地方也懶得找(不才,沒找到),于是就換了種思路,打算用python來解決。

二、用python解決

總體的方法思路如下:
識別初始化的數(shù)獨 -> 解數(shù)獨 -> 將解填入至游戲中

1、解數(shù)獨

最復(fù)雜的部分就是解數(shù)獨了,好的算法會更快。但是算法什么的目前還搞不定,先找一找解數(shù)獨的相關(guān)資料用現(xiàn)成的。發(fā)現(xiàn)一個排除候選猜測法,感覺還是很不錯的。試驗了一些數(shù)獨,解得很快,具體的算法可以參看他的page。
Python秒解最難數(shù)獨

大概是這樣:先是采用“排除候選法”,確定能確定的數(shù)字,中間還額外增加了隱形排除法用來簡化問題。當(dāng)所有的空位都確定后,仍有一些空位有多個值,這時候就采用作者后半部分的猜測算法。先是進(jìn)行對候選的列表進(jìn)行評分,根據(jù)評分選擇候選列表中數(shù)字最少的一個來開始 猜測-回溯。

2、識別數(shù)獨

有了解數(shù)獨的方法,剩下的就好辦了,只需給他傳一個初始化的data數(shù)組就行。有內(nèi)容的填對應(yīng)的數(shù)字,空內(nèi)容的則填寫0。

初始化數(shù)組的方法打算用圖片處理:先把當(dāng)前游戲頁面截圖,然后分別識別數(shù)獨9x9宮格的對應(yīng)內(nèi)容,之后存入data數(shù)組

處理圖片用的是PIL庫,用到的基本操作都很簡單:

# 讀取image
image = Image.open(ori_img)

# 確定剪裁區(qū)域
box = (x_start, y_start, x_end, y_end)

# 剪裁圖片
newImage = image.crop(box)

#保存剪裁的圖片
newImage.save(save_file)

圖片識別使用的是tesseract-ocr引擎和pytesseract庫。因為游戲中數(shù)字的背景很純(忽略顏色),所以非常容易識別,出錯率很小。使用方法也異常的簡單。需要注意的就是參數(shù)psm,不同情況需要調(diào)整psm參數(shù)才行。

# PIL 打開已經(jīng)剪裁好的圖片
image = Image.open(img)

# 轉(zhuǎn)換為L -> 灰色圖像 方便識別。
# 關(guān)于PIL其他8種模式可以翻閱其他資料,這里采用L模式
image = image.convert('L')

# 使用pytesseract模塊中的image_to_string方法,將圖片識別的數(shù)字轉(zhuǎn)為string。
text = pytesseract.image_to_string(image, config='-psm 9')

# string轉(zhuǎn)int,這里偷懶,沒做校驗。如果出錯的就掛了╥﹏╥...
number = int(text)

# 返回數(shù)字供調(diào)用方
return number

附:psm參數(shù)的說明,可以使用命令tesseract --help-psm查看

$ tesseract --help-psm
Page segmentation modes:
  0    Orientation and script detection (OSD) only.
  1    Automatic page segmentation with OSD.
  2    Automatic page segmentation, but no OSD, or OCR.
  3    Fully automatic page segmentation, but no OSD. (Default)
  4    Assume a single column of text of variable sizes.
  5    Assume a single uniform block of vertically aligned text.
  6    Assume a single uniform block of text.
  7    Treat the image as a single text line.
  8    Treat the image as a single word.
  9    Treat the image as a single word in a circle.
 10    Treat the image as a single character.
 11    Sparse text. Find as much text as possible in no particular order.
 12    Sparse text with OSD.
 13    Raw line. Treat the image as a single text line,
            bypassing hacks that are Tesseract-specific.

這樣通過識別9x9宮格的圖片后,我們就自然而然的轉(zhuǎn)化為我們需要的data數(shù)組。另外,解法中最后提供的類型是numpy的ndarray類型。

3、填充數(shù)字

這里更懶,通過最原始的adb點坐標(biāo)形式。。。將數(shù)獨的81個數(shù)據(jù)與對應(yīng)的81個坐標(biāo)聯(lián)系起來,通過for循環(huán)依次填進(jìn)去。因為只在自己的機器上,所以坐標(biāo)什么的都寫死了??。

# 點擊空格坐標(biāo)定位
adb -s %s shell input tao x y
# 輸入當(dāng)前空格的解
adb -s %s shell input text num_input_from_data 

三、實驗

過程主要耗費在初始化data數(shù)組的時候,因為是線性執(zhí)行的來保證數(shù)組的正確順序,識別完一個后,才識別下一個。關(guān)于順序問題暫時沒想好怎么優(yōu)化,最后填充解的時候也是一個個填進(jìn)去的??。。。

最終效果,點開查看gif。
(不知道為什么,gif有的時候動,有的時候不動??)

四、總結(jié)

其實到了后面,目的就已經(jīng)不是自動解題了。。。而是在這個過程中接觸的新東西。

1、了解了數(shù)獨

之前只是單純的玩兒,但是沒想到解題的過程中運用了很高深的知識,尤其是自己摸索出的一切技巧,居然有一些高大上的對應(yīng)名詞。

2、查看了各種數(shù)獨的解題算法

思路可以理解,但寫不出來。。。

3、接觸了Tesseract-OCR引擎

發(fā)現(xiàn)圖像識別可以運用到自己的工作中,如解決一些需要人工驗證的自動化。感覺非常好玩,在試驗過程中,有一些識別的不是很好,還能通過訓(xùn)練來提高識別度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,917評論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,172評論 4 61
  • 熟悉的城市 陌生的自己 二十四年太久 漂零了多少記憶 都不知去向哪里 初來的羞澀 那是因為別人的華麗 在羨慕中一點...
    月陵無聲閱讀 420評論 2 8
  • 為什么權(quán)力只為某些人所擁有? 權(quán)力,是什么? 為什么要擁有權(quán)力? 擁有權(quán)力之后會帶來什么好處? 看了前言部分,對“...
    Cynthiayumoon閱讀 510評論 0 0

友情鏈接更多精彩內(nèi)容