<p style='color:#C4C400;font-size:72px'>🐍讓電腦學會玩貪吃蛇🐍</p>
<p style='color:#C4C400;font-size:72px'>-- Q Learning</p>
<!-- .slide: data-background="https://img.tukuppt.com/bg_grid/00/13/64/Sc05arinYm.jpg!/fh/350" data-background-color="#005" -->
#### 報告: $\space$鐘仕翔、洪惟信
---
<h2 style='color:#C4C400'>貪吃蛇</h2>
----
<h2 style='color:#C4C400'>貪吃蛇是什麼?</h2>
- 在遊戲中,玩家操控一條細長的直線(俗稱蛇)
- 玩家只能操控蛇的頭部朝向(上下左右)
- 路上會有很多"食物"
- 每次貪食蛇吃掉一件食物,它的身體便增長一些
- 不能碰觸到牆壁跟自身的身體
- 目的: 讓自己的身體越長越好
- [貪吃蛇線上版 ](https://g.co/kgs/tNMVdn)
----
<h2 style='color:#C4C400'>環境規劃</h2>
- 簡單化(處理資料比較方便,效率比較好)
- 12*12
- 蛇身藍色
- 蛇頭綠色
- 食物紅色
- 背景白色
----

---
<h2 style='color:#C4C400'>貪食蛇遊戲建立</h2>
----
<h2 style='color:#C4C400'>Pygame</h2>
- 一種遊戲引擎
- 簡單方便,還有很多人做的小遊戲可以參考
- 非內建 需pip install pygame
- import pygame
----

----
<h3 style='color:#C4C400'>使用套件</h3>
```python= [1-5|1|2|3|4|5]
import pygame as pg
import numpy as np
import time
import random
import copy
```
----
<h3 style='color:#C4C400'>初始化</h3>
- <span> 設計畫面為720px * 720px <!-- .element: class="fragment" data-fragment-index="1" --></span>
- <span> 離散化為12*12<!-- .element: class="fragment" data-fragment-index="2" --></span>
- <span> 每一格佔60px * 60px<!-- .element: class="fragment" data-fragment-index="3" --></span>
----
<h3 style='color:#C4C400'>加載對象</h3>
- 貪吃蛇初始位置在右上角兩格
- 食物位置隨機(但不要出生在蛇身裡)

----
<h2 style='color:#C4C400'>遊戲流程</h2>
----
<h3 style='color:#C4C400'>貪食蛇移動</h3>
- 定義前後左右為 0右 1左 2下 3上
- 頭移動到下一個位置,其餘位置替換成前面
<p></p>
<h3 style='color:#C4C400'>貪食蛇吃到食物</h3>
- 身體不動,把頭換成食物的位置
- 讓食物隨機出生(不要碰到蛇)
<p></p>
<h3 style='color:#C4C400'>死亡條件</h3>
- 頭的位置碰到自己的身體
- 頭的位置碰到牆壁
----
<h3 style='color:#C4C400'>繪製圖像</h3>
- 蛇的頭綠色,身體藍色
- 食物顏色紅色
- <span> 透過pygame畫矩形<!-- .element: class="fragment" data-fragment-index="1" --></span>
<span>
```python=
#畫矩形 rect(顏色,[x,y,width,height],線寬)
pg.draw.rect(bg, (0,0,255),[x, y, 60, 60], 0)
```
<!-- .element: class="fragment" data-fragment-index="1" -->
</span>
----

---
$\space \space$<p></p>
<h1 style='color:#EA0000'> 讓電腦學會</h1>
<h1 style='color:#EA0000'>
玩貪食蛇</h1>
$\space \space$<p></p>
$\space \space$<p></p>
$\space \space$<p></p>
$\space \space$<p></p>
$\space \space$<p></p>
<!-- .slide: data-background="https://case.ntu.edu.tw/blog/wp-content/uploads/2023/03/16578213_MotionElements_ai-humanoid-robot-touching.jpg" data-background-color="#005" -->
----
<h1 style='color:#C4C400'>Q Learning</h1>
----
<h2 style='color:#C4C400'>基礎名稱定義</h2>
- agent代理
- environment環境
- state狀態
- action動作
- reward獎勵
- value function價值函數
----
<h2 style='color:#C4C400'>Q Learning</h2>
- Q-learning 是強化學習的一種方法,主要是透過記錄學習過的策略,來告訴Agent,什麼情況下要對應採取什麼Action會得到最大的Reward。
- Q-learning 最基本的應用方式,就是將對應行動的獎勵值存在一個Q表中(Q-table)。
----
<h3 style='color:#C4C400'>Q-table</h3>
- Q-table 簡單來說就是一個查詢表,用來計算某狀態下做某行為後未來可以期望得到最大的Reward為多少。這個表可以導出每個State下,最好的Action。
----

<!--  -->
----
<h3 style='color:#C4C400'>定義狀態</h3>
- <span> 蛇的頭跟食物的相對位置(不好) <!-- .element: class="fragment" data-fragment-index="1" --></span>
- <span> 蛇的頭跟食物的相對位置 + 身體的位置(不好) <!-- .element: class="fragment" data-fragment-index="2" --></span>
- <span> 蛇的頭跟食物的相對位置 + 蛇的頭上下左右有沒有障礙物 <!-- .element: class="fragment" data-fragment-index="3" --></span>
<h3 style='color:red'>Qtable[(x,y),(l,r,u,d)] = [右, 左 ,下 ,上]<!-- .element: class="fragment" data-fragment-index="4" --></h3>
<span>(x,y)為蛇的頭跟食物的相對位置<!-- .element: class="fragment" data-fragment-index="4" --></span>
<span>(l,r,u,d)為蛇的頭上下左右有沒有障礙物<!-- .element: class="fragment" data-fragment-index="4" --></span>
<span>[右, 左 ,下 ,上] 做4個動作所得到的價值<!-- .element: class="fragment" data-fragment-index="4" --></span>
----
<h3 style='color:#C4C400'>設定reward</h3>
- 撞到身體(-150)
- 撞到牆壁(-150)
- 拿到獎勵(200)
- 每走一步(-1)
----
<h3 style='color:#C4C400'>更新Qtable</h3>
:::success
$$Q(s,a)=Q(s,a) + \alpha(r + \gamma maxQ(s',a') - Q(s,a))$$
:::
- q(s,a) 在s狀態執行a動作的價值
- α 學習率
- r 獎勵
- γ 衰變值
----
<h3 style='color:#C4C400'> 基於狀態的自主決策系統 </h3>
- <span>只需要根據當前的state,查詢Qtable
例如:當前的state為[(1,2),(0,0,0,1)]
也就是和食物距離(1,2)然後上面有障礙物<!-- .element: class="fragment" data-fragment-index="1" -->
</span>
- <span>所以查詢Qtable,會得到選擇[右, 左 ,下 ,上]的值
只要選擇最大值即為當前最好的選擇<!-- .element: class="fragment" data-fragment-index="2" --></span>
- <span>最後依照公式更改Qtable<!-- .element: class="fragment" data-fragment-index="3" --></span>
----
<h3 style='color:#C4C400'>成果展示</h3>
--->[程式碼傳送門](https://hackmd.io/@HIPP0/BybEcF1B3)<---
---
<h2 style='color:#C4C400'>總結</h2>
----
<h3 style='color:#C4C400'>過程中遇到的問題</h3>
- python深複製/淺複製
```python=
# 淺複製
body = self.snake_body.copy()
```
```python=
# 深複製
import copy
body = copy.deepcopy(self.snake_body)
```
----
<h3 style='color:#C4C400'>訓練結果</h3>
- 在4000次訓練當中,貪吃蛇可以穩定達到30以上(MAX)
- (人類)微信50場中,目前最高29
- (微信不服,在後續n場之後拿到36分)
- 訓練結果與一般人大約相同
- 訓練時間不到1分鐘
----

----
<h3 style='color:#C4C400'>如何改進</h3>
- State改變
- 調參數
- 其他方式 (ex: Deep Q learning)
---
# Thanks
{%hackmd /@hipp0/Hippotumuxthem %}
{"metaMigratedAt":"2023-06-18T03:40:21.415Z","metaMigratedFrom":"YAML","breaks":true,"slideOptions":"{\"theme\":\"night\",\"transition\":\"fade\"}","description":"在遊戲中,玩家操控一條細長的直線(俗稱蛇)","title":"python_QL貪吃蛇","contributors":"[{\"id\":\"b4bc52a4-04a8-4c6d-920a-32b9ab31a7f9\",\"add\":10995,\"del\":5521}]"}