Tusia o se Taaloga Kata i le Swift

Tusia o se Taaloga Kata i le Swift

O lenei tusiga o loʻo faʻamatalaina le faʻagasologa o le fatuina o se taʻaloga aʻoaʻoga faigofie e manatua ai ou te fiafia tele i ai. E ese mai le lelei ia te ia lava, o le ae aoao atili e uiga i vasega Swift ma tulafono aoe alu. Ae tatou te lei amataina, ia tatou malamalama i le taaloga lava ia.

Matou te faʻamanatu atu ia te oe: mo tagata faitau uma o le "Habr" - o se faʻaitiitiga o 10 rubles pe a lesitala i soʻo se vasega Skillbox e faʻaaoga ai le code promotional "Habr".

Ua fautuaina e Skillbox: A'oa'oga i luga ole laiga "Profesa Java Developer".

Fa'afefea ona ta'alo Memory Card

E amata le ta'aloga i se fa'aaliga o se seti o kata. E taooto fa'asaga i lalo (fa'atatau, ata i lalo). A e kiliki i luga o se tasi, o le ata e matala mo ni nai sekone.

O le galuega a le tagata taalo o le su'eina lea o kata uma e tutusa ata. Afai, a uma ona tatala le kata muamua, e te liliu i luga le lona lua ma fetaui ata, o loʻo matala uma kata e lua. Afai e le fetaui, ona toe tapuni lea o kata. O le sini ia tatala mea uma.

Fa'atulagaina o le poloketi

Ina ia fatuina se faʻamatalaga faigofie o lenei taʻaloga e te manaʻomia vaega nei:

  • Tasi Pule: GameController.swift.
  • Tasi Vaaiga: CardCell.swift.
  • Lua Fa'ata'ita'iga: MemoryGame.swift ma Card.swift.
  • Main.storyboard e faʻamautinoa ai o loʻo avanoa le seti atoa o vaega.

Tatou amata i le vaega sili ona faigofie o le taaloga, o kata.

Card.swift

O le fa'ata'ita'iga kata o le a iai ni meatotino se tolu: id e fa'ailoa ai mea ta'itasi, o se fesuiaiga boolean e fa'aalia e fa'amaonia ai le tulaga o le kata (natia pe tatala), ma artworkURL mo ata i luga o kata.

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

E te mana'omia fo'i metotia nei e pulea ai fegalegaleai a tagata fa'aoga ma fa'afanua:

Metotia mo le faʻaalia o se ata i luga o se kata. O iinei tatou te toe setiina uma meatotino i le faaletonu. Mo id, matou te fatuina se id faʻafuaseʻi e ala i le valaʻau i le NSUUIS().uuidString.

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

Metotia mo le fa'atusatusaina o kata ID.

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

Metotia e fai ai se kopi o kata taitasi - ina ia maua se numera tele o mea tutusa. O lenei metotia o le a toe faʻafoʻi ai le kata e tutusa tau.

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

Ma e tasi le isi auala e manaʻomia e faʻafefe ai kata i le amataga. O le a matou faia o se faʻaopoopoga o le vasega Array.

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

Ma o le faʻatinoga lea o le tulafono mo le faʻataʻitaʻiga Card ma meatotino uma ma metotia.

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() }
        }
    }
}

Faaauau loa.

O le faʻataʻitaʻiga lona lua o MemoryGame, o iinei matou te setiina ai le 4 * 4 grid. O le fa'ata'ita'iga o le ai ai meatotino e pei o kata (se fa'asologa o kata i luga o se fa'asologa), o se fa'aaliga fa'aalia ma kata ua uma ona tatala, ma le boolean variable isPlaying e siaki ai le tulaga o le ta'aloga.

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

Matou te manaʻomia foʻi le atinaʻeina o auala e pulea ai fegalegaleaiga a tagata faʻaoga ma le faʻasologa.

O se auala e fa'afefeteina ai kata i se fa'asologa.

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

Metotia mo le fatuina o se taaloga fou. O iinei tatou te taʻua ai le auala muamua e amata ai le faʻasologa muamua ma faʻauluina le fesuiaiga isPlaying i le moni.

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

Afai tatou te fia toe amata le taaloga, ona matou setiina lea o le isPlaying fesuiaiga i le sese ma aveese le uluai faatulagaga o kata.

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

Metotia mo le fa'amaonia o kata kiliki. Fa'amatalaga e uiga ia te ia mulimuli ane.

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

O se auala e toe faʻafoʻi ai le tulaga o se kata faʻapitoa.

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

Siaki le tausisia o le kata filifilia ma le tulaga masani.

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

O lenei metotia e faitau le elemene mulimuli i le **cardsShown** array ma toe faafoi mai le kata e le fetaui.

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 ma GameController.swift

Main.storyboard e pei o lenei:

Tusia o se Taaloga Kata i le Swift

