Ho Ngola Papali ea Memori Cards ka Swift

Ho Ngola Papali ea Memori Cards ka Swift

Sengoliloeng sena se hlalosa mokhoa oa ho theha papali e bonolo ea koetliso ea memori eo ke e ratang haholo. Ntle le ho ba hantle ka bohona, u tla ithuta ho eketsehileng ka litlelase tsa Swift le liprothokholo ha u ntse u ea. Empa pele re qala, ha re utloisiseng papali ka boeona.

Re hopotsa: bakeng sa babali bohle ba "Habr" - theolelo ea li-ruble tse 10 ha u ngolisa thupelong efe kapa efe ea Skillbox u sebelisa khoutu ea papatso ea "Habr".

Skillbox e khothaletsa: Lithuto tsa inthaneteng "Professional Java Developer".

Mokhoa oa ho bapala karete ea memori

Papali e qala ka pontšo ea sehlopha sa likarete. Ba robala ka sefahleho (ka ho latellana, setšoantšo fatše). Ha u tobetsa leha e le efe, setšoantšo se buleha ka metsotsoana e seng mekae.

Mosebetsi oa sebapali ke ho fumana likarete tsohle tse nang le litšoantšo tse tšoanang. Haeba, ka mor'a ho bula karete ea pele, u phetla ea bobeli 'me litšoantšo li tsamaellana, likarete tseo ka bobeli li lula li butsoe. Haeba li sa lumellane, likarete lia koaloa hape. Sepheo ke ho bula tsohle.

Sebopeho sa morero

Ho theha mofuta o bonolo oa papali ena o hloka likarolo tse latelang:

  • Taolo e le 'ngoe: GameController.swift.
  • Pono e le 'ngoe: CardCell.swift.
  • Mehlala e 'meli: MemoryGame.swift le Card.swift.
  • Main.storyboard ho etsa bonnete ba hore sehlopha sohle sa likarolo se fumaneha.

Re qala ka karolo e bonolo ka ho fetisisa ea papali, likarete.

Karete.kabelo

Mohlala oa karete o tla ba le thepa e meraro: id ho khetholla e 'ngoe le e' ngoe, mofuta oa boolean o bonts'itsoeng ho hlakisa boemo ba karete (e patiloeng kapa e bulehileng), le artworkURL bakeng sa litšoantšo tse likareteng.

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

U tla hloka hape mekhoa ena ho laola tšebelisano ea basebelisi le limmapa:

Mokhoa oa ho hlahisa setšoantšo kareteng. Mona re seta thepa eohle ho ea kamehla. Bakeng sa id, re hlahisa id e sa reroang ka ho letsetsa NSUUIS().uuidString.

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

Mokhoa oa ho bapisa likarete tsa ID.

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

Mokhoa oa ho etsa kopi ea karete ka 'ngoe - molemong oa ho fumana palo e kholoanyane ea tse tšoanang. Mokhoa ona o tla khutlisa karete e nang le boleng bo tšoanang.

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

'Me mokhoa o mong oa hlokahala ho kopanya likarete qalong. Re tla e etsa katoloso ea sehlopha sa Array.

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

'Me mona ke ts'ebetsong ea khoutu bakeng sa mohlala oa Card ka thepa eohle le mekhoa.

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

Tsoela pele.

Mohlala oa bobeli ke MemoryGame, mona re beha marang-rang a 4 * 4. Moetso ona o tla ba le litšobotsi tse kang likarete (mofuta oa likarete ho grid), likarete tse bonts'itsoeng tse nang le likarete tse seng li butsoe, 'me mofuta oa boolean o ntse o Bapala ho lekola boemo ba papali.

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

Re boetse re hloka ho theha mekhoa ea ho laola tšebelisano ea basebelisi le grid.

Mokhoa o kopanyang likarete ka har'a marang-rang.

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

Mokhoa oa ho theha papali e ncha. Mona re bitsa mokhoa oa pele oa ho qala moralo oa pele le ho qala phapang ea isPlaying hore e be 'nete.

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

Haeba re batla ho qala papali hape, ebe re beha phapang ea isPlaying hore e be leshano ebe re tlosa sebopeho sa pele sa likarete.

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

Mokhoa oa ho netefatsa likarete tse tobetse. Tse ling ka eena hamorao.

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

Mokgoa o kgutlisang boemo ba karete e itseng.

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

Ho hlahloba ho lumellana ha karete e khethiloeng le maemo.

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

Mokhoa ona o bala karolo ea ho qetela lethathamong la **likaretePontšo** ebe o khutlisa karete e sa ts'oanang.

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

Main.storyboard e shebahala tjena:

Ho Ngola Papali ea Memori Cards ka Swift

Qalong, o hloka ho beha papali e ncha joalo ka viewDidLoad ho molaoli, ho kenyelletsa le litšoantšo tsa grid. Papaling, tsena tsohle li tla emeloa ke 4 * 4 collectionView. Haeba ha u so tloaelane le collectionView, ke ena u ka fumana lintlha tseo u li hlokang.

