ãã®èšäºã§ã¯ãç§ããšãŠãæ°ã«å
¥ã£ãŠããã·ã³ãã«ãªèšæ¶åãã¬ãŒãã³ã° ã²ãŒã ã®äœæããã»ã¹ã«ã€ããŠèª¬æããŸãã ããèªäœãåªããŠããããšã«å ããŠãåŠç¿ãé²ããŠãããã¡ã« Swift ã®ã¯ã©ã¹ãšãããã³ã«ã«ã€ããŠããã«åŠã¶ããšã«ãªããŸãã ããããå§ããåã«ãã²ãŒã èªäœãç解ããŸãããã
ãªãã€ã³ããŒïŒ ãHabrãã®ãã¹ãŠã®èªè ã察象 - ãHabrãããã¢ãŒã·ã§ã³ ã³ãŒãã䜿çšããŠã¹ãã«ããã¯ã¹ ã³ãŒã¹ã«ç»é²ãããš 10 ã«ãŒãã«ã®å²åŒã
ã¹ãã«ããã¯ã¹ã¯æ¬¡ã®ããšãæšå¥šããŸãã æè²ãªã³ã©ã€ã³ã³ãŒã¹
ãè·æ¥ Java éçºè ã .
ã¡ã¢ãªãŒã«ãŒãã®éã³æ¹
ã²ãŒã ã¯ã«ãŒãã®ã»ããã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ããå§ãŸããŸãã 圌ãã¯ãã€äŒãã«å¯ãŸãïŒãããããã€ã¡ãŒãžãäžã«åããŸãïŒã ãããããã¯ãªãã¯ãããšãç»åãæ°ç§ééããŸãã
ãã¬ã€ã€ãŒã®ä»äºã¯ãåãçµµæã®ã«ãŒãããã¹ãŠèŠã€ããããšã§ãã æåã®ã«ãŒããéããåŸãXNUMX çªç®ã®ã«ãŒããããã£ãŠçµµãäžèŽããå Žåãäž¡æ¹ã®ã«ãŒãã¯éãããŸãŸã«ãªããŸãã äžèŽããªãå Žåãã«ãŒãã¯åã³éããããŸãã ç®æšã¯ãã¹ãŠããªãŒãã³ã«ããããšã§ãã
ãããžã§ã¯ãã®æ§é
ãã®ã²ãŒã ã®ç°¡æããŒãžã§ã³ãäœæããã«ã¯ã次ã®ã³ã³ããŒãã³ããå¿ èŠã§ãã
- XNUMX ã€ã®ã³ã³ãããŒã©ãŒ: GameController.swiftã
- ã¯ã³ãã¥ãŒ: CardCell.swiftã
- XNUMX ã€ã®ã¢ãã«: MemoryGame.swift ãš Card.swiftã
- Main.storyboard ã䜿çšããŠãã³ã³ããŒãã³ãã®ã»ããå šäœãå©çšå¯èœã§ããããšã確èªããŸãã
ã²ãŒã ã®æãåçŽãªã³ã³ããŒãã³ãã§ããã«ãŒãããå§ããŸãã
ã«ãŒãã¹ã€ãã
ã«ãŒã ã¢ãã«ã«ã¯ XNUMX ã€ã®ããããã£ããããŸãããããããèå¥ãã IDãã«ãŒãã®ã¹ããŒã¿ã¹ (é衚瀺ãŸãã¯ãªãŒãã³) ãæå®ããããã«è¡šç€ºãããããŒã«å€æ°ãããã³ã«ãŒãäžã®ç»åã®ã¢ãŒãã¯ãŒã¯ URL ã§ãã
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
ãŠãŒã¶ãŒã«ããããããšã®å¯Ÿè©±ãå¶åŸ¡ããã«ã¯ã次ã®ã¡ãœãããå¿ èŠã«ãªããŸãã
ã«ãŒãäžã«ç»åã衚瀺ããæ¹æ³ã ããã§ã¯ããã¹ãŠã®ããããã£ãããã©ã«ãã«ãªã»ããããŸãã id ã«ã€ããŠã¯ãNSUUIS().uuidString ãåŒã³åºããŠã©ã³ãã 㪠ID ãçæããŸãã
init(image: UIImage) {
self.id = NSUUID().uuidString
self.shown = false
self.artworkURL = image
}
IDã«ãŒããæ¯èŒããæ¹æ³ã
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
}
ãããŠãæåã«ã«ãŒããã·ã£ããã«ããã«ã¯ããã XNUMX ã€ã®æ¹æ³ãå¿ èŠã§ãã ããã Array ã¯ã©ã¹ã®æ¡åŒµåã«ããŸãã
extension Array {
mutating func shuffle() {
for _ in 0...self.count {
sort { (_,_) in arc4random() < arc4random() }
}
}
}
ããã§ã¯ããã¹ãŠã®ããããã£ãšã¡ãœãããåãã Card ã¢ãã«ã®ã³ãŒãã®å®è£ ã瀺ããŸãã
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() }
}
}
}
å ã«è¡ãã
4 çªç®ã®ã¢ãã«ã¯ MemoryGame ã§ãããã§ã¯ 4*XNUMX ã°ãªãããèšå®ããŸãã ã¢ãã«ã«ã¯ãã«ãŒã (ã°ãªããäžã®ã«ãŒãã®é å)ããã§ã«éããŠããã«ãŒããå«ãcardShowné åãã²ãŒã ã®ã¹ããŒã¿ã¹ã远跡ããããã®ããŒã«å€æ°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 å€æ°ã true ã«åæåããŸãã
func newGame(cardsArray:[Card]) -> [Card] {
cards = shuffleCards(cards: cardsArray)
isPlaying = true
return cards
}
ã²ãŒã ãåéãããå Žåã¯ã 次ã«ãisPlaying å€æ°ã false ã«èšå®ããã«ãŒãã®åæã¬ã€ã¢ãŠããåé€ããŸãã
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
}
ãã®ã¡ãœããã¯ã**cardsShown** é åã®æåŸã®èŠçŽ ãèªã¿åããäžèŽããªãã«ãŒããè¿ããŸãã
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 collectionView ã§è¡šãããŸãã collectionView ã«ãŸã æ
£ããŠããªãå Žåã¯ããããåç
§ããŠãã ããã
GameController ãã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒã ã³ã³ãããŒã©ãŒãšããŠèšå®ããŸãã GameController ã«ã¯ãIBOutlet ãšããŠåç §ãã collectionView ããããŸãã ãã XNUMX ã€ã®åç §ã¯ãIBAction onStartGame() ãã¿ã³ã§ãããã㯠UIButton ã§ãããPLAY ãšããã¹ããŒãªãŒããŒãã§ç¢ºèªã§ããŸãã
ã³ã³ãããŒã©ãŒã®å®è£ ã«ã€ããŠå°ã説æããŸãã
- ãŸããXNUMX ã€ã®äž»èŠãªãªããžã§ã¯ããã€ãŸãã°ãªãã: ã²ãŒã = MemoryGame() ãšã«ãŒãã®ã»ãã: ã«ãŒã = [Card]() ãåæåããŸãã
- åæå€æ°ã viewDidLoad ãšããŠèšå®ããŸããããã¯ãã²ãŒã ã®å®è¡äžã«åŒã³åºãããæåã®ã¡ãœããã§ãã
- ãŠãŒã¶ãŒã PLAY ãæŒããŸã§ãã¹ãŠã®ã«ãŒããé衚瀺ã«ãªããããcollectionView ã¯é衚瀺ã«èšå®ãããŸãã
- PLAY ãæŒããšããã«ãonStartGame IBAction ã»ã¯ã·ã§ã³ãéå§ãããã«ãŒãã衚瀺ãããããã« collectionView isHidden ããããã£ã false ã«èšå®ããŸãã
- ãŠãŒã¶ãŒãã«ãŒããéžæãããã³ã«ãdidSelectItemAt ã¡ãœãããåŒã³åºãããŸãã ãã®ã¡ãœããã§ã¯ãdidSelectCard ãåŒã³åºããŠã¡ã€ã³ ã²ãŒã ããžãã¯ãå®è£ ããŸãã
æçµç㪠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)
}
}
ããã§ãéèŠãªãããã³ã«ã«ã€ããŠå°ã説æããŸãããã
ãããã³ã«
ãããã³ã«ã®æäœã¯ Swift ããã°ã©ãã³ã°ã®äžæ žã§ãã ãããã³ã«ã¯ãã¯ã©ã¹ãæ§é äœããŸãã¯åæã®ã«ãŒã«ãå®çŸ©ããæ©èœãæäŸããŸãã ãã®ååã«ãããã¢ãžã¥ãŒã«åãããæ¡åŒµå¯èœãªã³ãŒããäœæã§ããŸãã å®éããã㯠GameController ã® collectionView ã«å¯ŸããŠãã§ã«å®è£ ãããŠãããã¿ãŒã³ã§ãã ã§ã¯ãç¬èªã®ããŒãžã§ã³ãäœæããŠã¿ãŸãããã æ§æã¯æ¬¡ã®ããã«ãªããŸãã
protocol MemoryGameProtocol {
//protocol definition goes here
}
ãããã³ã«ã䜿çšãããšãã¯ã©ã¹ãå®è£ ããããã®ã«ãŒã«ãåœä»€ãå®çŸ©ã§ããããšã¯ããã£ãŠããã®ã§ãããããã©ãããã¹ãããèããŠã¿ãŸãããã åèšXNUMXã€å¿ èŠã§ãã
- ã²ãŒã éå§:memoryGameDidStartã
- ã«ãŒããè£è¿ãå¿ èŠããããŸã:memoryGameShowCardsã
- ã«ãŒããè£è¿ãå¿ èŠããããŸã:memoryGameHideCardsã
- ã²ãŒã çµäº:memoryGameDidEndã
XNUMX ã€ã®ã¡ãœããã¯ãã¹ãŠãã¡ã€ã³ ã¯ã©ã¹ã§ãã GameController ã«å®è£ ã§ããŸãã
ã¡ã¢ãªã²ãŒã ãéå§ããŸãã
ãã®ã¡ãœãããå®è¡ããããšãã²ãŒã ãéå§ãããŸã (ãŠãŒã¶ãŒã PLAY ãæŒããŸã)ã ããã§ã¯ã collectionView.reloadData() ãåŒã³åºããŠã³ã³ãã³ããåããŒãããã ãã§ãã«ãŒããã·ã£ããã«ãããŸãã
func memoryGameDidStart(_ game: MemoryGame) {
collectionView.reloadData()
}
ã¡ã¢ãªã²ãŒã ã·ã§ãŒã«ãŒã
ãã®ã¡ãœãã㯠collectionSDViewSelectItemAt ããåŒã³åºããŸãã ãŸãéžæããã«ãŒãã衚瀺ãããŸãã 次ã«ãcardsShown é åå ã«äžèŽããªãã«ãŒãããããã©ããã確èªããŸã (cardShown ã®æ°ãå¥æ°ã®å Žå)ã ååšããå Žåã¯ãéžæããã«ãŒããšæ¯èŒãããŸãã åçãåãå Žåãäž¡æ¹ã®ã«ãŒããã«ãŒã衚瀺ã«è¿œå ãããè¡šåãã®ãŸãŸã«ãªããŸãã ç°ãªãå Žåãã«ãŒãã¯è¡šç€ºãããã«ãŒããæ®ããäž¡æ¹ãšãè£åãã«ãªããŸãã
ã¡ã¢ãªã²ãŒã é衚瀺ã«ãŒã
ã«ãŒããäžèŽããªãå Žåããã®ã¡ãœãããåŒã³åºãããã«ãŒãã®ç»åãé衚瀺ã«ãªããŸãã
衚瀺 = falseã
ã¡ã¢ãªã²ãŒã çµäº
ãã®ã¡ãœãããåŒã³åºããããšããã¹ãŠã®ã«ãŒãããã§ã«å ¬éãããcardsShown ãªã¹ã (cardsShown.count =cards.count) ã«å«ãŸããŠããããšãæå³ãããããã²ãŒã ã¯çµäºããŸãã ãã®ã¡ãœããã¯ãç¹ã« endGame() ãåŒã³åºã㊠isPlaying å€æ°ã false ã«èšå®ããåŸã«åŒã³åºããããã®åŸã²ãŒã çµäºã¡ãã»ãŒãžã衚瀺ãããŸãã ãŸããalertController ã¯ã³ã³ãããŒã©ãŒã®ã€ã³ãžã±ãŒã¿ãŒãšããŠäœ¿çšãããŸãã viewDidDischaracter ãåŒã³åºãããã²ãŒã ããªã»ãããããŸãã
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()
}
}
å®ã¯ããã ãã§ãã ãã®ãããžã§ã¯ãã䜿çšããŠãç¬èªã®ããŒãžã§ã³ã®ã²ãŒã ãäœæã§ããŸãã
ã³ãŒãã£ã³ã°ã楜ããã§ãã ãã!
ã¹ãã«ããã¯ã¹ã¯æ¬¡ã®ããšãæšå¥šããŸãã
- å®è·µã³ãŒã¹
ãã¢ãã€ã«ããããããŒPROã .- ãªã³ã©ã€ã³ã³ãŒã¹ã®ç³ã蟌ã¿
ãPythonããŒã¿ã¢ããªã¹ãã .- XNUMX幎éã®å®è·µã³ãŒã¹
ãç§ã¯ããã®ãŠã§ãéçºè ã§ãã .
åºæïŒ habr.com