ぷよぷよsteam版の画面領域認識

![スクリーンショット 2024-10-09 22.05.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/8ce41d48-9b49-f992-e0a7-e85bd2cf3976.png)




steam版のぷよぷよeスポーツは有料です。

https://store.steampowered.com/app/971620/_e/?l=japanese



画像の取り扱いについては以下のサイトを参照してください。

https://puyo.sega.jp/PuyoPuyo_eSports/agreement/index.html


©SEGA

## library
keyboard, pyautogui, pygetwindow　の３つをpipインストールする。


```python
import keyboard as kb
import pyautogui as ag
import numpy as np
from PIL import Image,ImageDraw
```

前のステップで取り込んだサンプル画像を使用します。


```python
im = Image.open("all1920x1080.png")
im
```



![output_4_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/50c14e36-569f-188e-7ef2-d17dda4ff2e0.png)


    



グレーに変換します。


```python
im1=im.convert('L')
im1
```





    
![output_6_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/a593a2d2-1b83-350c-588a-f58202a1c948.png)



二値化します。閾値は80くらいで良さそうです。  
0 black  
255 white


```python
im2=im1.point(lambda x: 0 if x < 80 else 255)
im2
```


![output_8_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/a8f0d1dd-17bb-90ee-b3b0-8f096f917362.png)


    

    



## zone recognition


```python
w,h = im1.size
print(w,h)
```

    1920 1080


## Zone stage
左側1/8から3/8　を対象に検索する


```python
x1 = w//8
y1 = h//12
lx = x1
rx = x1*3
uy = y1
ly = y1*11
for i in range(x1,x1*3):
    uy1 = y1*11
    ly1 = y1 
    l_max = 0
    l = 0
    for j in range(y1,y1*11):
        gs = im1.getpixel((i,j))
        if gs < 80: # black
            l+=1
            if l > l_max:
                uy1 = j-l
                ly1 = j
                l_max = l
        else: #white
            l = 0
    if l_max>y1 * 5:
        uy = uy1
        ly = ly1
        lx = i
        break

for i in range(x1*3,x1,-1):
    uy1 = y1*11
    ly1 = y1 
    l_max = 0
    l = 0
    for j in range(y1,y1*11):
        gs = im1.getpixel((i,j))
        if gs < 80: # black
            l+=1
            if l > l_max:
                uy1 = j-l
                ly1 = j
                l_max = l
        else: #white
            l = 0
    if l_max > y1 * 5:
        rx = i
        break
puyo_w = (rx-lx)//6
puyo_h = (ly-uy)//12
print(lx,uy,rx,ly,puyo_w,puyo_h)
```

    272 158 668 882 66 60



```python
## zone next puyo
```


```python
lx1 = rx + puyo_w
rx1 = rx + puyo_w
uy1 = uy
ly1 = uy + int(puyo_h*1.1) * 2
t_uy1 = uy1 + int(puyo_h*0.5)
t_ly1 = ly1 - int(puyo_h*0.5)

for i in range(lx1,lx1-puyo_w,-1):
    l = 0
    for j in range(t_uy1,t_ly1):
        gs = im1.getpixel((i,j))
        if gs > 250: # white
            l+=1
    if l == (t_ly1-t_uy1):
        lx1 = i
        break

for i in range(rx1,rx1+puyo_w):
    l = 0
    for j in range(t_uy1,t_ly1):
        gs = im1.getpixel((i,j))
        if gs > 250: # white
            l+=1
    if l == (t_ly1-t_uy1):
        rx1 = i
        break
c_x1 = int((lx1 + rx1)*0.5)
lx1 = c_x1 - int(puyo_w*0.55)
rx1 = c_x1 + int(puyo_w*0.55)

print(lx1,uy1,rx1,ly1)
```

    715 158 787 290


## zone 2nd next puyo


```python
lx2 = rx + puyo_w * 2
rx2 = rx + puyo_w * 2
ly2 = uy + puyo_h * 4
uy2 = ly2 - int(puyo_h*0.9) * 2

t_ly2 = ly2
t_uy2 = ly2 - int(puyo_h*0.9)

for i in range(lx2,lx2-puyo_w,-1):
    l = 0
    for j in range(t_uy2,t_ly2):
        gs = im1.getpixel((i,j))
        if gs > 250: # white
            l+=1
    if l == (t_ly2-t_uy2):
        lx2 = i
        break

for i in range(rx2,rx2+puyo_w):
    l = 0
    for j in range(t_uy2,t_ly2):
        gs = im1.getpixel((i,j))
        if gs > 250: # white
            l+=1
    if l == (t_ly2-t_uy2):
        rx2 = i
        break
c_x2 = int((lx2 + rx2)*0.5)
lx2 = c_x2 - int(puyo_w*0.45)
rx2 = c_x2 + int(puyo_w*0.45)

print(lx2,uy2,rx2,ly2)
```

    767 290 825 398



```python

draw = ImageDraw.Draw(im) # 矩形の描画の準備

rectcolor = (255, 0, 0) # 矩形の色(RGB)。red
linewidth = 4 # 線の太さ
draw.rectangle([(lx, uy), (rx, ly)], \
               outline=rectcolor, width=linewidth) # stage

draw.rectangle([(lx1, uy1), (rx1, ly1)], \
               outline=rectcolor, width=linewidth) # next puyo
draw.rectangle([(lx2, uy2), (rx2,ly2)], 
               outline=rectcolor, width=linewidth) # next puyo

im
```




    
    
![output_17_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/d57b6825-5326-900d-3147-533e66393a36.png)



認識できているようです。
***

![puyopuyo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/1fdf8221-96c5-fcfa-3a52-383422a6fdc3.gif)
　ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
　どうやって、Chromebookで、１０分で、素敵な人工知能を作れるのでしょうか？
　秘密は、３つ。
　１　jupyter liteで、webクライアントがpythonコードを実行
　２　超軽量な機械学習フレームワークdezeroを採用
　３　ぷよぷよのstageとactionがコンパクト

### Github&X

https://github.com/Lunanaedu/jupyterlite-puyopuyo

https://github.com/Lunanaedu/puyopuyo-kai

https://x.com/educationai_ai

### ぷよぷよプログラミングAI学習用まとめ

https://qiita.com/educational-ai/items/50c0fa689c01794d145e