파이톤으로 제 문제를 해결해 보도록 하겠습니다.

16893 단어 Python3Python

파이썬 3으로 제 회전구를 풀어봤습니다.


지난달에는 어떤 이유로 파이톤을 배웠기 때문에 예전 대학 강연회에서 원어민 강사가 시간을 보내면서 했던 것을 모방해 마이스위퍼를 자동으로 풀어봤다.
끝나고 난 그냥 커닝하는 줄 알았는데 그냥 혼자 즐기는 것 같아서 괜찮겠지.
비디오↓
https://www.youtube.com/watch?v=8JslBSjS8bI&feature=youtu.be
개량↓
https://qiita.com/RRRF/items/e0c36d1a8efd2a38e6fb

개시하다


사실, 나는 원래 처음부터 Windows에 들어갈 것이라고 생각했지만, 매우 유감스럽게도 Windows10에 없다. 그래서 나는 응용 프로그램 상점에서 마이크로소프트 Minesweeper를 찾았다.

화면이 이런 느낌이야.

컨디션

  • Python 3.6.4
  • Windows10
  • Microsoft Minesweeper
  • 이미지에서 숫자 읽기


    또박또박 캡처하다


    한 칸 한 칸 캡처하는 데 시간이 오래 걸리는 이유라고 생각합니다.
    사실 캡처 한 장만 처리하면 될 것 같았어요. 픽셀 수 때문에 완성이 안 돼서 다른 방법도 귀찮아서 결정했어요.

    main.py
    import pyautogui
    X = 582   #右端
    Y = 213   #上端
    def imageread():   #スクリーンショットをとる関数
        key = 84
        for i in range(9):
            for j in range(9):
                img = pyautogui.screenshot(
                    imageFilename = "imagefile/image" + str(i) + str(j) + ".png",
                    region = (X + i * key, Y + j * key, key, key)
                )
    

    캡처에서 숫자 읽기


    원래 pyocr 등을 사용하여 숫자를 식별해야 하는데 왜 pyocr를 설치해도 사용할 수 없는지 포기했습니다.
    그래서 나는 색깔로 숫자를 판단해야 한다. 이것도 집행에 시간이 필요한 주요 원인이라고 생각한다.
    또한 해당 색상의 숫자는 반드시 코드에 직접 써야 하며, RGB의 작은 값을 고려하는 조건은 매우 번거롭기 때문에 1~3의 경우만 생각해야 한다. 따라서 4 이상이 발생하면 이 게임은 오류가 발생하여 끝난다.
    main.py
    from PIL import Image
    import numpy as np
    def imagescan(i, j):   #指定したマスの数字を色から読み取る関数
        img = Image.open('imagefile/image' + str(i) + str(j) + '.png')
        width, height = img.size
        img_pixels = np.array([[img.getpixel((35, j)) for j in range(27, 54)]])
        image = img_pixels[0]
        count = 0
        count_b = 0
        count_one = 0
        count_three = 0
        for r in image:
            if sum(r) > 730:   #RGB値を足した数が730以上だと背景が白と判断する
                count += 1
            elif r[2] > 200:
                if r[2] > r[0] and r[2] > r[1]:   #RGBのBが一番多いと1だと判断する
                    count_one += 1   #RGBのBが多いことより青っぽい色であることを記録する
                count_b += 1
            if r[0] > r[1] and r[0] > r[2]:   #RGBのRが一番多いと3だと判断する
                count_three += 1
        if count >= 27:
            return 0
        elif count_b >= 27:
            return 100
        elif count_three > 2:
            return 3
        elif count_one > 1:
            return 1
        else:
            return 2
    

    붓을 풀다


    알고리즘에 관한 문제는 데이터 구조와 알고리즘이 현재 학습 중이기 때문에 (아직 파악하지 못했다) 계산량이 상당히 많은 방법을 채택했다고 생각합니다.

    1. 주변 송어 상황 조사


    먼저 좌표에서 송어를 지정해 주변 8송어 상황 조사의 함수를 만들었다.
    아래 절차에 따라 운행하다.
    1. 주변 8개의 공백 중 몇 개의 미개봉 공백을 계산한다
    2. 세면서 폭탄이 있다는 걸 알았다면 기록해
    3. 주변 8송어의 폭탄 수량을 주변 미개봉송어의 수량으로 나누고 각 송어의 리스트 S의 값을 더한다. 또 2가 폭탄이 있다는 것을 알았다면 이 몇 분의 폭탄을 빼자.
    4. 주변에 개봉하지 않은 송어의 수량 > 폭탄의 수량 = 폭탄이 있는 송어의 수량을 확정한다. 그러면 폭탄이 있는 송어는 폭탄이 없는 것이 확실치 않다―50대입이다.
    5. 폭탄이 확실한 송어에게 100을 대입
    main.py
    def sarch(a, b, key):   #引数の周囲8マスのSを更新する関数
        a += 1
        b += 1
        count = 0   #未開封マスのカウンター
        for i in range(a - 1, a + 2):
            for j in range(b - 1, b + 2):
                if i != a or j != b:
                    if S[i][j] == 100:
                        key -= 1
                        #周囲のマスに未開封爆弾ありマスがある場合keyから1を引く
                    elif S[i][j] >= 0:
                        count += 1
        if count == key:   #周囲8マスの未開封マスと爆弾の数が一致した場合
            key = 100
        elif key != 0:
            key = key / count
        for i in range(a - 1, a + 2):
            for j in range(b - 1, b + 2):
                if key == 0 and S[i][j] != 100:
                    if S[i][j] != -1:
                        S[i][j] = -50
                        click(i, j)
                        no_bomb.append([i, j])
                        #周囲8マスに未開封爆弾がありかつ,自身のマスではない場合-50を代入
                        #自身のマス番地をno_bombに追加
                elif i != a or j != b:
                    if S[i][j] < 100 and S[i][j] != -1 and S[i][j] != -50:
                        S[i][j] += key
                        #周囲8マスについて未開封爆弾の位置がわからない場合,Sにkeyを足す
                    if S[i][j] >= 100:
                        S[i][j] = 100
                        #未開封爆弾が確実にあるマスについては100を維持
    

    2. 개봉


    1. 폭탄 없는 송어(S=-50)를 모두 열기
    2. 상기한 송어가 없으면 S의 값으로 가장 작은 송어를 연다
    이것들을 끊임없이 한 번 되풀이했다.

    감상


    나는 더 많은 사람들이 할 수 없는 속도로 조금씩 개봉을 상상하면서도 기계가 켜는 것처럼 한가로워서 정말 유감이다.
    프로그래밍 기술을 향상시키고 더 빨리 해결할 수 있는 방법을 생각해 보려고 합니다.
    이어서 초밥을 풀어보고 싶지만, 이를 위해 OCR의 프로그램 라이브러리를 사용해야 한다고 생각해서 사용할 수 있도록 노력하고 싶습니다.
    코드 전문도 붙여.
    붙이고 싶은데 왜 안 돼요?
    종결어.

    좋은 웹페이지 즐겨찾기