Python이 Brain Wars를 플레이 해 보았습니다 3
소개
파이썬이 Brain Wars의 Make10을 플레이 해 보았습니다.
Make10 규칙
숫자의 합이 10이 되는 카드 조합을 찾아 탭합니다.
하지만
환경
숫자의 합이 10이 되는 카드 조합을 찾아 탭합니다.
하지만
환경
Vysor이라는 Chrome 확장 플러그인을 사용하여 우분투에서 스마트 폰을 조작하고 있습니다.
코드
import mss
import numpy as np
import time
import cv2
import pyautogui as pag
import itertools
from sklearn.neighbors import KNeighborsClassifier
def grab_screen(bbox):
"""Capture the specified area on the screen"""
with mss.mss() as sct:
left, top, width, height = bbox
grab_area = {'left': left, 'top': top, 'width': width, 'height': height}
img = sct.grab(grab_area)
return np.array(img)[:, :, :3]
def process_img(img):
"""Extract numbers from each card"""
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, img_bin = cv2.threshold(img_gray, 210, 255, cv2.THRESH_BINARY)
_, cnts, _ = cv2.findContours(img_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = list(filter(lambda x: 30 < cv2.boundingRect(x)[-1] < 70, cnts))
cnts = sorted(cnts, key=lambda x: (cv2.boundingRect(x)[1] // 10, cv2.boundingRect(x)[0]))
rois = []
locs = []
for cnt in cnts:
x, y, w, h = cv2.boundingRect(cnt)
locs.append([int(x + w/2), int(y + h/2)])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
roi = cv2.resize(img_bin[y:y+h, x:x+w], (10, 10)).reshape(1, 100)
rois.append(roi)
cv2.imwrite('detection_result.jpg', img)
locs = np.array(locs)
rois = np.array(rois).squeeze()
return rois, locs
def build_knn():
"""Create and train knn classifier"""
samples = np.loadtxt('train_samples.data', np.uint8)
labels = np.loadtxt('train_labels.data', np.float32)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(samples, labels)
return knn
def find_combination(nums):
"""Find a combination which sums to 10"""
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == 10]
return result
def main():
grab_bbox = (104, 385, 467, 300)
knn = build_knn()
while True:
img = grab_screen(grab_bbox)
rois, locs = process_img(img.copy())
if len(rois) > 12 or len(rois) < 9:
print('Done')
break
nums = knn.predict(rois).astype(int) # classify numbers
while len(locs) > 0:
idx = (np.abs(locs[:, 1] - locs[-1, 1]) < 5) # index of cards at the bottom row
locs_ = locs[idx].tolist()
nums_ = nums[idx].tolist()
comb = find_combination(nums_)
print('Cards to click:', comb[0])
for num in comb[0]:
idx_click = nums_.index(num) # index of card to tap
x, y = (locs_.pop(idx_click))
nums_.pop(idx_click)
pag.click(grab_bbox[0] + x, grab_bbox[1] + grab_bbox[3] - 50) # tap card
locs = locs[~idx] # remove cards at the bottom row
nums = nums[~idx]
if len(locs) > 0:
time.sleep(0.085)
time.sleep(0.36)
if __name__ == '__main__':
main()
결과
파이썬 편리
Reference
이 문제에 관하여(Python이 Brain Wars를 플레이 해 보았습니다 3), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/harupy/items/0232479a86fd3cfb6dd3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import mss
import numpy as np
import time
import cv2
import pyautogui as pag
import itertools
from sklearn.neighbors import KNeighborsClassifier
def grab_screen(bbox):
"""Capture the specified area on the screen"""
with mss.mss() as sct:
left, top, width, height = bbox
grab_area = {'left': left, 'top': top, 'width': width, 'height': height}
img = sct.grab(grab_area)
return np.array(img)[:, :, :3]
def process_img(img):
"""Extract numbers from each card"""
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, img_bin = cv2.threshold(img_gray, 210, 255, cv2.THRESH_BINARY)
_, cnts, _ = cv2.findContours(img_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = list(filter(lambda x: 30 < cv2.boundingRect(x)[-1] < 70, cnts))
cnts = sorted(cnts, key=lambda x: (cv2.boundingRect(x)[1] // 10, cv2.boundingRect(x)[0]))
rois = []
locs = []
for cnt in cnts:
x, y, w, h = cv2.boundingRect(cnt)
locs.append([int(x + w/2), int(y + h/2)])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
roi = cv2.resize(img_bin[y:y+h, x:x+w], (10, 10)).reshape(1, 100)
rois.append(roi)
cv2.imwrite('detection_result.jpg', img)
locs = np.array(locs)
rois = np.array(rois).squeeze()
return rois, locs
def build_knn():
"""Create and train knn classifier"""
samples = np.loadtxt('train_samples.data', np.uint8)
labels = np.loadtxt('train_labels.data', np.float32)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(samples, labels)
return knn
def find_combination(nums):
"""Find a combination which sums to 10"""
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == 10]
return result
def main():
grab_bbox = (104, 385, 467, 300)
knn = build_knn()
while True:
img = grab_screen(grab_bbox)
rois, locs = process_img(img.copy())
if len(rois) > 12 or len(rois) < 9:
print('Done')
break
nums = knn.predict(rois).astype(int) # classify numbers
while len(locs) > 0:
idx = (np.abs(locs[:, 1] - locs[-1, 1]) < 5) # index of cards at the bottom row
locs_ = locs[idx].tolist()
nums_ = nums[idx].tolist()
comb = find_combination(nums_)
print('Cards to click:', comb[0])
for num in comb[0]:
idx_click = nums_.index(num) # index of card to tap
x, y = (locs_.pop(idx_click))
nums_.pop(idx_click)
pag.click(grab_bbox[0] + x, grab_bbox[1] + grab_bbox[3] - 50) # tap card
locs = locs[~idx] # remove cards at the bottom row
nums = nums[~idx]
if len(locs) > 0:
time.sleep(0.085)
time.sleep(0.36)
if __name__ == '__main__':
main()
파이썬 편리
Reference
이 문제에 관하여(Python이 Brain Wars를 플레이 해 보았습니다 3), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/harupy/items/0232479a86fd3cfb6dd3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)