用Python搞點事

用Python讓小恐龍突破天際吧!

講者: 楊平

大綱

  • 課程介紹
  • 套件介紹
  • 分析遊戲
  • 實作
  • 科普人工智慧

課程介紹

本日目標

能學到什麼

  • PIL套件
  • PyAutoGui
  • 人工智慧科普

套件介紹

PIL套件

PIL(Python Imagine Library)是一套處理圖片的Python套件

  • 調整大小、色調、對比、亮度...
  • 裁切圖片
  • 旋轉圖片
  • 加濾鏡
  • 附加文字浮水印
  • etc.

PyAutoGui套件

  • 控制鍵盤滑鼠
  • 自動控制
  • 可用做自動化測試

mss套件

  • 多螢幕截圖
  • 快速

mss(multiple screenshots)

from PIL import Image
import mss

with mss.mss() as sct:
    box = {'top': 0, 'left': 0, 'width': 300, 'height': 300}
    sct_img = sct.grab(box)
    image = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')

image.show()

mss套件

file = open('demo.py', 'r', encoding='UTF-8')
try:
    for line in file:
        print(line, end='')
except:
    print('讀取檔案發生錯誤')
finally:
    file.close()

等同於

with open('demo.py', 'r', encoding='UTF-8') as file:
    for line in file:
        print(line, end='')

with ... as ... 用法

套件安裝

pip install pillow
pip install pyautogui==0.9.39
pip install mss

分析遊戲

開啟遊戲

Chrome網址列輸入chrome://dino

日與夜-1

當分數可被700整除時進入夜晚模式

過了200之後重回白天模式

  • 0~700: day1
  • 700~900: night1
  • 900~1400: day2
  • 1400~1600: night2

日與夜-2

日夜中間會有一段灰階的漸層

日與夜-3

日夜地板會有一段小小的高低差

日與夜-4

月亮會變喔!

速度漸快

小恐龍會越跑越快,但有個速度上限

大約在1500達到極速

可以透過每100閃爍過後的數字來確認速度

蹲下

在地上按下方向鍵「下」蹲下躲避中間的鳥

急速下墜

在半空中按下方向鍵「下」可急速下墜

實作

調整大小

將runner-canvas寬度調整為600

可用F12開發者工具調整

開始遊戲

先建立一個字典coordinates,存放開始按鈕的座標(用小畫家觀察座標位置)

並用pyautogui在該座標按下滑鼠

from PIL import ImageGrab, Image
import pyautogui

cordinates = {
	'replayBtn': (303, 356)
}

def startGame():
    pyautogui.click(cordinates['replayBtn']) 

跳躍判斷

利用PIL抓取前方區域,並判斷該區域有無障礙物

抓取範圍應為地板與最高的鳥之間(注意翅膀)

大約是頭頂至地板上方一點點即可

跳躍判斷

設定小恐龍鼻頭上方座標,作為參考

cordinates = {
    'replayBtn': (303, 356),
    'dino': (86, 360)
}
def imageGrab():
   with mss.mss() as sct:
	box = {'top': cordinates['dino'][1], 'left': cordinates['dino'][0]+70, 
               'width': 50, 'height': 40}
	sct_img = sct.grab(box)
        image = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
    bwImage = image.convert('1')
    return list(bwImage.getdata()).count(0)

抓取區域函式,調整框起來的數值可決定甚麼時候跳躍

問題與解法

目前看起來已經可以穩穩地度過第一天了,但有幾個問題

  1. 到了晚上會發瘋
  2. 中間的鳥躲得有點驚險
  3. 速度漸增到後面會來不及反應

問題與解法

到了晚上會發瘋

def imageGrab():
    # ...
    grayImage = image.convert('L')
    return len(grayImage.getcolors())
while True:
    if(imageGrab() > 1):
        pressSpace()

如果多於一種顏色就跳

利用判斷"顏色種類"的方式決定要不要跳,如果前方有障礙物,裡面的顏色一定不只一種

問題與解法

中間的鳥躲得有點驚險

在地上時保持低頭避開中間飛來的鳥

調整偵測區域高度,不要碰到中間的鳥

