C47_2 多邊形— nested loop(巢狀迴圈) 練習
題目
練習
直角三角形
- 由於外層迴圈控制了行數,所以內層迴圈的執行次數也與行數相對應。
- 在內層迴圈中,將 🟡 加入到
content
中,每次內層迴圈執行時都會根據i的值
的增加,而逐步添加 🟡 到 。 - 當行數為 1 時,內層迴圈執行 1 次,添加一個 🟡,當行數為 2 時,內層迴圈執行 2 次,依次添加兩個 🟡 ;以此類推,直到行數達到
count
的值。
// 直角三角形
func rightTriangle() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
for i in 1...count {
for _ in 1...i { // 根據行數 i 的值來控制每行中的 🟡
content += "🟡"
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
倒直角三角形
- 行與列的次數相反
- 外層迴圈控制行數。迴圈從 1 開始,執行到
count
的值。 - 內層迴圈控制每行中的符號個數。迴圈從
i
的值開始,執行到count
的值。 - 在內層迴圈中,每次迴圈執行時,將一個 “🟡” 添加到
content
字串中。列數
的執行次數根據i
的值而減少。
// 倒直角三角形
func antiRightTriangle() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
for i in 1...count { // 行數迴圈從 1 開始,執行到 count 的值。
for _ in i...count { // 列數迴圈從 i 的值開始,執行到 count 的值。
content += "🟡"
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
兩個emoji的直角三角形
- 本質上它是由矩形構成的。
- 根據內層迴圈的條件判斷,如果行數
i
大於列數j
,則添加一個 "⚫️";否則,添加一個 "🟡"。 - 雖然形狀本質上是一個矩形,但由於符號的顯示方式和視覺效果,看起來像是一個直角三角形。這是通過在不同的位置上使用不同的符號來達到的。
// 直角三角形兩個圖案
func twoPatternTriangle() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
for i in 1...count { // 行數的迴圈
for j in 1...count { // 列數的迴圈
if i > j { // 如果 行數 > 列數,添加一個 "⚫️"。
content += "⚫️"
} else {
content += "🟡" // 否則,添加一個黃色正方形符號 "🟡"。
}
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
畫金字塔
- 外層迴圈
for i in 1...count
控制金字塔的行數。迴圈從 1 開始,執行到count
的值,每次迴圈增加一行。 - 內層迴圈
for _ in i..<count
在當前行中添加黑色圓圈符號 "⚫️"。該迴圈從i
開始,執行到count
的前一個值,每次迴圈在當前行添加一個黑色圓圈符號。 let pyramidNumber = i * 2 - 1
計算當前行的金字塔部分 "🟡" 應該有多少個。金字塔部分的個數根據行數i
進行計算。- 內層迴圈
for _ in 1...pyramidNumber
在當前行中添加 "🟡"。該迴圈從 1 開始,執行到pyramidNumber
的值,每次迴圈在當前行添加一個”🟡”。
// 金字塔
func pyramidPattern() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
for i in 1...count { // 每次迭代都會增加一行到金字塔中。
for _ in i..<count { // 從 i 到 count(不含 count),每次迭代都會在當前行添加一個 "⚫️"。
content += "⚫️"
}
let pyramidNumber = i * 2 - 1 // 計算當前行的金字塔部分("🟡")應該有多少個。
for _ in 1...pyramidNumber { // 從 1 到 pyramidNumber 迴圈,每次迭代都會在當前行添加一個 "🟡"。
content += "🟡"
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
let pyramidNumber = i * 2 - 1
的目的是計算每一層金字塔圖案中連續🟡符號的個數,以確保金字塔圖案的結構正確。
pyramidNumber 的值表示每一層金字塔圖案中連續符號的個數。
根據公式 i * 2 - 1,可以觀察到以下特點:
當 i 為 1 時,number 的值為 1。
當 i 為 2 時,number 的值為 3。
當 i 為 3 時,number 的值為 5。
以此類推,每增加一行,number 的值就會增加 2。
- 請AI模擬流程
如果 count 為 3,將會有三行。在每一行中,"⚫️" 的數量由 count - i 決定。
而 "🟡" 的數量由 i * 2 - 1 決定。以下是逐行的解釋:
在第一行 (i = 1),會有 3 - 1 = 2 個 "⚫️" 和 1 * 2 - 1 = 1 個 "🟡"。
在第二行 (i = 2),會有 3 - 2 = 1 個 "⚫️" 和 2 * 2 - 1 = 3 個 "🟡"。
在第三行 (i = 3),會有 3 - 3 = 0 個 "⚫️" 和 3 * 2 - 1 = 5 個 "🟡"。
所以,如果 count 為 3,content 字串將如下所示:
⚫️⚫️🟡\n
⚫️🟡🟡🟡\n
🟡🟡🟡🟡🟡\n
三角形
emojiCount
決定了每一行有多少個 "🟡"。- 接著開始 for 迴圈,迴圈的次數由用戶輸入的數字的兩倍減一決定。
- 在每次迴圈中,我們會添加一行三角形中。
- 每行中,根據 emojiCount 的值,添加相應數量的 “🟡”。
- 在接近三角形的頂點之前(即
i < count
),每行的 "🟡" 數量(emojiCount)會遞增;一旦超過頂點(即i >= count
),每行的 "🟡" 數量會遞減,形成一個三角形的形狀。
// 三角形
func equiangularTriangle() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
var emojiCount = 1 // 初始化一個數量變數,用於決定每行要放置多少個🟡。
for i in 1...count*2-1 { // 1 到 count*2-1 的迴圈,決定行數迴圈的次數。
for _ in 1...emojiCount { // 1 到 emojiCount 的迴圈,每次迴圈都會在 當前行 添加一個 "🟡"。
content += "🟡"
}
if i < count { // 如果沒有達到三角形的頂點,就增加emojiCount,否則減少 emojiCount。
emojiCount += 1
} else {
emojiCount -= 1
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
emojiCount
- 當開始構建三角形時,希望從一個 “🟡” 開始(也就是三角形的頂點),然後每次迴圈,增加一個 “🟡”,直到達到指定的
count
數量。因此將emojiCount
初始化為 1。 - 當
i
(也就是當前行數)小於count
時,增加 "🟡" 的數量,所以emojiCount
每次都增加 1。 - 而當
i
達到或超過count
時,減少 "🟡" 的數量,所以emojiCount
每次都減少 1。
這樣可以創建三角形的模式,它的頂點有一個 “🟡”,然後每行向下遞增到 count
數量的 "🟡",然後再遞減回到一個 "🟡"。這就是為什麼需要設置 var emojiCount = 1
的原因。
如果 count 為 4,得到一個三角形,有 7 行。
前四行每行的 "🟡" 數量遞增,後三行每行的 "🟡" 數量遞減。
以下是詳細的行列:
第一行(i = 1),emojiCount = 1,有一個 "🟡"。
第二行(i = 2),emojiCount = 2,有兩個 "🟡"。
第三行(i = 3),emojiCount = 3,有三個 "🟡"。
第四行(i = 4),emojiCount = 4,有四個 "🟡"。
第五行(i = 5),emojiCount = 3,有三個 "🟡"。
第六行(i = 6),emojiCount = 2,有兩個 "🟡"。
第七行(i = 7),emojiCount = 1,有一個 "🟡"。
🟡\n
🟡🟡\n
🟡🟡🟡\n
🟡🟡🟡🟡\n
🟡🟡🟡\n
🟡🟡\n
🟡\n
菱形
- 結合前面兩題的概念
從滑桿中選擇的數字 count
來確定菱形的大小。這個數字決定了菱形的行數
和最大寬度
。
- 在主迴圈中,
blackBallCount
的數量會在每一次迭代時減少 1,而yellowBallCount
的數量則會在每一次迭代時增加 2,直到達到菱形的最高點。 - 首先,
blackBallCount
的初始值為count - 1
,表示第一行有count - 1
個 ⚫️ 。隨著主迴圈的進行,每一行的 ⚫️ 數量都會減少 1。 - 同時,
yellowBallCount
的初始值為 1,表示第一行有 1 個 🟡。隨著主迴圈的進行,每一行的 🟡 數量都會增加 2。 - 當迭代達到菱形的最高點(第
count
行)之後,blackBallCount
開始增加 1,而yellowBallCount
開始減少 2。這樣就形成了菱形的上半部分,⚫️ 數量逐漸增加,而 🟡 數量逐漸減少。 - 因此,通過這種方式,每一行中的 ⚫️ 和 🟡 的數量都在根據行數的不同進行調整,從而創建出菱形的圖案。
func diamondPattern() {
let count = Int(emojiSliderControl.value) // 將slider值轉為整數。
countValueLabel.text = "\(count)" // 將 count 的值做當前數值顯示。
var content = "" // 用於存儲生成的圖案內容。
var blackBallCount = count - 1 // 用於追蹤每行 "⚫️" 的數量
var yellowBallCount = 1 // 用於追蹤每行 "🟡" 的數量
for i in 1...count*2-1 { // 主迴圈用來創建菱形的每一行。
for _ in 0..<blackBallCount { // 第一個子迴圈在每一行中添加一定數量的 "⚫️"。
content += "⚫️"
}
for _ in 1...yellowBallCount { // 第二個子迴圈在每一行中添加一定數量的 "🟡"。
content += "🟡"
}
if i < count { // 判斷是否達到菱形的最高點。
blackBallCount -= 1 // 在達到最高點之前,每行 "⚫️" 的數量遞減。
yellowBallCount += 2 // 在達到最高點之前,每行 "🟡" 的數量遞增。
} else { // 達到最高點後,"⚫️" 的數量遞增,"🟡" 的數量遞減。
blackBallCount += 1
yellowBallCount -= 2
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
- 模擬流程
如果 count 為 3,函數 diamondPattern 將會生成一個五行的菱形模式,以下是每行的詳細情況:
第一行(i = 1),blackBallCount = 2, yellowBallCount = 1。 所以有兩個 "⚫️" 和一個 "🟡"。
第二行(i = 2),blackBallCount = 1, yellowBallCount = 3。 所以有一個 "⚫️" 和三個 "🟡"。
第三行(i = 3),blackBallCount = 0, yellowBallCount = 5。 所以有五個 "🟡"。
第四行(i = 4),blackBallCount = 1, yellowBallCount = 3。 所以一個 "⚫️" 和三個 "🟡"。
第五行(i = 5),blackBallCount = 2, yellowBallCount = 1。 所以有兩個 "⚫️" 和一個 "🟡"。
⚫️⚫️🟡\n
⚫️🟡🟡🟡\n
🟡🟡🟡🟡🟡\n
⚫️🟡🟡🟡\n
⚫️⚫️🟡\n
Chatgpt補充:如何觀察
以菱形模式為例,如果手動繪製 count = 3
的情況,可以看到以下的模式:
⚫️⚫️🟡\n
⚫️🟡🟡🟡\n
🟡🟡🟡🟡🟡\n
⚫️🟡🟡🟡\n
⚫️⚫️🟡\n
觀察需注意的點:
- 菱形模式的上半部分和下半部分是對稱的。
- 菱形模式中的每行, “🟡” 的數量從1開始,到
count
的兩倍減1,然後再縮減到1。 - 同時,"⚫️" 的數量從
count - 1
開始,逐漸減少到0,然後再增加到count - 1
。
- 這就是設計迴圈和條件判斷的依據。我們設計迴圈以使其能夠繪製每一行,並在每一行中添加適當數量的 “⚫️” 和 “🟡”。
- 我們也添加了條件判斷,以確定何時停止增加 “🟡” 的數量並開始減少,以及何時開始增加 “⚫️” 的數量。
總的來說,編寫此類程式的關鍵在於觀察並理解你試圖模擬的模式的結構和規律。一旦理解了這些規律,就可以編寫代碼來模擬它們。
每排顯示不同圖案
- 我的slider最小值以及起始值是1。
- 設置emojis的陣列,陣列的索引值是由0開始,而不是從 1 開始。
- 外層迴圈範圍
i in 0..<count
:要從一個陣列中取得元素,需要從 0 開始數。這就是為什麼在外層迴圈中使用了0..<count
。這樣,第一次迴圈時,會獲得emojis
陣列中的第一個元素。 - 內層迴圈的範圍
1...(i+1)
:原因是想要在每一行生成等於行數的表情符號數量
。 - 因為我的行數從 1 開始(
i
在這裡代表行數,但由於我們的迴圈從 0 開始,所以需要加 1)。 - 因為
i in 0..<count
,所以第一行(i = 0
)有 1 個表情符號,第二行(i = 1
)有 2 個表情符號,以此類推。
// 每排顯示不同圖案
func rowDifferentPattern() {
let count = Int(emojiSliderControl.value) // 取得滑桿的值,轉換為整數
countValueLabel.text = "\(count)" // 將 count 的值顯示在畫面上
var content = "" // 添加的內容
let emojis = ["🟡", "🔵", "🟢", "🔴"] // 定義一個 emoji 的陣列。
for i in 0..<count { // 外層迴圈用於產生每一行。
for _ in 1...(i+1) { // 內層迴圈用於在每一行中添加表情符號。
let emoji = emojis[i % emojis.count] // 確定要添加的表情符號,取決於當前的行數 i。
content += emoji // 將選定的表情符號添加到內容字串中。
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
- 如果
count
為 4,每行的表情符號數量分別為 1, 2, 3, 4,並且從emojis
陣列中選取的表情符號分別為第 1, 2, 3, 4 個。
假設 count 的值是 4:
- 外部迴圈的索引
i
實際上是從 0 開始,而不是 1。因為for i in 0..<count
,這個迴圈將從 0 開始,直到count - 1
。因此,當count
等於 1 時,i
會等於 0,i+1
就會等於 1,所以第一行只會有一個表情符號。 - 每一行的表情符號數量是
i+1
,選擇的表情符號是 emojis 陣列的i % emojis.count
索引。
- ChatGPT補充:對於我的slider起始值為1的狀況下。
在你的滑桿起始值為 1 的情況下,這是你的程式碼會如何運行的:
count 會等於 1(你的滑桿的值)。在 for i in 0..<count 迴圈中,i 會從 0 運行到 count - 1,所以 i 只會等於 0。
然後,在 for _ in 1...(i+1) 迴圈中,這個迴圈會運行 i+1 次,也就是 1 次(因為 i 是 0)。所以,你只會添加一個表情符號到 content 中。
所以,根據你的程式碼,滑桿的起始值為 1 的時候,你的程式碼會生成一行,並且這一行只有一個表情符號(🟡)。
每排顯示不同圖案2
let number = (emojiCount - 1) / 2
的目的在於計算目前這一行中要顯示的表情符號的數量。因為每一行的表情符號是對稱的,所以我們將這個數量分成兩半來處理,這樣就可以更簡單地生成對稱的圖案。
- 子迴圈
(for j in 0…number)
:這個子迴圈負責在每一行中添加正確數量和順序的表情符號。它的迴圈範圍是從 0 到number
,number
的值是(emojiCount - 1) / 2
。 - 子迴圈
(for j in 0..<number)
:這個子迴圈負責在每一行中添加反向順序的表情符號。迴圈範圍是從 0 到number-1
。在每次迭代中,從emojis
陣列中根據索引(number-1-j)
取出表情符號。
這兩個子迴圈的結果是在每一行中按照正向和反向順序添加表情符號,形成菱形圖案的一部分。
以count為 3 時候,執行三行的流程:慢慢去與ChatGPT 修正才寫出來 XD
⬜️⬜️🟡
⬜️🟡🔵🟡
🟡🔵🟢🔵🟡
⬜️🟡🔵🟡
⬜️⬜️🟡
- 主迴圈的第一次迭代(
i
為1):
- 子迴圈1:由於
squareCount
的初始值為2(count-1
),所以進入子迴圈1,迴圈內容為添加2個⬜️(即"⬜️⬜️")。 let number = (emojiCount - 1) / 2
:計算得到number
的值為0。- 子迴圈2:由於
number
的值為0,所以進入子迴圈2,迴圈內容為添加1個emojis(根據索引0選取陣列中的第一個元素,即"🟡")。 - 子迴圈3:由於
number
的值為0,不滿足迴圈條件,因此不進入子迴圈3。 - 減少⬜️的數量:由於
i
小於count
(1小於3),所以將squareCount
減少1,變為1。 - 增加
球
的數量:由於i
小於count
(1小於3),所以將emojiCount
增加2,變為3。 - 將內容插入換行符號:將換行符號”\n”添加到
content
中。 - 完成第一次迭代後,
content
的內容為:"⬜️⬜️🟡\n"
2 . 主迴圈的第二次迭代(i
為2):
- 子迴圈1:由於
squareCount
的值為1,所以進入子迴圈1,迴圈內容為添加1個⬜️(即"⬜️")。 let number = (emojiCount - 1) / 2
:計算得到number
的值為1。- 子迴圈2:由於
number
的值為1,所以進入子迴圈2,迴圈內容為添加2個emojis符號(根據索引0、1選取emojis陣列中的元素,即"🟡🔵")。 - 子迴圈3:由於
number
的值為1,所以進入子迴圈3,迴圈內容為添加1個emojis符號(根據索引0選取陣列中的第一個元素,即"🟡")。 - 減少 ⬜️的數量:由於
i
小於count
(2小於3),所以將squareCount
減少1,變為0。 - 增加
球
的數量:由於i
小於count
(2小於3),所以將emojiCount
增加2,變為5。 - 將內容插入換行符號:將換行符號”\n”添加到
content
中。 - 完成第二次迭代後,
content
的內容為:"⬜️🟡🔵🟡\n"
3. 主迴圈的第三次迭代(i
為3):
- 子迴圈1:由於
squareCount
的值為0,不滿足迴圈條件,不進入子迴圈1。 let number = (emojiCount - 1) / 2
:計算得到number
的值為2。- 子迴圈2:由於
number
的值為2,所以進入子迴圈2,迴圈內容為添加3個emojis(根據索引0、1、2選取陣列中的元素,即"🟡🔵🟢")。 - 子迴圈3:由於
number
的值為2,所以進入子迴圈3,迴圈內容為添加2個表情符號(根據索引1、0選取陣列中的元素,即"🔵🟡")。 - 此時 i 為4的關係已經大於count。
- 增加⬜️的數量:squareCount = 0 +1。
- 減少
球
的數量:emojiCount = 5 – 2。 - 完成第三次迭代後,
content
的內容為:"🟡🔵🟢🔵🟡\n"
4. 主迴圈的第四次迭代(i
為4):
- 子迴圈1:由於
squareCount
的值為1,所以進入子迴圈1,迴圈內容為添加1個⬜️(即"⬜️")。 let number = (emojiCount - 1) / 2
:計算得到number
的值為1。- 子迴圈2:由於
number
的值為1,所以進入子迴圈2,迴圈內容為添加2個emojis(根據索引0、1選取陣列中的元素,即"🟡🔵")。 - 子迴圈3:由於
number
的值為1,所以進入子迴圈3,迴圈內容為添加1個表情符號(根據索引0選取表情符號陣列中的第一個元素,即"🟡")。 - 此時 i 為4的關係已經大於count。
- 增加⬜️的數量:squareCount = 1 +1。
- 減少
球
的數量:emojiCount = 3 – 2。 - 完成第四次迭代後,
content
的內容為::”⬜️🟡🔵🟡”
5 .主迴圈的第五次迭代(i
為5):
- 子迴圈1:由於
squareCount
的值為2,所以進入子迴圈1,迴圈內容為添加2個⬜️(即"⬜️⬜️")。 let number = (emojiCount - 1) / 2
:計算得到number
的值為0。- 子迴圈2:由於
number
的值為0,所以進入子迴圈2,迴圈內容為添加1個emojis(根據索引0選取陣列中的第一個元素,即"🟡")。 - 子迴圈3:由於
number
的值為0,不滿足迴圈條件,因此不進入子迴圈3。 - 增加⬜️的數量:由於
i
大於count
(5大於3),所以將squareCount
增加1,變為3。 - 減少
球
的數量:由於i
大於count
(5大於3),所以將emojiCount
減少2,變為1。 - 將內容插入換行符號:將換行符號”\n”添加到
content
中。 - 完成第五次迭代後,
content
的內容應為:"⬜️⬜️🟡"
// 每排顯示不同圖案(菱形)
func differentRowDiamondPattern() {
let count = Int(emojiSliderControl.value) // 取得滑桿的值,轉換為整數
countValueLabel.text = "\(count)" // 將 count 的值顯示在畫面上
var content = "" // 添加的內容
let emojis = ["🟡", "🔵", "🟢", "🔴"] // 定義一個 emoji 的陣列,用來在模式中循環使用。
var squareCount = count - 1 // 初始化⬜️的數量,每行前面的⬜️數量
var emojiCount = 1 // 初始化 emoji 的數量,用來控制每一行的 emoji 數量。
for i in 1...count*2-1 { // 主迴圈,進行兩次 count 次數(-1)的循環,以生成菱形。
for _ in 0..<squareCount { // 子迴圈,在每一行開頭添加適當數量的⬜️狀。
content += "⬜️"
}
let number = (emojiCount - 1) / 2
for j in 0...number { // 子迴圈,負責在每一行中添加正確數量和順序的表情符號。
content += emojis[j % emojis.count] // 使用 % 符號來確保索引不會超出表情符號陣列的範圍。
}
for j in 0..<number {
content += emojis[(number-1-j) % emojis.count]
}
if i < count { // 生成菱形的上半部,則減少 ⬜️ 並增加 emoji 數量。
squareCount -= 1
emojiCount += 2
} else { // 生成菱形的下半部,則增加 ⬜️ 並減少 emoji 數。
squareCount += 1
emojiCount -= 2
}
content += "\n" // 在內容的最後插入換行符號,以形成每行增加的效果。
}
// 將內容加到Label
displayEmojiLabel.text = content
}
簡單解釋:
當 count = 4,對於每一行,squareCount 和 emojiCount 的變化如下:
第一行:squareCount = 3, emojiCount = 1,所以有3個⬜️和1個表情符號。
第二行:squareCount = 2, emojiCount = 3,所以有2個⬜️和3個表情符號。
第三行:squareCount = 1, emojiCount = 5,所以有1個⬜️和5個表情符號。
第四行:squareCount = 0, emojiCount = 7,所以有0個⬜️和7個表情符號。
以上是菱形的上半部分,接下來是菱形的下半部分:
第五行:squareCount = 1, emojiCount = 5,所以有1個⬜️和5個表情符號。
第六行:squareCount = 2, emojiCount = 3,所以有2個⬜️和3個表情符號。
第七行:squareCount = 3, emojiCount = 1,所以有3個⬜️和1個表情符號。
在 i < count 的情況下,會每行減少一個⬜️ 並增加 兩個表情符號。
當 i >= count 時,則會每行增加一個⬜️ 並減少 兩個表情符號,以產生菱形的下半部分。
⬜️⬜️⬜️🟡
⬜️⬜️🟡🔵🟡
⬜️🟡🔵🟢🔵🟡
🟡🔵🟢🔴🟢🔵🟡
⬜️🟡🔵🟢🔵🟡
⬜️⬜️🟡🔵🟡
⬜️⬜️⬜️🟡
GitHub
參考