Ep.20[ wen’s iOS ] — 西洋棋棋盤的 nested loop 練習

本篇練習用巢狀迴圈寫出西洋棋盤並用 struct 儲存棋子資訊,再用 for loop 放置棋子。

再一次建立 struct 的概念並練習用巢狀迴圈建立靜態的西洋棋盤,struct 的概念還是很弱,希望藉由這次簡單的練習加深印象。

App 實作

Storyboard 建立

建立棋盤的 View:拉一個 UIView 的 IBoutlet 作為棋盤。

@IBOutlet weak var chessBoardView: UIView!

程式部分

棋盤是由 8 * 8 的方格製成,宣告方格 square 作為常數,數值為棋盤大小除以 8 。

let square = chessBoardView.frame.width / 8 // 每個方格的大小

外層迴圈控制橫排的行 ( y 值隨 row 改變),內層迴圈控制直排的列 ( x 值隨 column 改變 )。

if else (row + column) % 2 == 0 :西洋棋盤格子規律是彼此黑白相間。

// 迴圈用於建立棋盤上的每個方格
for row in 0...7 {
for column in 0...7 {
let chessSquareImageView = UIImageView(frame: CGRect(x: square * CGFloat(column), y: square * CGFloat(row), width: square, height: square))

// 根據棋盤位置設定方格的背景顏色
if (row + column) % 2 == 0 {
chessSquareImageView.backgroundColor = UIColor.brown
} else {
chessSquareImageView.backgroundColor = UIColor.systemBrown
}

chessBoardView.addSubview(chessSquareImageView)
}
}
}

Struct 建立

這個結構定義了一個 chessPiece 棋子的資料結構,具有以下屬性:

  • row:表示棋子所在的行數,為一個整數。
  • column:表示棋子所在的列數,可能有多列,以整數陣列的形式表示。
  • image:表示棋子的圖像表示,直接使用內建的 emoji ,型別為字串,如 "♟"、"♜"、"♞" 等。
struct chessPiece {
var row : Int
var column : [Int]
var image : String
}

接著這個陣列 pieces 儲存了多個棋子的資訊。每個元素都是一個 chessPiece 結構的實例,表示一個棋子的屬性。

 let pieces = [
chessPiece(row: 1, column: Array(0...7), image: "♟"), // 棋子的資訊
chessPiece(row: 0, column: [0, 7], image: "♜"),
chessPiece(row: 0, column: [1, 6], image: "♞"),
chessPiece(row: 0, column: [2, 5], image: "♝"),
chessPiece(row: 0, column: [3], image: "♛"),
chessPiece(row: 0, column: [4], image: "♚"),
chessPiece(row: 6, column: Array(0...7), image: "♙"),
chessPiece(row: 7, column: [0, 7], image: "♖"),
chessPiece(row: 7, column: [1, 6], image: "♘"),
chessPiece(row: 7, column: [2, 5], image: "♗"),
chessPiece(row: 7, column: [3], image: "♕"),
chessPiece(row: 7, column: [4], image: "♔")
]

這段程式碼在迴圈中遍歷 pieces 陣列中的每個棋子物件。對於每個棋子,它檢查該棋子的行數和列數是否與當前的迴圈索引值 (rowcolumn) 相符。如果是相符的,則建立一個 UILabel 來顯示西洋棋子,但是唯獨黑色士兵跟其他棋子長得差很多,不知道是發生什麼事 xd ; 我另外還調整了置中與 emoji 西洋棋大小,最後用 .addSubview 將棋子標籤添加到對應的棋盤方塊視圖 (chessSquareImageView) 中,以便將棋子顯示在正確的位置上。

for piece in pieces {
// 檢查棋子的行數和列數是否與當前的迴圈索引值(row, column)相符
if piece.row == row && piece.column.contains(column) {
// 建立一個 UILabel 來顯示棋子的圖像
let chessPieceLabel = UILabel(frame: CGRect(x: 0, y: 0, width: square, height: square))
chessPieceLabel.textAlignment = .center // 將文字置中對齊
chessPieceLabel.font = UIFont.systemFont(ofSize: square * 1) // 設定字體大小
chessPieceLabel.text = piece.image // 設定文字內容為棋子的圖像表示
chessSquareImageView.addSubview(chessPieceLabel) // 將棋子標籤添加到棋盤方塊的視圖中
}
}

這邊詢問 Chatgpt 新東西.cotains 的應用,可以用於檢查可選陣列的值是否存在,或是否包含特定物件。

補充:這種使用 $0 的方式稱為閉包簡寫(Closure Shorthand),它可以讓我們更簡潔地編寫閉包表達式,特別是在單行的簡單條件中。當在 .contains 的閉包中使用 $0 時,它代表陣列中的每個元素。

let numbers = [1, 2, 3, 4, 5]

// 檢查陣列中是否包含特定的元素
let containsThree = numbers.contains(3) // true
let containsTen = numbers.contains(10) // false

// 檢查字串陣列中是否包含特定的字串
let fruits = ["apple", "banana", "orange", "grape"]
let containsBanana = fruits.contains("banana") // true
let containsWatermelon = fruits.contains("watermelon") // false

// 檢查自訂物件陣列中是否包含特定物件
struct Person {
let name: String
let age: Int
}

let people = [
Person(name: "John", age: 25),
Person(name: "Sarah", age: 30),
Person(name: "Emily", age: 28)
]

let containsSarah = people.contains { $0.name == "Sarah" } // true
let containsAlex = people.contains { $0.name == "Alex" } // false

--

--