Ukubhala Umdlalo Wamakhadi Enkumbulo nge-Swift

Ukubhala Umdlalo Wamakhadi Enkumbulo nge-Swift

Lesi sihloko sichaza inqubo yokudala umdlalo olula wokuqeqesha inkumbulo engiwujabulela kakhulu. Ngaphandle kokuba muhle ngokwakho, uzofunda okwengeziwe mayelana namakilasi e-Swift namaphrothokholi njengoba uhamba. Kodwa ngaphambi kokuthi siqale, ake siqonde umdlalo ngokwawo.

Siyakukhumbuza: kubo bonke abafundi be-"Habr" - isaphulelo sama-ruble angu-10 lapho ubhalisa kunoma yisiphi isifundo se-Skillbox usebenzisa ikhodi yephromoshini ethi "Habr".

I-Skillbox iyancoma: Isifundo se-inthanethi semfundo "Umthuthukisi we-Java ochwepheshe".

Idlalwa kanjani iMemori Card

Umdlalo uqala ngokuboniswa kwesethi yamakhadi. Balala babheke phansi (ngokulandelana, isithombe phansi). Uma uchofoza kunoma yisiphi, isithombe sivuleka imizuzwana embalwa.

Umsebenzi womdlali ukuthola wonke amakhadi anezithombe ezifanayo. Uma, ngemuva kokuvula ikhadi lokuqala, uphendule elesibili bese izithombe zihambisana, womabili amakhadi ahlala evuliwe. Uma engahambisani, amakhadi ayavalwa futhi. Inhloso ukuvula yonke into.

Isakhiwo sephrojekthi

Ukuze udale inguqulo elula yalo mdlalo udinga izingxenye ezilandelayo:

  • Isilawuli esisodwa: I-GameController.swift.
  • Ukubuka Okukodwa: CardCell.swift.
  • Amamodeli Amabili: I-MemoryGame.swift ne-Card.swift.
  • I-Main.storyboard ukuqinisekisa ukuthi isethi yonke yezingxenye iyatholakala.

Siqala ngengxenye elula yomdlalo, amakhadi.

Ikhadi.esheshayo

Imodeli yekhadi izoba nezinto ezintathu: i-id yokuhlonza ngayinye, okuguquguqukayo kwe-boolean okuboniswa ukuze kucaciswe isimo sekhadi (elifihliwe noma elivuliwe), kanye ne-artworkURL yezithombe ezisemakhadini.

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

Uzodinga futhi lezi zindlela ukuze ulawule ukusebenzisana komsebenzisi namamephu:

Indlela yokubonisa isithombe ekhadini. Lapha sisetha kabusha zonke izakhiwo zibe okumisiwe. Ku-id, sakha i-id engahleliwe ngokushayela i-NSUUIS().uuidString.

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

Indlela yokuqhathanisa amakhadi omazisi.

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

Indlela yokwenza ikhophi yekhadi ngalinye - ukuze uthole inombolo enkulu efanayo. Le ndlela izobuyisela ikhadi elinamanani afanayo.

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

Futhi enye indlela eyengeziwe iyadingeka ukushova amakhadi ekuqaleni. Sizokwenza isandiso sekilasi le-Array.

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

Futhi nakhu ukuqaliswa kwekhodi yemodeli yeKhadi nazo zonke izakhiwo nezindlela.

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

Qhubeka.

Imodeli yesibili yiMemoryGame, lapha sibeka igridi engu-4*4. Imodeli izoba nezakhiwo ezinjengamakhadi (uhlu lwamakhadi kugridi), amakhadiAmakhadi abonisiwe anamakhadi asevuliwe kakade, kanye noguquko lwe-boolean Kuyadlala ukuze kulandelelwe isimo somdlalo.

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

Kudingeka futhi sakhe izindlela zokulawula ukusebenzisana komsebenzisi negridi.

Indlela eshova amakhadi kugridi.

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

Indlela yokudala igeyimu entsha. Lapha sibiza indlela yokuqala yokuqala isakhiwo sokuqala futhi siqalise ukuguquguquka kwe-isPlaying kube iqiniso.

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

Uma sifuna ukuqala kabusha umdlalo, bese sisetha okuguquguqukayo kwe-isPlaying kube amanga futhi sikhipha isakhiwo sokuqala samakhadi.

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

Indlela yokuqinisekisa amakhadi achofoziwe. Okuningi ngaye kamuva.

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

Indlela ebuyisela indawo yekhadi elithile.

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

Ihlola ukuthobela kwekhadi elikhethiwe nezinga.

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

Le ndlela ifunda ingxenye yokugcina ohlwini **amakhadiAbonisiwe** futhi ibuyisela ikhadi elingameshani.

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

I-Main.storyboard kanye ne-GameController.swift

I-Main.storyboard ibukeka kanje:

Ukubhala Umdlalo Wamakhadi Enkumbulo nge-Swift

Ekuqaleni, udinga ukusetha igeyimu entsha njenge-viewDidLoad kusilawuli, okuhlanganisa nezithombe zegridi. Emdlalweni, konke lokhu kuzomelwa yi-4*4 collectionView. Uma ungakajwayeli iqoqoBuka, nansi ungathola ulwazi oludingayo.

