ハシカンがCMしていたからはじめた放置少女。
偶然ハシカンに出会っても「放置少女やってます」って話しかけられる。
僕と環奈を繋ぐたった一つの糸。放置少女。
そんな放置少女の育成は死ぬほどめんどくさい。
めんどくさいことは自動化しよう。
アンドロイドエミュレーターNoxとPyAutoGuiで画像認識させて自動化してみたので、必要な人は参考にして。
ディレクトリ構成
PyAutoGuiでこれらのボタンの位置を探してきて、クリックする
getParameter()の中で画像の位置を取得してます。下のコードではPC画面の右半分くらいを範囲として(region=(275, 1373, 276, 40))、指定の画像を探しています。PC画面全域から探させるのは処理が重くなるかなと思って、せめてもの優しさ?
pyautogui.click()の位置がずれるのはRetinaディスプレイの絡み。
pyautogui.locateOnScreen()で画像の位置情報を取ってこれるのですが、その座標をpyautogui.click()でクリックさせてもズレている…
これはMacのディスプレイの解像度がRetinaディスプレイで普通の2倍の解像度を持っているかららしい!
てことで、pyautogui.locateOnScreen()で取ってきた座標を÷2してあげれば、正しく画像の位置をクリックしてくれる!
like this way
pyautogui.click(btnLeftX / 2, btnLeftY / 2)
育成前後のステータスをスクショ撮って、PyOCRでどれだけステータスが上がったのか計算
育成前のスクショ 育成後のスクショ
getSS()で育成前と育成後のステータス部分のスクリーンショットを撮って、getText()の中でPyOCRを使ってステータスの画像認識をして数値を取得し、どのステータスがどれだけ上がったのかを計算しています。
トータル戦力が上がればいいかなってことで筋力×4、体力×3、敏捷・知力等倍の重みで計算してます。
total = strength * 4 + physical * 3 + agile + inte
今回は武将verですが、謀士弓将でこの計算式はいじります。
それぞれのステータスには重みがあるので、筋力や知力が1上がったとしても、総戦力の上がり方が違います(武将は筋力と体力をあげたい)
この重みを計算するための式を↓の記事で書いています。
サンプルコード
import getParameter as gp
import time
def main():
print('main')
# ボタンの場所などを確認
gp.getParameter()
# ウィンドウのアクティブ化
gp.clickLeft()
for i in range(500):
print('---------------------------')
# C級育成
gp.clickLeft()
gp.getSS()
gp.getText()
main()
import pyautogui
import cv2
import pyocr
import pyocr.builders
from PIL import Image
import sys
import time
preParamImg = 'tempImg/preParamImg.png'
paramImg = 'tempImg/paramImg.png'
preStatusTop = 0
preStatusBottom = 0
statusTop = 0
statusBottom = 0
preTop = 0
height = 0
btnLeft = 0
btnRight = 0
def test():
preStatusTop = pyautogui.screenshot(region=(275, 1373, 276, 40))
preStatusTop.save('test.png')
pyautogui.click(250, 400)
pyautogui.click(250, 400)
pyautogui.click(250, 400)
def getParameter():
global preStatusTop
global preStatusBottom
global statusTop
global statusBottom
global preTop
global height
global btnLeft
global btnRight
preStatusTop = pyautogui.locateOnScreen(
'refImg/preStatusTop.png', region=(0, 0, 1000, 1500), confidence=0.8)
preStatusBottom = pyautogui.locateOnScreen(
'refImg/preStatusBottom.png', region=(0, 0, 1500, 1500), confidence=0.8)
statusTop = pyautogui.locateOnScreen(
'refImg/statusTop.png', region=(0, 0, 1000, 1500), confidence=0.8)
statusBottom = pyautogui.locateOnScreen(
'refImg/statusBottom.png', region=(0, 0, 1500, 1500), confidence=0.8)
preTop = preStatusTop.top + preStatusTop.height
height = statusBottom.top - preTop
btnLeft = pyautogui.locateOnScreen(
'refImg/btnLeft.png', region=(0, 0, 1500, 3000), confidence=0.8)
btnRight = pyautogui.locateOnScreen(
'refImg/btnRight.png', region=(0, 0, 1500, 3000), confidence=0.8)
def clickLeft():
btnLeftX, btnLeftY = pyautogui.center(btnLeft)
pyautogui.click(btnLeftX / 2, btnLeftY / 2) # retinaDesiplayは/2
time.sleep(1)
def clickRight():
btnRightX, btnRightY = pyautogui.center(btnRight)
pyautogui.click(btnRightX/2, btnRightY/2) # retinaDesiplayは/2
time.sleep(1)
def getSS():
preSc = pyautogui.screenshot(
region=(preStatusTop.left, preTop, preStatusTop.width, height))
sc = pyautogui.screenshot(
region=(statusTop.left, preTop, statusTop.width, height))
preSc.save(preParamImg)
sc.save(paramImg)
# time.sleep(1)
def getText():
tools = pyocr.get_available_tools()
tool = tools[0]
langs = tool.get_available_languages()
param = tool.image_to_string(
Image.open(paramImg),
lang='eng',
builder=pyocr.builders.DigitBuilder()
).split()
preParam = tool.image_to_string(
Image.open(preParamImg),
lang='eng',
builder=pyocr.builders.DigitBuilder()
).split()
while (len(param) != 4):
time.sleep(0.3)
print('成長後のステが取れなかったのでもう一度')
getSS()
param = tool.image_to_string(
Image.open(paramImg),
lang='eng',
builder=pyocr.builders.DigitBuilder()
).split()
print(preParam)
print(param)
strength = int(param[0]) - int(preParam[0])
agile = int(param[1]) - int(preParam[1])
inte = int(param[2]) - int(preParam[2])
physical = int(param[3]) - int(preParam[3])
total = strength * 4 + physical * 3 + agile + inte
print(total)
if (total >= 0):
print(total)
print('保存')
clickRight()
# 結果が表示される。邪魔なので3秒待つ。
time.sleep(3)
else:
print(total)
print('閉じる')
clickLeft()