เจธเจตเจฟเจซเจŸ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ•เจพเจฐเจก เจ—เฉ‡เจฎ เจฒเจฟเจ–เจฃเจพ

เจธเจตเจฟเจซเจŸ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ•เจพเจฐเจก เจ—เฉ‡เจฎ เจฒเจฟเจ–เจฃเจพ

เจ‡เจน เจฒเฉ‡เจ– เจ‡เฉฑเจ• เจธเจงเจพเจฐเจจ เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจธเจฟเจ–เจฒเจพเจˆ เจ—เฉ‡เจฎ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจฆเจพ เจตเจฐเจฃเจจ เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจฟเจธเจฆเจพ เจฎเฉˆเจ‚ เจธเฉฑเจšเจฎเฉเฉฑเจš เจ…เจจเฉฐเจฆ เจฒเฉˆเจ‚เจฆเจพ เจนเจพเจ‚. เจ†เจชเจฃเฉ‡ เจ†เจช เจตเจฟเฉฑเจš เจšเฉฐเจ—เฉ‡ เจนเฉ‹เจฃ เจฆเฉ‡ เจ‡เจฒเจพเจตเจพ, เจคเฉเจธเฉ€เจ‚ เจœเจพเจ‚เจฆเฉ‡ เจธเจฎเฉ‡เจ‚ Swift เจ•เจฒเจพเจธเจพเจ‚ เจ…เจคเฉ‡ เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฌเจพเจฐเฉ‡ เจฅเฉ‹เฉœเจพ เจนเฉ‹เจฐ เจธเจฟเฉฑเจ–เฉ‹เจ—เฉ‡เฅค เจชเจฐ เจ‡เจธ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ€เจ, เจ†เจ“ เจ–เฉ‡เจก เจจเฉ‚เฉฐ เจธเจฎเจเฉ€เจเฅค

เจ…เจธเฉ€เจ‚ เจฏเจพเจฆ เจฆเจฟเจตเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚: "Habr" เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจชเจพเจ เจ•เจพเจ‚ เจฒเจˆ - "Habr" เจชเฉเจฐเจšเจพเจฐ เจ•เฉ‹เจก เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจ•เจฟเจธเฉ‡ เจตเฉ€ เจธเจ•เจฟเฉฑเจฒเจฌเจพเจ•เจธ เจ•เฉ‹เจฐเจธ เจตเจฟเฉฑเจš เจฆเจพเจ–เจฒเจพ เจฒเฉˆเจฃ เจตเฉ‡เจฒเฉ‡ 10 เจฐเฉ‚เจฌเจฒ เจฆเฉ€ เจ›เฉ‹เจŸเฅค

เจธเจ•เจฟเฉฑเจฒเจฌเจพเจ•เจธ เจธเจฟเจซเจผเจพเจฐเจฟเจธเจผ เจ•เจฐเจฆเจพ เจนเฉˆ: เจตเจฟเจฆเจฟเจ…เจ• เจ”เจจเจฒเจพเจˆเจจ เจ•เฉ‹เจฐเจธ "เจชเฉเจฐเฉ‹เจซเฉˆเจธเจผเจจ เจœเจพเจตเจพ เจกเจฟเจตเฉˆเจฒเจชเจฐ".

เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ•เจพเจฐเจก เจ•เจฟเจตเฉ‡เจ‚ เจ–เฉ‡เจกเจฃเจพ เจนเฉˆ

เจ–เฉ‡เจก เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ‡ เจ‡เฉฑเจ• เจธเฉˆเฉฑเจŸ เจฆเฉ‡ เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจ‰เจน เจฎเฉ‚เฉฐเจน เจนเฉ‡เจ เจพเจ‚ เจฒเฉ‡เจŸเจฆเฉ‡ เจนเจจ (เจ•เฉเจฐเจฎเจตเจพเจฐ, เจšเจฟเฉฑเจคเจฐ เจนเฉ‡เจ เจพเจ‚). เจœเจฆเฉ‹เจ‚ เจคเฉเจธเฉ€เจ‚ เจ•เจฟเจธเฉ‡ 'เจคเฉ‡ เจ•เจฒเจฟเฉฑเจ• เจ•เจฐเจฆเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจšเจฟเฉฑเจคเจฐ เจ•เฉเจ เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจฒเจˆ เจ–เฉเฉฑเจฒเฉเจนเจฆเจพ เจนเฉˆเฅค

เจ–เจฟเจกเจพเจฐเฉ€ เจฆเจพ เจ•เฉฐเจฎ เจ‡เฉฑเจ•เฉ‹ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจตเจพเจฒเฉ‡ เจธเจพเจฐเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจจเฉ‚เฉฐ เจฒเฉฑเจญเจฃเจพ เจนเฉˆเฅค เจœเฉ‡เจ•เจฐ, เจชเจนเจฟเจฒเฉ‡ เจ•เจพเจฐเจก เจจเฉ‚เฉฐ เจ–เฉ‹เจฒเฉเจนเจฃ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจคเฉเจธเฉ€เจ‚ เจฆเฉ‚เจœเฉ‡ เจจเฉ‚เฉฐ เจฎเฉ‹เฉœเจฆเฉ‡ เจนเฉ‹ เจ…เจคเฉ‡ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจฎเฉ‡เจฒ เจ–เจพเจ‚เจฆเฉ€เจ†เจ‚ เจนเจจ, เจคเจพเจ‚ เจฆเฉ‹เจตเฉ‡เจ‚ เจ•เจพเจฐเจก เจ–เฉเฉฑเจฒเฉเจนเฉ‡ เจฐเจนเจฟเฉฐเจฆเฉ‡ เจนเจจเฅค เจœเฉ‡เจ•เจฐ เจ‰เจน เจฎเฉ‡เจฒ เจจเจนเฉ€เจ‚ เจ–เจพเจ‚เจฆเฉ‡, เจคเจพเจ‚ เจ•เจพเจฐเจก เจฆเฉเจฌเจพเจฐเจพ เจฌเฉฐเจฆ เจ•เจฐ เจฆเจฟเฉฑเจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจเฅค เจŸเฉ€เจšเจพ เจธเจญ เจ•เฉเจ เจ–เฉ‹เจฒเฉเจนเจฃเจพ เจนเฉˆ.

เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฌเจฃเจคเจฐ

เจ‡เจธ เจ—เฉ‡เจฎ เจฆเจพ เจ‡เฉฑเจ• เจธเจงเจพเจฐเจจ เจธเฉฐเจธเจ•เจฐเจฃ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจญเจพเจ—เจพเจ‚ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ:

  • เจ‡เฉฑเจ• เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ: GameController.swift.
  • เจ‡เฉฑเจ• เจฆเฉเจฐเจฟเจธเจผ: CardCell.swift.
  • เจฆเฉ‹ เจฎเจพเจกเจฒ: MemoryGame.swift เจ…เจคเฉ‡ Card.swiftเฅค
  • Main.storyboard เจ‡เจน เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ•เจฟ เจญเจพเจ—เจพเจ‚ เจฆเจพ เจชเฉ‚เจฐเจพ เจธเฉˆเฉฑเจŸ เจ‰เจชเจฒเจฌเจง เจนเฉˆเฅค

เจ…เจธเฉ€เจ‚ เจ–เฉ‡เจก เจฆเฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจนเจฟเฉฑเจธเฉ‡, เจ•เจพเจฐเจกเจพเจ‚ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค

เจ•เจพเจฐเจก.เจธเจตเจฟเจซเจŸ

เจ•เจพเจฐเจก เจฎเจพเจกเจฒ เจฆเฉ€เจ†เจ‚ เจคเจฟเฉฐเจจ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจนเฉ‹เจฃเจ—เฉ€เจ†เจ‚: เจนเจฐเฉ‡เจ• เจฆเฉ€ เจชเจ›เจพเจฃ เจ•เจฐเจจ เจฒเจˆ เจ†เจˆเจกเฉ€, เจ•เจพเจฐเจก เจฆเฉ€ เจธเจฅเจฟเจคเฉ€ (เจฒเฉเจ•เจฟเจ† เจœเจพเจ‚ เจ–เฉเฉฑเจฒเฉเจนเจพ) เจฆเจฐเจธเจพเจ‰เจฃ เจฒเจˆ เจฆเจฟเจ–เจพเจ‡เจ† เจ—เจฟเจ† เจ‡เฉฑเจ• เจฌเฉเจฒเฉ€เจ…เจจ เจตเฉ‡เจฐเฉ€เจเจฌเจฒ, เจ…เจคเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ 'เจคเฉ‡ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจฒเจˆ เจ†เจฐเจŸเจตเจฐเจ• URLเฅค

class Card {        
    var id: String    
    var shown: Bool = false    
    var artworkURL: UIImage!
}

เจคเฉเจนเจพเจจเฉ‚เฉฐ เจจเจ•เจธเจผเจฟเจ†เจ‚ เจจเจพเจฒ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฆเฉ€ เจ†เจชเจธเฉ€ เจคเจพเจฒเจฎเฉ‡เจฒ เจจเฉ‚เฉฐ เจจเจฟเจฏเฉฐเจคเจฐเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจ‡เจนเจจเจพเจ‚ เจคเจฐเฉ€เจ•เจฟเจ†เจ‚ เจฆเฉ€ เจตเฉ€ เจฒเฉ‹เฉœ เจชเจตเฉ‡เจ—เฉ€:

เจ‡เฉฑเจ• เจ•เจพเจฐเจก 'เจคเฉ‡ เจ‡เฉฑเจ• เจšเจฟเฉฑเจคเจฐ เจจเฉ‚เฉฐ เจชเฉเจฐเจฆเจฐเจธเจผเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจขเฉฐเจ—. เจ‡เฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจฎเฉ‚เจฒ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจฐเฉ€เจธเฉˆเจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจ†เจˆเจกเฉ€ เจฒเจˆ, เจ…เจธเฉ€เจ‚ NSUUIS().uuidString เจจเฉ‚เฉฐ เจ•เจพเจฒ เจ•เจฐเจ•เฉ‡ เจ‡เฉฑเจ• เจฌเฉ‡เจคเจฐเจคเฉ€เจฌ เจ†เจˆเจกเฉ€ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค

init(image: UIImage) {        
    self.id = NSUUID().uuidString        
    self.shown = false        
    self.artworkURL = image    
}

เจ†เจˆเจกเฉ€ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ€ เจคเฉเจฒเจจเจพ เจ•เจฐเจจ เจฆเจพ เจคเจฐเฉ€เจ•เจพเฅค

func equals(_ card: Card) -> Bool {
    return (card.id == id)    
}

