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
陣列中的每個棋子物件。對於每個棋子,它檢查該棋子的行數和列數是否與當前的迴圈索引值 (row
和 column
) 相符。如果是相符的,則建立一個 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