WFU

2023年4月21日 星期五

Playgrounds 開始編寫程式碼:開始你的程式設計之旅

作者:楊于葳




Playgrounds 是 Apple 設計給想學 Swift 語言的初學者而設計的互動式教學程式,《開始編寫程式碼》就是其中一個主題,可以在 Mac 或 iPad 上操作,而且是繁體中文介面,雖然某些部分解釋的並不完全,但只要跟進度循序漸進,或者是直接動手操作看看,就能以遊戲化、視覺化的方式,更容易理解 Swift 語言的基本概念。以下是我在《開始編寫程式碼》的解題記錄。




「開始編寫程式碼」裡只有九大學習目標,每個目標裡面都有各自的實作子題,每一題都是以玩家的角度,配不同單元學到的概念,操作遊戲角色達到指定目的才能過關,例如:「獲得寶石」或「打開開關」。

在正式開始操作之前,每個「簡介」都會有視覺化、生活化與非常淺顯易懂例子,讓我們理解該目標的概念與使用方式,雖然說是破關遊戲,但實際上並沒有所謂的正確解答,達成目的的方式有很多種,系統也期待玩家可以使用不同的方式達到目的。


一、指令

(一)簡介


(二)發出指令





moveForward()
moveForward()
moveForward()
collectGem()


(三)切換開關





moveForward()
moveForward()
turnLeft()
moveForward()
collectGem()
moveForward()
turnLeft()
moveForward()
moveForward()
toggleSwitch()


(四)尋找並修正程式錯誤





moveForward()
moveForward()
turnLeft()
moveForward()
collectGem()
moveForward()
toggleSwitch()


二、For 迴圈

(一)簡介


(二)使用迴圈





for i in 1 ...5 {
    moveForward()
    moveForward()
    collectGem()
    moveForward()
    }


(三)迴圈每一側





for i in 1 ... 4 {
    moveForward()
    collectGem()
    moveForward()
    moveForward()
    moveForward()
    turnRight()
}


三、條件碼

(一)簡介


(二)檢查開關





moveForward()
moveForward()
    if isOnClosedSwitch{
        toggleSwitch() 
    }  
    moveForward()
if isOnClosedSwitch{
    toggleSwitch() 
}  
moveForward()
if isOnClosedSwitch{
    toggleSwitch() 
}  


(三)使用 else if





moveForward()
if isOnGem{
    collectGem()    
} else if isOnClosedSwitch{
    toggleSwitch()    
}
moveForward()
if isOnGem{
    collectGem()    
} else if isOnClosedSwitch{
    toggleSwitch()    
}


(四)符合條件時往上爬





for i in 1 ... 3 {
    if isOnGem {
        collectGem()
    } else {
        moveForward()
    }
}
turnLeft()
for i in 1 ... 5 {
    if isOnGem {
        collectGem()
    } else {
        moveForward()
    }
}
turnLeft()
for i in 1 ... 3 {
    if isOnGem {
        collectGem()
    } else {
        moveForward()
    }
}
turnLeft()
for i in 1 ... 5 {
    if isOnGem {
        collectGem()
    } else {
        moveForward()
    }
}


四、邏輯運算子

(一)簡介


(二)使用 NOT 運算子





第一次解出這題的時候,完全沒有使用到題目希望使用的 NOT,而是使用其他功能達到相同目的,系統也能夠偵測到是否有用教學的方式解題,如果使用其他方法,系統就會告訴你:「 恭喜你找到了一個有創意的解決方法!」