เจนเจฐเฉ‡เจ• เจ•เจพเจฐเจก เจฆเฉ€ เจ•เจพเจชเฉ€ เจฌเจฃเจพเจ‰เจฃ เจฆเจพ เจคเจฐเฉ€เจ•เจพ - เจธเจฎเจพเจจ เจฆเฉ€ เจ‡เฉฑเจ• เจตเฉฑเจกเฉ€ เจ—เจฟเจฃเจคเฉ€ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ. เจ‡เจน เจตเจฟเจงเฉ€ เจธเจฎเจพเจจ เจฎเฉเฉฑเจฒเจพเจ‚ เจตเจพเจฒเจพ เจ•เจพเจฐเจก เจตเจพเจชเจธ เจ•เจฐเฉ‡เจ—เฉ€เฅค

func copy() -> Card {        
    return Card(card: self)    
}
 
init(card: Card) {        
    self.id = card.id        
    self.shown = card.shown        
    self.artworkURL = card.artworkURL    
}

เจ…เจคเฉ‡ เจธเจผเฉเจฐเฉ‚ เจตเจฟเฉฑเจš เจ•เจพเจฐเจกเจพเจ‚ เจจเฉ‚เฉฐ เจธเจผเจซเจฒ เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจตเจฟเจงเฉ€ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค เจ…เจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจเจฐเฉ‡ เจ•เจฒเจพเจธ เจฆเจพ เจเจ•เจธเจŸเฉˆเจ‚เจธเจผเจจ เจฌเจฃเจพเจตเจพเจ‚เจ—เฉ‡เฅค

extension Array {    
    mutating func shuffle() {        
        for _ in 0...self.count {            
            sort { (_,_) in arc4random() < arc4random() }        
        }   
    }
}

เจ…เจคเฉ‡ เจ‡เฉฑเจฅเฉ‡ เจธเจพเจฐเฉ€เจ†เจ‚ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจ…เจคเฉ‡ เจคเจฐเฉ€เจ•เจฟเจ†เจ‚ เจจเจพเจฒ เจ•เจพเจฐเจก เจฎเจพเจกเจฒ เจฒเจˆ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ เจนเฉˆเฅค

class Card {
    
    var id: String
    var shown: Bool = false
    var artworkURL: UIImage!
    
    static var allCards = [Card]()
 
    init(card: Card) {
        self.id = card.id
        self.shown = card.shown
        self.artworkURL = card.artworkURL
    }
    
    init(image: UIImage) {
        self.id = NSUUID().uuidString
        self.shown = false
        self.artworkURL = image
    }
    
    func equals(_ card: Card) -> Bool {
        return (card.id == id)
    }
    
    func copy() -> Card {
        return Card(card: self)
    }
}
 