Re tla hlophisa GameController joalo ka taolo ea motso oa sesebelisoa. GameController e tla ba le pokello ea Pokello eo re tla e bitsa IBOutlet. Tšupiso e 'ngoe ke ea konopo ea IBAction onStartGame(), ena ke UIButton, u ka e bona letlapeng la pale le bitsoang PLAY.

Hanyenyane mabapi le ts'ebetsong ea balaoli:

  • Taba ea pele, re qala lintho tse peli tsa mantlha - marang-rang: papali = MemoryGame (), le sehlopha sa likarete: likarete = [Karete] ().
  • Re beha mefuta ea pele e le viewDidLoad, ona ke mokhoa oa pele o bitsoang ha papali e ntse e sebetsa.
  • collectionView e behiloe ho patiloe hobane likarete tsohle li patiloe ho fihlela mosebelisi a tobetsa PLAY.
  • Hang ha re tobetsa PLAY, karolo ea onStartGame IBAction ea qala, 'me re beha pokello ea View isHidden thepa hore e be leshano e le hore likarete li ka bonahala.
  • Nako le nako ha mosebelisi a khetha karete, mokhoa oa didSelectItemAt o bitsoa. Ka mokhoa oo re o bitsang didSelectCard ho kenya ts'ebetsong mohopolo oa mantlha oa papali.

Mona ke ts'ebetsong ea ho qetela ea 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)
    }
}

Joale ha re bue hanyane ka liprothokholo tsa bohlokoa.

Melao-motheo

Ho sebetsa le liprothokholo ke motheo oa lenaneo la Swift. Li-protocol li fana ka bokhoni ba ho hlalosa melao bakeng sa sehlopha, sebopeho, kapa palo. Molao-motheo ona o u lumella ho ngola khoutu ea modular le e atolositsoeng. Ebile, ona ke mokhoa oo re seng re o sebelisa bakeng sa pokelloView ho GameController. Joale ha re iketsetse mofuta oa rona. Syntax e tla shebahala tjena:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Rea tseba hore melaoana e re lumella ho hlalosa melao kapa litaelo tsa ho kenya tšebetsong sehlopha, kahoo ha re nahaneng hore na e tlameha ho ba eng. U hloka tse 'nè ka kakaretso.

  • Qalo ea papali: memoryGameDidStart.
  • U hloka ho shebisa karete sefahleho fatše: memoryGameShowCards.
  • U hloka ho theola sefahleho sa karete fatše: memoryGameHideCards.
  • Qetello ea papali: memoryGameDidEnd.

Mekhoa eohle e mene e ka sebelisoa bakeng sa sehlopha se seholo, e leng GameController.

memoryGameDidStart

Ha mokhoa ona o etsoa, ​​​​papali e lokela ho qala (mosebelisi o tobetsa PLAY). Mona re tla kenya litaba hape ka ho letsetsa collectionView.reloadData(), e tla kopanya likarete.

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

memoryGameShowCards

Re bitsa mokhoa ona ho tsoa ho collectionSDViewSelectItemAt. Ea pele e bontša karete e khethiloeng. Ebe u hlahloba ho bona hore na ho na le karete e sa bapisoang le likarete tse bonts'itsoeng (haeba palo ea likarete e bonts'itsoeng e sa tloaeleha). Haeba e le teng, karete e khethiloeng e bapisoa le eona. Haeba litšoantšo li tšoana, likarete tseo ka bobeli li eketsoa likareteng tse bontšitsoeng 'me li lule li shebile holimo. Haeba e fapane, karete e siea likarete tse bonts'itsoeng 'me ka bobeli li shebane fatše.

memoryGameHideCards

Haeba likarete li sa lumellane, mokhoa ona o bitsoa 'me litšoantšo tsa karete li patiloe.

bontshitsweng = bohata.

memoryGameDidEnd

Ha mokhoa ona o bitsoa, ​​ho bolela hore likarete tsohle li se li senotsoe 'me li le lethathamong le bontšitsoeng: cardsShown.count = cards.count, kahoo papali e felile. Mokhoa ona o bitsoa ka ho khetheha ka mor'a hore re bitse endGame() ho beha isPlaying var ho ea bohata, ka mor'a moo molaetsa oa ho qetela oa papali o bontšoa. Hape alertController e sebelisoa e le sesupo sa molaoli. viewDidDisappear e bitsoa mme papali e setiloe bocha.

Mona ke hore na e shebahala joang ho 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()
    }
}

Ho Ngola Papali ea Memori Cards ka Swift
Haele hantle, ke phetho. U ka sebelisa morero ona ho iketsetsa mofuta oa papali.

Thabela khouto!

Skillbox e khothaletsa:

Source: www.habr.com

Eketsa ka tlhaloso