I le taimi muamua, e tatau ona e setiina le taaloga fou e pei o le viewDidLoad i le pule, e aofia ai ata mo le faʻasologa. I le taʻaloga, o nei mea uma o le a faʻatusalia e le 4 * 4 collectionView. Afai e te le'i masani ile collectionView, o lea e mafai ona e mauaina faʻamatalaga e te manaʻomia.

O le a matou faʻatulagaina le GameController e avea ma aʻa aʻa o le talosaga. O le GameController o le ai ai se collectionView lea o le a matou taʻua o se IBOutlet. O le isi faʻamatalaga o le IBAction onStartGame() button, o le UIButton lea, e mafai ona e vaʻai i ai i le laupapa tala e taʻua o PLAY.

O sina mea itiiti e uiga i le faʻatinoina o pule:

  • Muamua, matou te amataina ni mea autu se lua - o le faasologa: taaloga = MemoryGame(), ma se seti o kata: kata = [Card]().
  • Matou te setiina suiga muamua e pei o viewDidLoad, o le auala muamua lea e taʻua aʻo taʻavale le taʻaloga.
  • collectionView ua seti i le natia ona o kata uma e natia seia oomi e le tagata faaaoga le PLAY.
  • O le taimi lava matou te oomiina ai le PLAY, o le onStartGame IBAction vaega e amata, ma matou seti le collectionView isHidden meatotino i le sese ina ia mafai ona iloa kata.
  • O taimi uma e filifili ai e le tagata faʻaoga se kata, e valaʻau le didSelectItemAt method. I le auala matou te taʻua didSelectCard e faʻatino ai le taʻaloga autu.

O le faʻatinoga mulimuli lea o GameController:

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)
    }
}

Se'i o tatou talanoa la'itiiti e uiga i tulafono taua.

Maliega

O le galulue faatasi ma protocols o le autu lea o polokalame Swift. Protocols e maua ai le tomai e faʻamatala ai tulafono mo se vasega, fausaga, poʻo le faʻasologa. O lenei mataupu faavae e mafai ai ona e tusia code modular ma extensible. O le mea moni, o se mamanu lea ua uma ona matou faʻatinoina mo le aoinaView i GameController. Se'i fai la tatou lava fa'aliliuga. O le syntax o le a pei o lenei:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Matou te iloa o se protocol e mafai ai ona matou faʻamalamalamaina tulafono poʻo faʻatonuga mo le faʻatinoina o se vasega, o lea seʻi o tatou mafaufau i mea e tatau ona i ai. E te mana'omia le fa atoa.

  • Taaloga amata: memoryGameDidStart.
  • E tatau ona e fa'asaga i lalo le kata: memoryGameShowCards.
  • E tatau ona e fa'asaga i lalo le kata: memoryGameHideCards.
  • Ta'aloga fa'ai'uga: memoryGameDidEnd.

O auala uma e fa e mafai ona faʻatinoina mo le vasega autu, o le GameController.

memoryGameDidStart

A fa'atino lenei metotia, e tatau ona amata le ta'aloga (oomi le tagata fa'aoga PLAY). O iinei o le a matou toe faʻapipiʻi ai mea e ala i le valaʻau collectionView.reloadData(), lea e faʻafefe ai kata.

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

memoryGameShowCards

Matou te taʻua lenei metotia mai le collectionSDViewSelectItemAt. Muamua o loʻo faʻaalia ai le kata filifilia. Ona siaki lea pe i ai se kata e le mafaatusalia i totonu o kata Fa'aalia fa'asologa (pe a le numera o kata Fa'aalia e ese). Afai ei ai se tasi, o le kata filifilia e faʻatusatusa i ai. Afai e tutusa ata, e fa'aopoopo uma kata i kata Fa'aali ma fa'asaga i luga. Afai e ese, o le kata e tu'u ai kata Fa'aali ma fa'asaga uma i lalo.

memoryGameHideCards

Afai e le fetaui ia kata, e ta'ua lea auala ma e natia ata o kata.

fa'aalia = sese.

memoryGameDidEnd

A ta'ua lea metotia, o lona uiga ua uma ona fa'aalia kata uma ma o lo'o i totonu o le lisi fa'aalia: cardsShown.count = cards.count, o lea ua uma ai le ta'aloga. O le metotia e taʻua faʻapitoa pe a uma ona matou valaʻau endGame() e seti le isPlaying var i le sese, a maeʻa ona faʻaalia le feʻau faʻaiʻuga. Fa'apea fo'i le alertController e fa'aaogaina e fai ma fa'ailoga mo le pule. ua vala'au viewDidDisappear ma toe setiina le ta'aloga.

O le mea lenei e foliga uma i GameController:

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()
    }
}

Tusia o se Taaloga Kata i le Swift
O le mea moni, pau lava lena. E mafai ona e fa'aogaina lenei poloketi e fai ai sau lava fa'aaliga o le ta'aloga.

Manuia coding!

Ua fautuaina e Skillbox:

puna: www.habr.com

Faaopoopo i ai se faamatalaga