for i in 1 ... 4 {
    moveForward()    
    if isOnGem {
        collectGem()        
        }else {
        turnLeft()
        moveForward()
        moveForward()
        collectGem()
        turnLeft()
        turnLeft()
        moveForward()
        moveForward()
        turnLeft()  
    }




上圖是第二種解法「如果不在寶石處,就這麼做」。


for i in 1 ... 4 {
    moveForward()    
    if !isOnGem {
        turnLeft()
        moveForward()
        moveForward()
        collectGem()
        turnLeft()
        turnLeft()
        moveForward()
        moveForward()
        turnLeft()        
        }
    else {
        collectGem()        
    }
}


五、變數

(一)簡介


變數是用來儲存資訊的。


var name = "Mia"
var age = 19


如果要建立新變數,要使用 var,並在它後面加一個新的變數名稱和一個值。建立之後,該變數的資料類型,永遠不會改變。

指定值運算子(等號)會設定變數的值。

name 會儲存 String(引號中的文字)。

age 會儲存 Int (一個整數或整個數字)。


(二)持續追蹤





var gemCounter = 0
moveForward()
moveForward()
collectGem()
gemCounter = +1


(三)遞增數值





var gemCounter = 0
moveForward()
for i in 1 ... 7 {
    if isOnGem {
        collectGem() 
        gemCounter = +1
        moveForward()        
    }else {
        moveForward()        
    }
}
turnRight()
for i in 1 ... 2 {
    if isOnGem {
        collectGem() 
        gemCounter = +1
        moveForward()        
    }else {
        moveForward()        
    }
}
turnRight()
for i in 1 ... 7 {
    if isOnGem {
        collectGem()  
        gemCounter = +1
        moveForward()        
    }else {
        moveForward()        
    }
}


六、類型

(一)簡介


類型就是房子的藍圖,呈現了房子的特徵和動作。在類型中,功能稱為「屬性」(實際上只是在類型內部被定義的變數),動作增為「方法」(實際上只是在類型內部被定義的函數)。


(二)關閉傳送門





greenPortal.isActive = true

moveForward()
moveForward()
while greenPortal.isActive {
    greenPortal.isActive = false
    moveForward()
}
for i in 1 ... 3 {
    turnRight()
    moveForward()
    moveForward()
    moveForward()
    toggleSwitch()
    turnRight()
    turnRight()
    moveForward()
    moveForward()
    moveForward() 
}


(三)設定正確的傳送門





moveForward()

for i in 1 ... 6 {
    moveForward() 
    if  isOnGem {
        collectGem()
    }else {
        while isBlocked {
            turnRight()
            turnRight()
            while bluePortal.isActive {
                bluePortal.isActive = false
            }
        }
    }
}
bluePortal.isActive = true
moveForward()
moveForward()
for i in 1 ... 2 {
    moveForward() 
    if  isOnGem {
        collectGem()
    }else {
        while isBlocked {
            turnRight()
            turnRight()
            moveForward()            
            }
        }
    }
bluePortal.isActive = false
moveForward()
turnRight()
turnRight()
pinkPortal.isActive = false
moveForward()
moveForward()
collectGem()


七、初始化

(一)簡介


傳送門稱為 Portal 類型,我們的角色稱為 Character 類型,現在可以控制一個新的類型「Expert」,他有一個新方法(動作)叫做「turnLockUp()」。






(二)初始化你的專家





let expert = Expert()
for i in 1 ... 3 {
    expert.moveForward()
}
expert.turnLockUp()
while expert.isBlocked {
    expert.turnRight()
    expert.turnRight()
    expert.moveForward()
    expert.moveForward()
    expert.moveForward()
}
expert.turnLeft()
for i in 1 ... 3 {
    expert.moveForward()
    expert.moveForward()
    expert.moveForward()
    expert.moveForward()
    expert.collectGem()
    while expert.isBlocked {
        expert.turnRight()
        expert.turnRight()
        expert.moveForward()
        expert.moveForward()
        expert.moveForward()
    }
    expert.turnLeft()    

}


八、函數

(一)簡介



(二)收集、切換、重複





func doIt(){
    collectGem()
    moveForward()
    toggleSwitch()
    }
    moveForward()
    doIt()
    moveForward()
    turnLeft()
    moveForward()    
    doIt()
    moveForward()
    moveForward()    
    turnLeft()
    moveForward()    
    doIt()
    moveForward()
    turnLeft()
    moveForward()
    doIt()    


九、參數

(一)簡介


參數=建立選項。函數可以包括多個參數。






(二)繼續前行





let expert = Expert()
    func move(distance: Int){
    for i in 1 ... distance{
        expert.moveForward()
    }
    }
    expert.move(distance:6)
expert.turnRight()
expert.move(distance:2)
expert.turnRight()
for i in 1 ... 2 {
    expert.move(distance:5)
    expert.turnLeft()
}
expert.turnLockUp()
expert.turnLeft()
for i in 1 ... 2 {
    
    expert.move(distance:3)
    expert.turnRight()
}
expert.move(distance:4)
expert.collectGem()


(三)置於特定位置





let expert = Expert()
world.place(expert, atColumn: 1, row: 1)
expert.collectGem()
world.place(expert, atColumn: 6, row: 1)
expert.collectGem()
world.place(expert, atColumn: 1, row: 6)
expert.collectGem()