2023年4月21日 星期五

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

作者:楊于葳




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




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

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


一、指令

(一)簡介


(二)發出指令





  1. moveForward()
  2. moveForward()
  3. moveForward()
  4. collectGem()


(三)切換開關





  1. moveForward()
  2. moveForward()
  3. turnLeft()
  4. moveForward()
  5. collectGem()
  6. moveForward()
  7. turnLeft()
  8. moveForward()
  9. moveForward()
  10. toggleSwitch()


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





  1. moveForward()
  2. moveForward()
  3. turnLeft()
  4. moveForward()
  5. collectGem()
  6. moveForward()
  7. toggleSwitch()


二、For 迴圈

(一)簡介


(二)使用迴圈





  1. for i in 1 ...5 {
  2. moveForward()
  3. moveForward()
  4. collectGem()
  5. moveForward()
  6. }


(三)迴圈每一側





  1. for i in 1 ... 4 {
  2. moveForward()
  3. collectGem()
  4. moveForward()
  5. moveForward()
  6. moveForward()
  7. turnRight()
  8. }


三、條件碼

(一)簡介


(二)檢查開關





  1. moveForward()
  2. moveForward()
  3. if isOnClosedSwitch{
  4. toggleSwitch()
  5. }
  6. moveForward()
  7. if isOnClosedSwitch{
  8. toggleSwitch()
  9. }
  10. moveForward()
  11. if isOnClosedSwitch{
  12. toggleSwitch()
  13. }


(三)使用 else if





  1. moveForward()
  2. if isOnGem{
  3. collectGem()
  4. } else if isOnClosedSwitch{
  5. toggleSwitch()
  6. }
  7. moveForward()
  8. if isOnGem{
  9. collectGem()
  10. } else if isOnClosedSwitch{
  11. toggleSwitch()
  12. }


(四)符合條件時往上爬





  1. for i in 1 ... 3 {
  2. if isOnGem {
  3. collectGem()
  4. } else {
  5. moveForward()
  6. }
  7. }
  8. turnLeft()
  9. for i in 1 ... 5 {
  10. if isOnGem {
  11. collectGem()
  12. } else {
  13. moveForward()
  14. }
  15. }
  16. turnLeft()
  17. for i in 1 ... 3 {
  18. if isOnGem {
  19. collectGem()
  20. } else {
  21. moveForward()
  22. }
  23. }
  24. turnLeft()
  25. for i in 1 ... 5 {
  26. if isOnGem {
  27. collectGem()
  28. } else {
  29. moveForward()
  30. }
  31. }


四、邏輯運算子

(一)簡介