def imageGrab():
    with mss.mss() as sct:
	box = {'top': cordinates['dino'][1]+39, 'left': cordinates['dino'][0]+70, 
               'width': 50, 'height': 1}
	sct_img = sct.grab(box)
        image = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
    grayImage = image.convert('L')
    return len(grayImage.getcolors())
   

問題與解法

中間的鳥躲得有點驚險

在startGame裡面加上這段,讓遊戲一開始小恐龍就低頭

def startGame():
    pyautogui.click(cordinates['replayBtn'])
    pyautogui.keyDown('down')

問題與解法

中間的鳥躲得有點驚險

def pressSpace(airtime):
    pyautogui.keyUp('down')
    pyautogui.keyDown('space')
    pyautogui.keyUp('space')
    time.sleep(airtime)
    pyautogui.keyDown('down')

每次跳躍前要先放開向下鍵,經過一段airtime(滯空時間之後再按回去

import time

引入時間模組,定義滯空時間

airtime = 0.14

問題與解法

速度漸增到後面會來不及反應

利用極速下墜,讓反映更靈敏

問題與解法

速度漸增到後面會來不及反應

每隔一段時間縮短airtime

airtime = 0.15
lastTime = time.time()
startGame()
while True:
    if time.time() - lastTime >= 5:
        airtime -= 0.01
        lastTime = time.time()
    if(imageGrab() > 1):
        pressSpace()

10

lastTime

11

time.time()

12

13

14

15

10

10

10

10

1

2

3

4

5

15

=

-

16

17

18

19

20

15

15

15

15

15

1

2

3

4

5

20

問題與解法

速度漸增到後面會來不及反應

每隔一段時間增加偵測範圍,讓牠早點起跳

airtime = 0.15
lastTime = time.time()
offset = 0 
startGame()
while True:
    if time.time() - lastTime >= 5:
        airtime -= 0.01
        offset += 5
        lastTime = time.time()
    if(imageGrab() > 1):
        pressSpace()
def imageGrab():
    with mss.mss() as sct:
	box = {'top': cordinates['dino'][1]+39, 'left': cordinates['dino'][0]+70,
               'width': 50 + offset, 'height': 1}
	sct_img = sct.grab(box)
	image = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
    grayImage = image.convert('L') # 改為灰階
    return len(grayImage.getcolors())

問題與解法

速度漸增到後面會來不及反應

aritime最多減至0,不可為負的

while True:
    if time.time() - lastTime >= 5:
        if airtime - 0.01 >= 0:
            airtime -= 0.01
        offset += 5
        lastTime = time.time()
    if(imageGrab() > 1):
        pressSpace()

offset也不能無限制增加

while True:
    if time.time() - lastTime >= 5:
        if airtime - 0.01 >= 0:
            airtime -= 0.01
        if offset <= 140:
            offset += 5
        lastTime = time.time()
    if(imageGrab() > 1):
        pressSpace()

完整程式碼

科普人工智慧

以下純屬個人有限之淺見,有錯請見諒

我今天做的這隻,是AI嗎?

恩... 不算是

這個才是

人工智慧? 機器學習? 深度學習?

人工智慧

專家系統

狗: 汪汪叫、沒有花紋

貓: 喵喵叫、有花紋

"我看到一個有花紋喵喵叫的東西,那是甚麼?"

機器學習 & 深度學習

類神經網路

機器學習 & 深度學習

類神經網路

細胞本體

軸突

突觸

樹突

機器學習 & 深度學習

類神經網路

可用來解決線性不可分離問題

機器學習 v.s 深度學習

你可以自己做做看

資料

特徵擷取

模型

利用iris set製作iris模型

AI會取代XX工作嗎???

先不論AI會不會取代什麼

只要科技在進步就一定有東西會被取代

所以怎麼辦呢?

總之,假設你的工作快被科技取代了

就快想想怎麼轉換跑道就對了

人性就是怠惰,但人的適應力極強

持續觀察持續學習,就不用怕了

大概

Thank for listening

填個問卷,讓我們更好

https://forms.gle/yEBJrX6dehRHtGrj9

多多來上課才不會被AI取代喔XD

打個廣告

我們在招新人喔!

用Python搞點事2-用Python讓小恐龍突破天際吧!

By Sam Yang

用Python搞點事2-用Python讓小恐龍突破天際吧!

  • 1,727