最近笔者在看斯坦福的ios课程,使用xcode+swift的配置
前三课入口:
https://blog.csdn.net/qq_36711094/article/details/113428347
第四课:主要讲述set、get方法,断言assert,讲述private\private(set)等关键词的概念,并描述了eume的概念
下面上代码
//
// Concentration.swift
// stanford_test_one
//
// Created by 王** on 2021/1/27.
//
import Foundation
class Concentration
{
private(set) var cards = [Card]()
private var indexOfOneAndOnlyFaceUpCard : Int?{
//第四课使用get、set方法
//定义get、set方法,获取index
get{
//初始化,如果只有一张卡被翻到正面,即isFaceUP == true,那就让唯一一张正面朝上的标识indexOfOneAndOnlyFaceUpCard 等于这个卡的index,否则就将indexOfOneAndOnlyFaceUpCard 置为nil
var foundIndex :Int?
for index in cards.indices{
if cards[index].isFaceUP{
if foundIndex == nil{
foundIndex = index
}else{
return nil
}
}
}
return foundIngex
}
set{
for index in cards.indices{
//赋值操作index == newValue总是flase的,即将所有正面朝上的翻转过去
cards[index].isFaceUP = (index == newValue)
}
}
}
func chooseCard (at index: Int){
assert(cards.indices.contains(index),"Concentration.chooseCard (at: \(index)) : choosen index not in the cards ")
if !cards[index].isMatched{
if let matchIndex = indexOfOneAndOnlyFaceUpCard,matchIndex != index{
if cards[matchIndex].identifier == cards[index].identifier{
cards[matchIndex].isMatched = true
cards[index].isMatched = true
}
cards[index].isFaceUP = true
//学到第四课,这里不需要再进行indexOfOneAndOnlyFaceUpCard 的初始化,虽然我们进行两张卡片匹配的操作是需要对indexOfOneAndOnlyFaceUpCard 进行初始化的,原因就是由于我们使用了get进行获取,并初始化indexOfOneAndOnlyFaceUpCard
//indexOfOneAndOnlyFaceUpCard = nil
}
else{
//这里也不在需要进行全部翻转为反面的操作,在indexOfOneAndOnlyFaceUpCard = index时即调用了set方法,set方法中进行了翻转操作,这里只需要进行indexOfOneAndOnlyFaceUpCard 唯一向上标识的确定 即将index复制给indexOfOneAndOnlyFaceUpCard
// for filpDownIndex in cards.indices{
//
// cards[filpDownIndex].isFaceUP = false
// }
// cards[index].isFaceUP = true
indexOfOneAndOnlyFaceUpCard = index
}
}
//翻牌测试
// if cards[index].isFaceUP {
// cards[index].isFaceUP = false
// }else{
// cards[index].isFaceUP = true
// }
//
}
init(numberOfPairsOfCards:Int) {
assert(numberOfPairsOfCards > 0,"Concentration.init (at: \(numberOfPairsOfCards)) : you must have an least one pairs of cards ")
for _ in 1...numberOfPairsOfCards{
//card是个结构体
let card = Card()
//将结构体赋值,即复制给matchingCard
//let matchingCard = card
// cards.append(card)
// cards.append(card)
//或者
cards += [card, card]
}
}
}
//
// Card.swift
// stanford_test_one
//
// Created by 王** on 2021/1/27.
//
import Foundation
struct Card
{
var isFaceUP = false
var isMatched = false
var identifier :Int
private static var indentifierFactory = 0
private static func getUniqueIndentifier()-> Int{
indentifierFactory += 1
return indentifierFactory
}
init() {
self.identifier = Card.getUniqueIndentifier()
}
}
//
// ViewController.swift
// stanford_test_one
//
// Created by 王** on 2021/1/26.
//
import UIKit
class ViewController: UIViewController
{
//第四课讲述成员变量使用权限
private lazy var game = Concentration(numberOfPairsOfCards: numberOfPairsOfCards)
//第四课使用get、set方法传值s
var numberOfPairsOfCards:Int{
return (cardButtons.count + 1) / 2
}
private(set) var filpCount = 0
{
didSet{
flipCountLable.text = "Flip: \(filpCount)"
}
}
@IBOutlet private weak var flipCountLable: UILabel!
@IBOutlet private var cardButtons: [UIButton]!
@IBAction private func touchCard(_ sender: UIButton) {
filpCount += 1
if let cardNumber = cardButtons.firstIndex(of: sender) {
//print("cardNumber = \(cardNumber)")
//翻转操作
game.chooseCard(at: cardNumber)
//从模型更新视图
updateViewFromMoudel()
}else{
print("choose cardNumber")
}
}
private func updateViewFromMoudel(){
//在cardButtons卡牌按钮中轮询
for index in cardButtons.indices{
//定义常量button 是被选择的卡牌按钮,定义常量card 是卡牌组中被选择的卡牌
let button = cardButtons[index]
let card = game.cards[index]
//如果卡卡牌正面朝上,那就设置为正面朝上的样子,调用setTitle修改卡牌的展示,这里使用emoji方法进行设置
if card.isFaceUP{
button.setTitle(emoji(for: card), for: UIControl.State.normal)
button.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
}else{
//如果卡片被面朝上那就将展示清空,并将颜色设置为orange
button.setTitle("", for: UIControl.State.normal)
button.backgroundColor = card.isMatched ? #colorLiteral(red: 1, green: 0.5763723254, blue: 0, alpha: 0) : #colorLiteral(red: 1, green: 0.5763723254, blue: 0, alpha: 1)
}
}
}
private var emojiChoise = ["👻","🦇","🙀","🎃","🍬", "🍭","🍎","😈","😱"]
//var emoji = Dictionary<Int,String>()
//定义emoji 是一个String字符型数组
private var emoji = [Int:String]()
private func emoji(for card: Card)-> String{
// if emoji[card.identifier] != nil{
// return emoji[card.identifier]!
// }else{
// return "?"
// }
//等价
//如果card的标识为nil并且emojiChoise中不为空,那就将emojiChoise通过arc4random随机出来的字符复制给emoji[card.identifier]
if emoji[card.identifier] == nil, emojiChoise.count > 0{
emoji[card.identifier] = emojiChoise.remove(at: emojiChoise.count.arc4random)
}
//返回emoji[card.identifier]给卡牌去展示
return emoji[card.identifier] ?? "?"
}
}
//第四课讲述使用拓展的方法
extension Int{
var arc4random :Int{
if self > 0{
return Int(arc4random_uniform(UInt32(self)))
}else if self < 0{
return -Int(arc4random_uniform(UInt32(self)))
}else{
return 0
}
}
}