CS193P – Assignment 3
So onto assignment 3 of Matchismo. This is by far the most involved assignment, especially if you plan on completing all the optional requirements (which I did).
Task 1 & 2
“Create an application that plays both the Set game (single player) in one tab and the Playing Card matching game in another.”
“You must use polymorphism to design your Controllers for the two games (i.e. you must have a (probably abstract) base card game Controller class and your Set game and Playing Card game Controllers must be subclasses thereof).”
OK so my version of Matchismo already conforms to these requirements as at the end of Assignment 2.
“For Set, 12 cards should be initially dealt and Set cards should always show what’s on them even if they are technically “face down”. For the Playing Card game deal 22 cards, all face down.”
I started by removing all reference to the cardButtons in both the card game and set game view controllers, deleting the buttons off the storyboard views and then amending the ‘startingCardCount methods for each viewController.
I then dragged out a UICollectionView in the storyboard and placed it where the buttons had previously been along with making the generic view contoller it’s datasource and delegate, not forgetting to set the class and reuse identifer of the cell to “Playing Card”. I then repeated this for the Set Card view, setting the reuse identifier to “SetCard” after dragging a UIView into the cell and having created a SetCardCollectionViewCell subclass. After wiring up all the outlets I implemented a simple setCard view to get the cards displaying on the screen.
“The user must then be able to choose matches just like in last week’s assignment.”
This is just a matter of setting up the tapGestureRecognizer by dragging a gesture recognizer onto the collection view and linking it to the flipCard method, I then added a call to ‘setNeedsDisplay’ in the setters of the setCard game.
“When a Set match is successfully chosen, the cards should be removed from the game (not just blanked out or grayed out, but actually removed from the user-interface and the remaining cards rearranged to use up the space that was freed up in the user- interface).”
For this I added a numberOfCards property and a method to remove cards from the game at a given index. I then added a BOOL property to say whether an unPlayable card should be removed and as part of the flipCard method, I check this property, if true I remove the cards from the model using the above method and then use ‘deleteItemsAtIndexPath’ to remove the cards from the collection view, this is automatically animated.
“Set cards must have the “standard” Set look and feel (i.e. 1, 2 or 3 squiggles, diamonds or ovals that are solid, striped or unfilled, and are either green, red or purple). You must draw these using Core Graphics and/or UIBezierPath. You may not use images or attributed strings. Use the PlayingCardView from the in-class demo to draw your Playing Card game cards.”
This assignment just involves the implementation of drawRect in the set card view, there are many possible ways to do this so feel free to check out GitHub for my implementation.
In the Set game (only), the user must always have the option somewhere in the UI of requesting 3 more cards to be dealt at any time if he or she is unable to locate a Set.
I started by dragging out a UIButton and renaming the title to “+3″. and it’s tag to 3. I then dragged an action from the button into the controller for ‘add3CardButtonPressed’ in which I simply called a new method ‘drawNewCard’ which implemented in the cardMatchingGame, this just loops 3 times calling the existing drawRandomCard method.
“Automatically scroll to show any new cards when you add some in the Set game.”
This is just a matter of implementing scrollToItemsAtIndexPath and passing in the numberOfCards property.
“Do something sensible when no more cards are in the deck and the user requests more.”
For this I added a new property for deckIsEmpty and checked it for a zero value in dealButtonPressed, if so I greyed out the add cards button and disabled it. In the getter for deckIsEmpty I check the numberOfCardsInDeck property which I added to the deck model.
“If there are more cards than will fit on the screen, simply allow the user to scroll down to see the rest of the cards. Pick a fixed (and reasonable) size for your cards and keep them that size for the whole game.”
The collection view already does this for us.
“It is very important that you continue to have a “last flip status” UI and that it show not only matches and mismatches, but also which cards are currently selected (because there can be so many cards now that you have to scroll to get to all the cards in a match). A UILabel may no longer be sufficient for this UI.”
For this I implemented a specific version of updateUI in the setCardGame view controller, which drew a set of three cards at the bottom of the UICollectionView (but outside of the view) to display and selected cards and highlight them if a match is found.
“The flip counter can be removed from the game. You must still show the score, however.”
Pretty straighforward, just delete the flipCount from the storyboard.
Task 13 & 14
“The user should still be able to abandon the game and start over with a fresh group of cards at any time (i.e. re-deal).”
This is already implemented as part of the deal button.
“The game must work properly (and look good) in both Landscape and Portrait orientations on both the iPhone 4 and the iPhone 5. Use Autolayout to make this work (not struts and springs).”
If you’ve watched lecture 8 this is pretty straight forward, it’s a matter of making sure you have no fixed widths (athough I think I had to put one on a button) and pinning a few UI elements. Don’t forget to turn AutoLayout on.
I’ll do another blog post for the extra tasks as part of the assignment. The solution up to this point can be found on my GitHub.