Sizomisa i-GameController njengesilawuli sempande yohlelo lokusebenza. I-GameController izoba neqoqoBuka esizobhekisela kuyo njenge-IBOutlet. Esinye isithenjwa sisenkinobho ethi IBAction onStartGame(), lena i-UIButton, ungayibona ebhodini lezindaba elibizwa ngokuthi DLALA.

Okuncane mayelana nokuqaliswa kwezilawuli:

  • Okokuqala, siqala izinto ezimbili ezibalulekile - igridi: umdlalo = MemoryGame(), kanye nesethi yamakhadi: amakhadi = [Ikhadi]().
  • Setha okuguquguqukayo kokuqala njenge-viewDidLoad, lena indlela yokuqala ebizwa ngokuthi umdlalo usasebenza.
  • collectionBuka isethwe kokufihliwe ngoba wonke amakhadi afihliwe kuze kube yilapho umsebenzisi ecindezela DLALA.
  • Ngokushesha nje lapho sicindezela okuthi PLAY, isigaba se-IBAction ye-OnStartGame siyaqala, futhi simisa into ethi Buka intoEfihliwe kube amanga ukuze amakhadi abonakale.
  • Ngaso sonke isikhathi uma umsebenzisi ekhetha ikhadi, kubizwa indlela ye- didSelectItemAt. Endleleni esiyibiza ngokuthi i-didSelectCard ukuze isebenzise i-logic yomdlalo oyinhloko.

Nakhu ukuqaliswa kokugcina kwe-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)
    }
}

Manje ake sikhulume kancane ngamaphrothokholi abalulekile.

Imithethonqubo

Ukusebenza namaphrothokholi kuwumgogodla wohlelo lwe-Swift. Amaphrothokholi ahlinzeka ngekhono lokuchaza imithetho yekilasi, isakhiwo, noma ukubala. Lesi simiso sikuvumela ukuthi ubhale ikhodi ye-modular nenwebekayo. Eqinisweni, lena iphethini esesivele siyisebenzisela ukuqoqwaBuka ku-GameController. Manje masenze eyethu inguqulo. I-syntax izobukeka kanje:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Siyazi ukuthi umthetho olandelwayo usivumela ukuthi sichaze imithetho noma imiyalelo yokusebenzisa ikilasi, ngakho-ke ake sicabange ukuthi kufanele ibe yini. Udinga ezine sezizonke.

  • Ukuqala komdlalo: inkumbuloGameDidStart.
  • Udinga ukubhekisa phansi ikhadi: imemoriGameShowCards.
  • Udinga ukubhekisa phansi ikhadi: imemoriGameHideCards.
  • Ukuphela kwegeyimu: inkumbuloGameDidEnd.

Zonke izindlela ezine zingasetshenziswa ekilasini elikhulu, okuyi-GameController.

inkumbuloGameDidStart

Uma le ndlela isetshenziswa, umdlalo kufanele uqale (umsebenzisi ucindezela PLAY). Lapha sizovele silayishe kabusha okuqukethwe ngokushayela i- collectionView.reloadData(), ezoshova amakhadi.

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

inkumbuloGameShowCards

Sibiza le ndlela kusuka kuqoqoSDViewSelectItemAt. Okokuqala kukhombisa ikhadi elikhethiwe. Bese ehlola ukuze abone ukuthi alikho yini ikhadi elingenakuqhathaniswa emakhadiniUhlu olukhonjisiwe (uma inombolo yamakhadiEkhonjisiwe iyinqaba). Uma likhona, ikhadi elikhethiwe liqhathaniswa nalo. Uma izithombe zifana, womabili amakhadi engezwa emakhadiniAbonisiwe futhi ahlala ebheke phezulu. Uma kuhlukile, ikhadi lishiya amakhadiEbonisiwe futhi womabili abhekiselwe phansi.

inkumbuloGameHideCards

Uma amakhadi engahambisani, le ndlela ibizwa ngokuthi futhi izithombe zekhadi ziyafihlwa.

kubonisiwe = amanga.

inkumbuloGameDidEnd

Uma le ndlela ibizwa, kusho ukuthi wonke amakhadi asevele embuliwe futhi asohlwini olukhonjisiwe: cardsShown.count = cards.count, ngakho umdlalo uphelile. Indlela ibizwa ngokuqondile ngemva kokuba sibize i-endGame() ukuze simise i-isPlaying var ibe amanga, ngemva kwalokho umlayezo wokuphela komdlalo uyaboniswa. Futhi i-alertController isetshenziswa njengenkomba yesilawuli. i-viewDidDisappear ibizwa futhi igeyimu isethwe kabusha.

Nakhu ukuthi konke kubukeka kanjani ku-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()
    }
}

Ukubhala Umdlalo Wamakhadi Enkumbulo nge-Swift
Empeleni, yilokho kuphela. Ungasebenzisa le phrojekthi ukuze udale inguqulo yakho yegeyimu.

Jabulela ukubhala ngekhodi!

I-Skillbox iyancoma:

Source: www.habr.com

Engeza amazwana