extension Array {
    mutating func shuffle() {
        for _ in 0...self.count {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

เจ…เฉฑเจ—เฉ‡ เจตเจงเฉ‹.

เจฆเฉ‚เจœเจพ เจฎเจพเจกเจฒ MemoryGame เจนเฉˆ, เจ‡เฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ 4*4 เจ—เจฐเจฟเฉฑเจก เจธเฉˆเจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจฎเจพเจกเจฒ เจตเจฟเฉฑเจš เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจนเฉ‹เจฃเจ—เฉ€เจ†เจ‚ เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจ•เจพเจฐเจก (เจ—เจฐเจฟเฉฑเจก 'เจคเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ€ เจ‡เฉฑเจ• เจเจฐเฉ‡), เจ‡เฉฑเจ• เจ•เจพเจฐเจก เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจ–เฉเฉฑเจฒเฉเจนเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจฆเจฟเจ–เจพเจˆ เจ—เจˆ เจเจฐเฉ‡, เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจฌเฉเจฒเฉ€เจ…เจจ เจตเฉ‡เจฐเฉ€เจเจฌเจฒ isPlaying เจ–เฉ‡เจก เจฆเฉ€ เจธเจฅเจฟเจคเฉ€ เจจเฉ‚เฉฐ เจŸเจฐเฉˆเจ• เจ•เจฐเจจ เจฒเจˆเฅค

class MemoryGame {        
    var cards:[Card] = [Card]()    
    var cardsShown:[Card] = [Card]()    
    var isPlaying: Bool = false
}

เจธเจพเจจเฉ‚เฉฐ เจ—เจฐเจฟเฉฑเจก เจฆเฉ‡ เจจเจพเจฒ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฆเฉ€ เจ†เจชเจธเฉ€ เจคเจพเจฒเจฎเฉ‡เจฒ เจจเฉ‚เฉฐ เจจเจฟเจฏเฉฐเจคเจฐเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจขเฉฐเจ— เจตเจฟเจ•เจธเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจตเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

เจ‡เฉฑเจ• เจคเจฐเฉ€เจ•เจพ เจœเฉ‹ เจ‡เฉฑเจ• เจ—เจฐเจฟเฉฑเจก เจตเจฟเฉฑเจš เจ•เจพเจฐเจกเจพเจ‚ เจจเฉ‚เฉฐ เจฌเจฆเจฒเจฆเจพ เจนเฉˆเฅค

func shuffleCards(cards:[Card]) -> [Card] {       
    var randomCards = cards        
    randomCards.shuffle()                
 
    return randomCards    
}

เจจเจตเฉ€เจ‚ เจ—เฉ‡เจฎ เจฌเจฃเจพเจ‰เจฃ เจฆเจพ เจคเจฐเฉ€เจ•เจพเฅค เจ‡เฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ เจธเจผเฉเจฐเฉ‚เจ†เจคเฉ€ เจฒเฉ‡เจ†เจ‰เจŸ เจจเฉ‚เฉฐ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจจ เจ…เจคเฉ‡ isPlaying เจตเฉ‡เจฐเฉ€เจเจฌเจฒ เจจเฉ‚เฉฐ เจธเจนเฉ€ เจตเจฟเฉฑเจš เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจจ เจฒเจˆ เจชเจนเจฟเจฒเฉ€ เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจ•เจพเจฒ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค

func newGame(cardsArray:[Card]) -> [Card] {       
    cards = shuffleCards(cards: cardsArray)        
    isPlaying = true            
 
    return cards    
}

เจœเฉ‡ เจ…เจธเฉ€เจ‚ เจ–เฉ‡เจก เจจเฉ‚เฉฐ เจฎเฉเฉœ เจšเจพเจฒเฉ‚ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚, เจซเจฟเจฐ เจ…เจธเฉ€เจ‚ isPlaying เจตเฉ‡เจฐเฉ€เจเจฌเจฒ เจจเฉ‚เฉฐ เจ—เจฒเจค เจคเฉ‡ เจธเฉˆเฉฑเจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ‡ เจธเจผเฉเจฐเฉ‚เจ†เจคเฉ€ เจ–เจพเจ•เฉ‡ เจจเฉ‚เฉฐ เจนเจŸเจพ เจฆเจฟเฉฐเจฆเฉ‡ เจนเจพเจ‚เฅค

func restartGame() {        
    isPlaying = false                
    cards.removeAll()        
    cardsShown.removeAll()    
}

เจ•เจฒเจฟเฉฑเจ• เจ•เฉ€เจคเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ€ เจชเฉเจธเจผเจŸเฉ€ เจ•เจฐเจจ เจฆเจพ เจคเจฐเฉ€เจ•เจพเฅค เจ‰เจธ เจฌเจพเจฐเฉ‡ เจนเฉ‹เจฐ เจฌเจพเจ…เจฆ เจตเจฟเฉฑเจš.

func cardAtIndex(_ index: Int) -> Card? {        
    if cards.count > index {            
        return cards[index]        
    } else {            
        return nil        
    }    
}

เจ‡เฉฑเจ• เจตเจฟเจงเฉ€ เจœเฉ‹ เจ‡เฉฑเจ• เจ–เจพเจธ เจ•เจพเจฐเจก เจฆเฉ€ เจธเจฅเจฟเจคเฉ€ เจจเฉ‚เฉฐ เจตเจพเจชเจธ เจ•เจฐเจฆเฉ€ เจนเฉˆเฅค

func indexForCard(_ card: Card) -> Int? {        
    for index in 0...cards.count-1 {            
        if card === cards[index] {                
            return index            
        }      
    }
        
    return nil    
}

เจธเจŸเฉˆเจ‚เจกเจฐเจก เจฆเฉ‡ เจจเจพเจฒ เจšเฉเจฃเฉ‡ เจ—เจ เจ•เจพเจฐเจก เจฆเฉ€ เจชเจพเจฒเจฃเจพ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐ เจฐเจฟเจนเจพ เจนเฉˆเฅค

func unmatchedCardShown() -> Bool {
    return cardsShown.count % 2 != 0
}

เจ‡เจน เจตเจฟเจงเฉ€ **เจ•เจพเจฐเจกเจธ เจฆเจฟเจ–เจพเจ** เจเจฐเฉ‡ เจตเจฟเฉฑเจš เจ†เจ–เจฐเฉ€ เจคเฉฑเจค เจจเฉ‚เฉฐ เจชเฉœเฉเจนเจฆเฉ€ เจนเฉˆ เจ…เจคเฉ‡ เจ—เฉˆเจฐ-เจฎเฉ‡เจฒ เจ–เจพเจ‚เจฆเจพ เจ•เจพเจฐเจก เจตเจพเจชเจธ เจ•เจฐเจฆเฉ€ เจนเฉˆเฅค

func didSelectCard(_ card: Card?) {        
    guard let card = card else { return }                
    
    if unmatchedCardShown() {            
        let unmatched = unmatchedCard()!                        
        
        if card.equals(unmatched) {          
            cardsShown.append(card)            
        } else {                
            let secondCard = cardsShown.removeLast()      
        }                    
    } else {            
        cardsShown.append(card)        
    }                
    
    if cardsShown.count == cards.count {            
        endGame()        
    }    
}

Main.storyboard เจ…เจคเฉ‡ GameController.swift

Main.storyboard เจ•เฉเจ เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจฆเจฟเจ–เจฆเจพ เจนเฉˆ:

เจธเจตเจฟเจซเจŸ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ•เจพเจฐเจก เจ—เฉ‡เจฎ เจฒเจฟเจ–เจฃเจพ

เจธเจผเฉเจฐเฉ‚ เจตเจฟเฉฑเจš, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจจเจตเฉ€เจ‚ เจ—เฉ‡เจฎ เจจเฉ‚เฉฐ เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจตเจฟเฉฑเจš viewDidLoad เจฆเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจธเฉˆเฉฑเจŸ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจ—เจฐเจฟเฉฑเจก เจฒเจˆ เจšเจฟเฉฑเจคเจฐ เจธเจผเจพเจฎเจฒ เจนเจจเฅค เจ—เฉ‡เจฎ เจตเจฟเฉฑเจš, เจ‡เจน เจธเจญ 4*4 เจ•เจฒเฉˆเจ•เจธเจผเจจ เจตเจฟเจŠ เจฆเฉเจ†เจฐเจพ เจฆเจฐเจธเจพเจ‡เจ† เจœเจพเจตเฉ‡เจ—เจพเฅค เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ เจ…เจœเฉ‡ เจ•เจฒเฉˆเจ•เจธเจผเจจเจตเจฟเจŠ เจคเฉ‹เจ‚ เจœเจพเจฃเฉ‚ เจจเจนเฉ€เจ‚ เจนเฉ‹, เจคเจพเจ‚ เจ‡เจน เจ‡เฉฑเจฅเฉ‡ เจนเฉˆ เจคเฉเจธเฉ€เจ‚ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจชเฉเจฐเจพเจชเจค เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹.

เจ…เจธเฉ€เจ‚ GameController เจจเฉ‚เฉฐ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฆเฉ‡ เจฐเฉ‚เจŸ เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจตเจœเฉ‹เจ‚ เจ•เฉŒเจ‚เจซเจฟเจ—เจฐ เจ•เจฐเจพเจ‚เจ—เฉ‡เฅค เจ—เฉ‡เจฎเจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจ•เฉ‹เจฒ เจ‡เฉฑเจ• เจ•เจฒเฉˆเจ•เจธเจผเจจ เจตเจฟเจŠ เจนเฉ‹เจตเฉ‡เจ—เจพ เจœเจฟเจธเจฆเจพ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• IBOutlet เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจนเจตเจพเจฒเจพ เจฆเฉ‡เจตเจพเจ‚เจ—เฉ‡เฅค เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจนเจตเจพเจฒเจพ IBAction onStartGame() เจฌเจŸเจจ เจฆเจพ เจนเฉˆ, เจ‡เจน เจ‡เฉฑเจ• UIButton เจนเฉˆ, เจคเฉเจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ PLAY เจจเจพเจฎเจ• เจธเจŸเฉ‹เจฐเฉ€เจฌเฉ‹เจฐเจก เจตเจฟเฉฑเจš เจฆเฉ‡เจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค

เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฌเจพเจฐเฉ‡ เจฅเฉ‹เฉœเจพ เจœเจฟเจนเจพ:

  • เจชเจนเจฟเจฒเจพเจ‚, เจ…เจธเฉ€เจ‚ เจฆเฉ‹ เจฎเฉเฉฑเจ– เจตเจธเจคเฉ‚เจ†เจ‚ เจจเฉ‚เฉฐ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ - เจ—เจฐเจฟเฉฑเจก: เจ—เฉ‡เจฎ = เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ—เฉ‡เจฎ (), เจ…เจคเฉ‡ เจ•เจพเจฐเจกเจพเจ‚ เจฆเจพ เจ‡เฉฑเจ• เจธเจฎเฉ‚เจน: เจ•เจพเจฐเจก = [เจ•เจพเจฐเจก]()เฅค
  • เจ…เจธเฉ€เจ‚ เจธเจผเฉเจฐเฉ‚เจ†เจคเฉ€ เจตเฉ‡เจฐเฉ€เจเจฌเจฒเจพเจ‚ เจจเฉ‚เฉฐ viewDidLoad เจฆเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจธเฉˆเฉฑเจŸ เจ•เฉ€เจคเจพ เจนเฉˆ, เจ‡เจน เจชเจนเจฟเจฒเจพ เจคเจฐเฉ€เจ•เจพ เจนเฉˆ เจœเจฟเจธ เจจเฉ‚เฉฐ เจ—เฉ‡เจฎ เจฆเฉ‡ เจšเฉฑเจฒเจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจ•เจฟเจนเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค
  • เจ•เจฒเฉˆเจ•เจธเจผเจจ เจตเจฟเจŠ เจจเฉ‚เฉฐ เจฒเฉเจ•เจพเจ‰เจฃ เจฒเจˆ เจธเฉˆเฉฑเจŸ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจธเจพเจฐเฉ‡ เจ•เจพเจฐเจก เจ‰เจฆเฉ‹เจ‚ เจคเฉฑเจ• เจฒเฉเจ•เฉ‡ เจฐเจนเจฟเฉฐเจฆเฉ‡ เจนเจจ เจœเจฆเฉ‹เจ‚ เจคเฉฑเจ• เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจชเจฒเฉ‡ เจจเจนเฉ€เจ‚ เจฆเจฌเจพเจ‰เจ‚เจฆเฉ‡เฅค
  • เจœเจฟเจตเฉ‡เจ‚ เจนเฉ€ เจ…เจธเฉ€เจ‚ PLAY เจจเฉ‚เฉฐ เจฆเจฌเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚, onStartGame IBAction เจธเฉˆเจ•เจธเจผเจจ เจธเจผเฉเจฐเฉ‚ เจนเฉ‹ เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ collectionView isHidden เจชเฉเจฐเจพเจชเจฐเจŸเฉ€ เจจเฉ‚เฉฐ เจ—เจฒเจค 'เจคเฉ‡ เจธเฉˆเฉฑเจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจคเจพเจ‚ เจ•เจฟ เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจˆ เจฆเฉ‡ เจธเจ•เจฃเฅค
  • เจนเจฐ เจตเจพเจฐ เจœเจฆเฉ‹เจ‚ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจ‡เฉฑเจ• เจ•เจพเจฐเจก เจšเฉเจฃเจฆเจพ เจนเฉˆ, เจคเจพเจ‚ didSelectItemAt เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจฎเฉเฉฑเจ– เจ—เฉ‡เจฎ เจคเจฐเจ• เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฒเจˆ เจœเจฟเจธ เจขเฉฐเจ— เจจเฉ‚เฉฐ เจ…เจธเฉ€เจ‚ didSelectCard เจ•เจนเจฟเฉฐเจฆเฉ‡ เจนเจพเจ‚เฅค

เจ‡เฉฑเจฅเฉ‡ เจ…เฉฐเจคเจฎ เจ—เฉ‡เจฎเจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจฒเจพเจ—เฉ‚เจ•เจฐเจจ เจนเฉˆ:

class GameController: UIViewController {
 
    @IBOutlet weak var collectionView: UICollectionView!
    
    let game = MemoryGame()
    var cards = [Card]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        game.delegate = self
        
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.isHidden = true
        
        APIClient.shared.getCardImages { (cardsArray, error) in
            if let _ = error {
                // show alert
            }
            
            self.cards = cardsArray!
            self.setupNewGame()
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        if game.isPlaying {
            resetGame()
        }
    }
    
    func setupNewGame() {
        cards = game.newGame(cardsArray: self.cards)
        collectionView.reloadData()
    }
    
    func resetGame() {
        game.restartGame()
        setupNewGame()
    }
    
    @IBAction func onStartGame(_ sender: Any) {
        collectionView.isHidden = false
    }
}
 
// MARK: - CollectionView Delegate Methods
extension GameController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cards.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CardCell", for: indexPath) as! CardCell
        cell.showCard(false, animted: false)
        
        guard let card = game.cardAtIndex(indexPath.item) else { return cell }
        cell.card = card
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! CardCell
        
        if cell.shown { return }
        game.didSelectCard(cell.card)
        
        collectionView.deselectItem(at: indexPath, animated:true)
    }
}

เจ†เจ“ เจนเฉเจฃ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฌเจพเจฐเฉ‡ เจฅเฉ‹เฉœเฉ€ เจ—เฉฑเจฒ เจ•เจฐเฉ€เจ.

เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ

เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจเจพ เจธเจตเจฟเจซเจŸ เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎเจฟเฉฐเจ— เจฆเจพ เจฎเฉเฉฑเจ– เจนเจฟเฉฑเจธเจพ เจนเฉˆเฅค เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจ‡เฉฑเจ• เจ•เจฒเจพเจธ, เจฌเจฃเจคเจฐ, เจœเจพเจ‚ เจ—เจฃเจจเจพ เจฒเจˆ เจจเจฟเจฏเจฎเจพเจ‚ เจจเฉ‚เฉฐ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจฏเฉ‹เจ—เจคเจพ เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจฆเฉ‡ เจนเจจเฅค เจ‡เจน เจธเจฟเจงเจพเจ‚เจค เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฎเจพเจกเจฏเฉ‚เจฒเจฐ เจ…เจคเฉ‡ เจเจ•เจธเจŸเฉˆเจ‚เจธเฉ€เจฌเจฒ เจ•เฉ‹เจก เจฒเจฟเจ–เจฃ เจฆเฉ€ เจ†เจ—เจฟเจ† เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจตเจพเจธเจคเจต เจตเจฟเฉฑเจš, เจ‡เจน เจ‡เฉฑเจ• เจชเฉˆเจŸเจฐเจจ เจนเฉˆ เจœเฉ‹ เจ…เจธเฉ€เจ‚ เจ—เฉ‡เจฎเจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจตเจฟเฉฑเจš เจ•เจฒเฉˆเจ•เจธเจผเจจเจตเจฟเจŠ เจฒเจˆ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจฒเจพเจ—เฉ‚ เจ•เจฐ เจฐเจนเฉ‡ เจนเจพเจ‚เฅค เจ†เจ‰ เจนเฉเจฃ เจ†เจชเจฃเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจฌเจฃเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚เฅค เจธเฉฐเจŸเฉˆเจ•เจธ เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจฆเจฟเจ–เจพเจˆ เจฆเฉ‡เจตเฉ‡เจ—เจพ:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

เจ…เจธเฉ€เจ‚ เจœเจพเจฃเจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ‡เฉฑเจ• เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจธเจพเจจเฉ‚เฉฐ เจ•เจฒเจพเจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฒเจˆ เจจเจฟเจฏเจฎเจพเจ‚ เจœเจพเจ‚ เจจเจฟเจฐเจฆเฉ‡เจธเจผเจพเจ‚ เจจเฉ‚เฉฐ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจ‡เจธ เจฒเจˆ เจ†เจ“ เจ‡เจธ เจฌเจพเจฐเฉ‡ เจธเฉ‹เจšเฉ€เจ เจ•เจฟ เจ‰เจน เจ•เฉ€ เจนเฉ‹เจฃเฉ‡ เจšเจพเจนเฉ€เจฆเฉ‡ เจนเจจเฅค เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เฉเฉฑเจฒ เจšเจพเจฐ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

  • เจ—เฉ‡เจฎ เจธเจผเฉเจฐเฉ‚: memoryGameDidStart.
  • เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เจพเจฐเจก เจจเฉ‚เฉฐ เจนเฉ‡เจ เจพเจ‚ เจตเฉฑเจฒ เจฎเฉ‹เฉœเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ: memoryGameShowCardsเฅค
  • เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เจพเจฐเจก เจจเฉ‚เฉฐ เจนเฉ‡เจ เจพเจ‚ เจตเฉฑเจฒ เจฎเฉ‹เฉœเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ: memoryGameHideCardsเฅค
  • เจ—เฉ‡เจฎ เจฆเจพ เจ…เฉฐเจค: memoryGameDidEndเฅค

เจธเจพเจฐเฉ‡ เจšเจพเจฐ เจคเจฐเฉ€เจ•เจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจฎเฉเฉฑเจ– เจ•เจฒเจพเจธ เจฒเจˆ เจฒเจพเจ—เฉ‚ เจ•เฉ€เจคเจพ เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ, เจœเฉ‹ เจ•เจฟ เจ—เฉ‡เจฎ เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจนเฉˆเฅค

memoryGameDidStart

เจœเจฆเฉ‹เจ‚ เจ‡เจน เจตเจฟเจงเฉ€ เจšเจฒเจพเจˆ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจคเจพเจ‚ เจ—เฉ‡เจฎ เจธเจผเฉเจฐเฉ‚ เจนเฉ‹ เจœเจพเจฃเฉ€ เจšเจพเจนเฉ€เจฆเฉ€ เจนเฉˆ (เจ‰เจชเจญเฉ‹เจ—เจคเจพ PLAY เจจเฉ‚เฉฐ เจฆเจฌเจพเจ‰เจฆเจพ เจนเฉˆ)เฅค เจ‡เฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ collectionView.reloadData() เจจเฉ‚เฉฐ เจ•เจพเจฒ เจ•เจฐเจ•เฉ‡ เจธเจฎเฉฑเจ—เจฐเฉ€ เจจเฉ‚เฉฐ เจฎเฉเฉœ เจฒเฉ‹เจก เจ•เจฐเจพเจ‚เจ—เฉ‡, เจœเฉ‹ เจ•เจพเจฐเจกเจพเจ‚ เจจเฉ‚เฉฐ เจฌเจฆเจฒ เจฆเฉ‡เจตเฉ‡เจ—เจพเฅค

func memoryGameDidStart(_ game: MemoryGame) {
    collectionView.reloadData()
}

เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ—เฉ‡เจฎเจธเจผเฉ‹เจ•เจพเจฐเจกเจธ

เจ…เจธเฉ€เจ‚ เจ‡เจธ เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ collectionSDViewSelectItemAt เจคเฉ‹เจ‚ เจ•เจพเจฒ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจชเจนเจฟเจฒเจพเจ‚ เจ‡เจน เจšเฉเจฃเจฟเจ† เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจซเจฟเจฐ เจ‡เจน เจฆเฉ‡เจ–เจฃ เจฒเจˆ เจœเจพเจ‚เจš เจ•เจฐเจฆเจพ เจนเฉˆ เจ•เจฟ เจ•เฉ€ เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจ เจ—เจ เจเจฐเฉ‡ เจตเจฟเฉฑเจš เจ•เฉ‹เจˆ เจฎเฉ‡เจฒ เจจเจนเฉ€เจ‚ เจ–เจพเจ‚เจฆเจพ เจ•เจพเจฐเจก เจนเฉˆ (เจœเฉ‡เจ•เจฐ เจฆเจฟเจ–เจพเจ เจ—เจ เจ•เจพเจฐเจกเจพเจ‚ เจฆเฉ€ เจ—เจฟเจฃเจคเฉ€ เจ…เจœเฉ€เจฌ เจนเฉˆ)เฅค เจœเฉ‡เจ•เจฐ เจ‡เฉฑเจ• เจนเฉˆ, เจคเจพเจ‚ เจšเฉเจฃเฉ‡ เจนเฉ‹เจ เจ•เจพเจฐเจก เจฆเฉ€ เจคเฉเจฒเจจเจพ เจ‡เจธ เจจเจพเจฒ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค เจœเฉ‡เจ•เจฐ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจ‡เฉฑเจ•เฉ‹ เจœเจฟเจนเฉ€เจ†เจ‚ เจนเจจ, เจคเจพเจ‚ เจฆเฉ‹เจตเฉ‡เจ‚ เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจ เจ—เจ เจ•เจพเจฐเจกเจพเจ‚ เจตเจฟเฉฑเจš เจธเจผเจพเจฎเจฒ เจ•เฉ€เจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจ…เจคเฉ‡ เจธเจพเจนเจฎเจฃเฉ‡ เจฐเจนเจฟเฉฐเจฆเฉ‡ เจนเจจเฅค เจœเฉ‡เจ•เจฐ เจตเฉฑเจ–เฉ‹-เจตเฉฑเจ–เจฐเฉ‡ เจนเฉเฉฐเจฆเฉ‡ เจนเจจ, เจคเจพเจ‚ เจ•เจพเจฐเจก เจ›เฉฑเจกเฉ‡ เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจ…เจคเฉ‡ เจฆเฉ‹เจตเฉ‡เจ‚ เจฎเฉ‚เฉฐเจน เจนเฉ‡เจ เจพเจ‚ เจ•เจฐ เจฆเจฟเฉฑเจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจเฅค

MemoryGameHideCards

เจœเฉ‡เจ•เจฐ เจ•เจพเจฐเจก เจฎเฉ‡เจฒ เจจเจนเฉ€เจ‚ เจ–เจพเจ‚เจฆเฉ‡, เจคเจพเจ‚ เจ‡เจธ เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจ•เจพเจฐเจก เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจฒเฉเจ•เจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค

เจฆเจฟเจ–เจพเจ‡เจ† = เจเฉ‚เจ เจพเฅค

memoryGameDidEnd

เจœเจฆเฉ‹เจ‚ เจ‡เจธ เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจคเจพเจ‚ เจ‡เจธเจฆเจพ เจฎเจคเจฒเจฌ เจนเฉˆ เจ•เจฟ เจธเจพเจฐเฉ‡ เจ•เจพเจฐเจก เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจชเฉเจฐเจ—เจŸ เจ•เฉ€เจคเฉ‡ เจ—เจ เจนเจจ เจ…เจคเฉ‡ เจ•เจพเจฐเจก เจฆเจฟเจ–เจพเจ เจ—เจ เจธเฉ‚เจšเฉ€ เจตเจฟเฉฑเจš เจนเจจ: cardsShown.count = cards.count, เจ‡เจธ เจฒเจˆ เจ–เฉ‡เจก เจ–เจคเจฎ เจนเฉ‹ เจ—เจˆ เจนเฉˆเฅค เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจ–เจพเจธ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‰เจฆเฉ‹เจ‚ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆ เจœเจฆเฉ‹เจ‚ เจ…เจธเฉ€เจ‚ isPlaying var เจจเฉ‚เฉฐ เจ—เจฒเจค 'เจคเฉ‡ เจธเฉˆเฉฑเจŸ เจ•เจฐเจจ เจฒเจˆ endGame() เจจเฉ‚เฉฐ เจ•เจพเจฒ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจœเจฟเจธ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจ—เฉ‡เจฎ เจธเจฎเจพเจชเจคเฉ€ เจธเฉเจจเฉ‡เจนเจพ เจฆเจฟเจ–เจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจจเจพเจฒ เจนเฉ€ alertController เจจเฉ‚เฉฐ เจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจฒเจˆ เจ‡เฉฑเจ• เจธเฉ‚เจšเจ• เจตเจœเฉ‹เจ‚ เจตเจฐเจคเจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค viewDidDisappear เจ•เจฟเจนเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจ—เฉ‡เจฎ เจฐเฉ€เจธเฉˆเจŸ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค

เจ—เฉ‡เจฎเจ•เฉฐเจŸเจฐเฉ‹เจฒเจฐ เจตเจฟเฉฑเจš เจ‡เจน เจธเจญ เจ•เฉเจ เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจฆเจฟเจ–เจพเจˆ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ:

extension GameController: MemoryGameProtocol {
    func memoryGameDidStart(_ game: MemoryGame) {
        collectionView.reloadData()
    }
 
 
    func memoryGame(_ game: MemoryGame, showCards cards: [Card]) {
        for card in cards {
            guard let index = game.indexForCard(card)
                else { continue
            }        
            
            let cell = collectionView.cellForItem(
                at: IndexPath(item: index, section:0)
            ) as! CardCell
 
            cell.showCard(true, animted: true)
        }
    }
 
    func memoryGame(_ game: MemoryGame, hideCards cards: [Card]) {
        for card in cards {
            guard let index = game.indexForCard(card)
                else { continue
            }
            
            let cell = collectionView.cellForItem(
                at: IndexPath(item: index, section:0)
            ) as! CardCell
    
            cell.showCard(false, animted: true)
        }
    }
 
    func memoryGameDidEnd(_ game: MemoryGame) {
        let alertController = UIAlertController(
            title: defaultAlertTitle,
            message: defaultAlertMessage,
            preferredStyle: .alert
        )
 
        let cancelAction = UIAlertAction(
            title: "Nah", style: .cancel) {
            [weak self] (action) in
            self?.collectionView.isHidden = true
        }
 
        let playAgainAction = UIAlertAction(
            title: "Dale!", style: .default) {
            [weak self] (action) in
            self?.collectionView.isHidden = true
 
            self?.resetGame()
        }
 
        alertController.addAction(cancelAction)
        alertController.addAction(playAgainAction)
        
        self.present(alertController, animated: true) { }
    
        resetGame()
    }
}

เจธเจตเจฟเจซเจŸ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจ•เจพเจฐเจก เจ—เฉ‡เจฎ เจฒเจฟเจ–เจฃเจพ
เจ…เจธเจฒ เจตเจฟเฉฑเจš, เจ‡เจน เจธเจญ เจนเฉˆ. เจคเฉเจธเฉ€เจ‚ เจ‡เจธ เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ—เฉ‡เจฎ เจฆเจพ เจ†เจชเจฃเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค

เจนเฉˆเจชเฉ€ เจ•เฉ‹เจกเจฟเฉฐเจ—!

เจธเจ•เจฟเฉฑเจฒเจฌเจพเจ•เจธ เจธเจฟเจซเจผเจพเจฐเจฟเจธเจผ เจ•เจฐเจฆเจพ เจนเฉˆ:

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