Android-数独世界自动完成标准数独的小脚本

最近从GP上翻出了之前玩的一款消磨时间的游戏“数独世界” --le.lenovo.sudoku,登陆了GP账号发现已经取得了一些成就,但之前的记录没了,得从新开始玩。懒得费力的去重复完成之前关卡,于是想着怎么能自动填充数独。

抱着试一试的态度,开始了研究。

一、反编译

这款app做了混淆处理,和一些简单的防反编译的措施。正常的工具会失败,得使用强力的反编译工具才行。

1、去广告

广告挺多的,从splash activity、ResumeGameActivity、SudokuActivity等页面都有广告。查看了一下,是使用的Android原生广告,并且程序打印了广告的一些log出来。顺着log可以找到关键地方,然后禁用掉。在AndroidManifest.xml中,也可以看到广告activity的声明,直接删掉就好了。剩下可能残留一些banner广告,暂时留着吧,也给开发者留点收入。

2、分析页面布局

游戏的主页面是SudokuActivity,查看布局发现,棋盘宫格的部分是自定义SuduPuzzleView,使用draw方法绘制出来。因为对Android不了解,没想到什么办法能够识别这块内容。代码中做了混淆,数独的生成的地方也懒得找(不才,没找到),于是就换了种思路,打算用python来解决。

二、用python解决

总体的方法思路如下:
识别初始化的数独 -> 解数独 -> 将解填入至游戏中

1、解数独

最复杂的部分就是解数独了,好的算法会更快。但是算法什么的目前还搞不定,先找一找解数独的相关资料用现成的。发现一个排除候选猜测法,感觉还是很不错的。试验了一些数独,解得很快,具体的算法可以参看他的page。
Python秒解最难数独

大概是这样:先是采用“排除候选法”,确定能确定的数字,中间还额外增加了隐形排除法用来简化问题。当所有的空位都确定后,仍有一些空位有多个值,这时候就采用作者后半部分的猜测算法。先是进行对候选的列表进行评分,根据评分选择候选列表中数字最少的一个来开始 猜测-回溯。

2、识别数独

有了解数独的方法,剩下的就好办了,只需给他传一个初始化的data数组就行。有内容的填对应的数字,空内容的则填写0。

初始化数组的方法打算用图片处理:先把当前游戏页面截图,然后分别识别数独9x9宫格的对应内容,之后存入data数组

处理图片用的是PIL库,用到的基本操作都很简单:

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

# 确定剪裁区域
box = (x_start, y_start, x_end, y_end)

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

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

图片识别使用的是tesseract-ocr引擎和pytesseract库。因为游戏中数字的背景很纯(忽略颜色),所以非常容易识别,出错率很小。使用方法也异常的简单。需要注意的就是参数psm,不同情况需要调整psm参数才行。

# PIL 打开已经剪裁好的图片
image = Image.open(img)

# 转换为L -> 灰色图像 方便识别。
# 关于PIL其他8种模式可以翻阅其他资料,这里采用L模式
image = image.convert('L')

# 使用pytesseract模块中的image_to_string方法,将图片识别的数字转为string。
text = pytesseract.image_to_string(image, config='-psm 9')

# string转int,这里偷懒,没做校验。如果出错的就挂了╥﹏╥...
number = int(text)

# 返回数字供调用方
return number

附:psm参数的说明,可以使用命令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宫格的图片后,我们就自然而然的转化为我们需要的data数组。另外,解法中最后提供的类型是numpy的ndarray类型。

3、填充数字

这里更懒,通过最原始的adb点坐标形式。。。将数独的81个数据与对应的81个坐标联系起来,通过for循环依次填进去。因为只在自己的机器上,所以坐标什么的都写死了😄。

# 点击空格坐标定位
adb -s %s shell input tao x y
# 输入当前空格的解
adb -s %s shell input text num_input_from_data 

三、实验

过程主要耗费在初始化data数组的时候,因为是线性执行的来保证数组的正确顺序,识别完一个后,才识别下一个。关于顺序问题暂时没想好怎么优化,最后填充解的时候也是一个个填进去的🤣。。。

最终效果,点开查看gif。
(不知道为什么,gif有的时候动,有的时候不动🤣)

四、总结

其实到了后面,目的就已经不是自动解题了。。。而是在这个过程中接触的新东西。

1、了解了数独

之前只是单纯的玩儿,但是没想到解题的过程中运用了很高深的知识,尤其是自己摸索出的一切技巧,居然有一些高大上的对应名词。

2、查看了各种数独的解题算法

思路可以理解,但写不出来。。。

3、接触了Tesseract-OCR引擎

发现图像识别可以运用到自己的工作中,如解决一些需要人工验证的自动化。感觉非常好玩,在试验过程中,有一些识别的不是很好,还能通过训练来提高识别度。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,043评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,943评论 4 60
  • 熟悉的城市 陌生的自己 二十四年太久 漂零了多少记忆 都不知去向哪里 初来的羞涩 那是因为别人的华丽 在羡慕中一点...
    月陵无声阅读 368评论 2 8
  • 为什么权力只为某些人所拥有? 权力,是什么? 为什么要拥有权力? 拥有权力之后会带来什么好处? 看了前言部分,对“...
    Cynthia雯霏阅读 390评论 0 0