(二)使用 NOT 運算子





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


  1. for i in 1 ... 4 {
  2. moveForward()
  3. if isOnGem {
  4. collectGem()
  5. }else {
  6. turnLeft()
  7. moveForward()
  8. moveForward()
  9. collectGem()
  10. turnLeft()
  11. turnLeft()
  12. moveForward()
  13. moveForward()
  14. turnLeft()
  15. }




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


  1. for i in 1 ... 4 {
  2. moveForward()
  3. if !isOnGem {
  4. turnLeft()
  5. moveForward()
  6. moveForward()
  7. collectGem()
  8. turnLeft()
  9. turnLeft()
  10. moveForward()
  11. moveForward()
  12. turnLeft()
  13. }
  14. else {
  15. collectGem()
  16. }
  17. }


五、變數

(一)簡介


變數是用來儲存資訊的。


  1. var name = "Mia"
  2. var age = 19


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

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

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

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


(二)持續追蹤





  1. var gemCounter = 0
  2. moveForward()
  3. moveForward()
  4. collectGem()
  5. gemCounter = +1


(三)遞增數值





  1. var gemCounter = 0
  2. moveForward()
  3. for i in 1 ... 7 {
  4. if isOnGem {
  5. collectGem()
  6. gemCounter = +1
  7. moveForward()
  8. }else {
  9. moveForward()
  10. }
  11. }
  12. turnRight()
  13. for i in 1 ... 2 {
  14. if isOnGem {
  15. collectGem()
  16. gemCounter = +1
  17. moveForward()
  18. }else {
  19. moveForward()
  20. }
  21. }
  22. turnRight()
  23. for i in 1 ... 7 {
  24. if isOnGem {
  25. collectGem()
  26. gemCounter = +1
  27. moveForward()
  28. }else {
  29. moveForward()
  30. }
  31. }


六、類型

(一)簡介


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


(二)關閉傳送門





  1. greenPortal.isActive = true
  2.  
  3. moveForward()
  4. moveForward()
  5. while greenPortal.isActive {
  6. greenPortal.isActive = false
  7. moveForward()
  8. }
  9. for i in 1 ... 3 {
  10. turnRight()
  11. moveForward()
  12. moveForward()
  13. moveForward()
  14. toggleSwitch()
  15. turnRight()
  16. turnRight()
  17. moveForward()
  18. moveForward()
  19. moveForward()
  20. }


(三)設定正確的傳送門





  1. moveForward()
  2.  
  3. for i in 1 ... 6 {
  4. moveForward()
  5. if isOnGem {
  6. collectGem()
  7. }else {
  8. while isBlocked {
  9. turnRight()
  10. turnRight()
  11. while bluePortal.isActive {
  12. bluePortal.isActive = false
  13. }
  14. }
  15. }
  16. }
  17. bluePortal.isActive = true
  18. moveForward()
  19. moveForward()
  20. for i in 1 ... 2 {
  21. moveForward()
  22. if isOnGem {
  23. collectGem()
  24. }else {
  25. while isBlocked {
  26. turnRight()
  27. turnRight()
  28. moveForward()
  29. }
  30. }
  31. }
  32. bluePortal.isActive = false
  33. moveForward()
  34. turnRight()
  35. turnRight()
  36. pinkPortal.isActive = false
  37. moveForward()
  38. moveForward()
  39. collectGem()


七、初始化

(一)簡介


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






(二)初始化你的專家





  1. let expert = Expert()
  2. for i in 1 ... 3 {
  3. expert.moveForward()
  4. }
  5. expert.turnLockUp()
  6. while expert.isBlocked {
  7. expert.turnRight()
  8. expert.turnRight()
  9. expert.moveForward()
  10. expert.moveForward()
  11. expert.moveForward()
  12. }
  13. expert.turnLeft()
  14. for i in 1 ... 3 {
  15. expert.moveForward()
  16. expert.moveForward()
  17. expert.moveForward()
  18. expert.moveForward()
  19. expert.collectGem()
  20. while expert.isBlocked {
  21. expert.turnRight()
  22. expert.turnRight()
  23. expert.moveForward()
  24. expert.moveForward()
  25. expert.moveForward()
  26. }
  27. expert.turnLeft()
  28.  
  29. }


八、函數

(一)簡介



(二)收集、切換、重複





  1. func doIt(){
  2.     collectGem()
  3. moveForward()
  4. toggleSwitch()
  5. }
  6. moveForward()
  7. doIt()
  8. moveForward()
  9. turnLeft()
  10. moveForward()
  11. doIt()
  12. moveForward()
  13. moveForward()
  14. turnLeft()
  15. moveForward()
  16. doIt()
  17. moveForward()
  18. turnLeft()
  19. moveForward()
  20. doIt()


九、參數

(一)簡介


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






(二)繼續前行





  1. let expert = Expert()
  2. func move(distance: Int){
  3. for i in 1 ... distance{
  4. expert.moveForward()
  5. }
  6. }
  7. expert.move(distance:6)
  8. expert.turnRight()
  9. expert.move(distance:2)
  10. expert.turnRight()
  11. for i in 1 ... 2 {
  12. expert.move(distance:5)
  13. expert.turnLeft()
  14. }
  15. expert.turnLockUp()
  16. expert.turnLeft()
  17. for i in 1 ... 2 {
  18. expert.move(distance:3)
  19. expert.turnRight()
  20. }
  21. expert.move(distance:4)
  22. expert.collectGem()


(三)置於特定位置





  1. let expert = Expert()
  2. world.place(expert, atColumn: 1, row: 1)
  3. expert.collectGem()
  4. world.place(expert, atColumn: 6, row: 1)
  5. expert.collectGem()
  6. world.place(expert, atColumn: 1, row: 6)
  7. expert.collectGem()