As per the rules of Set, when any card is chosen and there are already 3 matching Set cards selected, replace those 3 matching Set cards with new ones from the deck of 81 Set cards (again, see Set rules for what’s in a Set deck). If the deck is empty then matched cards can’t be replaced, but they should be hidden in the UI. If the card that was chosen was one of the 3 matching cards, then no card should be selected (since the selected card was either replaced or is no longer visible in the UI).
Your UI should be nicely laid out and look good (at least in portrait mode, preferably in landscape as well, though not required) on any iPhone 7 or later device. This means you’ll need to do some simple Autolayout with stack views.
Deal 12 cards only to start. They can appear anywhere on screen (i.e. they don’t have
to be aligned at the top or bottom or anything; they can be scattered to start if you
want), but should not overlap.
Currently the cards in the Model are not randomized (that’s why matching cards end
up always in the same place in our UI). Shuffle the cards in Concentration’s init()
method.
Add a game score label to your UI. Score the game by giving 2 points for every match
and penalizing 1 point for every previously seen card that is involved in a mismatch.
After 3 cards have been selected, you must indicate whether those 3 cards are a match or a mismatch (per Set rules). You can do this with coloration or however you choose, but it should be clear to the user whether the 3 cards they selected match or not.
Like you did for Concentration, you must have a New Game button and show the Score in the UI. It is up to you how you want to score your Set game. For example, you could give 3 points for a match and -5 for a mismatch and maybe even -1 for a deselection. Perhaps fewer points are scored depending on how many cards are on the table (i.e. how many times Deal 3 More Cards has been touched). Whatever you think best evaluates how well the player is playing.
Penalize pressing Deal 3 More Cards if there is a Set available in the visible cards. You’ll have to write an algorithm to determine whether a pile of Set cards does, in fact, include at least one Set.
Change the background and the “card back color” to match the theme.
For example:
Our Halloween theme has a black background and orange card backs. Maybe a
“winter” theme might have blue and white colors. A “construction” theme could be
black and yellow. UIViewController has a property called view which is connected to
the top-level view in the scene (i.e. the view that was black in lecture).
No need to go overboard here. Maybe just a button for each user that can be used to claim they see a Set on the board, then that player has a certain (fairly short) amount of time to actually choose the Set or the other person gets a turn (with twice as much time to find a Set)? Most Sets found wins. Hitting Deal 3 More Cards on one user’s side might give the other person a medium amount of time to find a Set without penalty if they can’t? Up to you.
You’ll probably need Timer (as mentioned in last week’s extra credit) to do this one.
Do not “pre-allocate” space for all 81 possible cards. At any given time, cards should
be as large as possible given the screen real estate available to cards and the number of
cards currently in play. In other words, when the game starts (with only 12 cards), the
cards will be pretty big, but as more and more cards appear on screen (due to Deal 3
More Cards), they will have to get smaller and smaller to fit.
The Deal 3 More Cards button should be disabled if there are:
no more cards in the Set deck
no more room in the UI to fit 3 more cards (note that there is always room for 3 more cards if the 3 currently-selected cards are a match since you replace them).
Factor “speed of play" into the user’s score. You can find out what time it is (to a fraction of a second) using the Date struct. The faster the user finds Sets, the higher his or her score should be. The penalty for mismatches probably needs to be high to discourage too much guessing.
Instead of drawing the Set cards in the classic form (we’ll do that next week), we’ll use these three characters ▲ ● ■ and use attributes in NSAttributedString to draw them appropriately (i.e. colors and shading). That way your cards can just be UIButtons. See the Hints for some suggestions for how to show the various Set cards.
Have a “play against the iPhone” mode. Each time a set is found, start a random-length timer (you’ll have to learn how to use Timer.scheduledTimer(withTimeInterval:repeats:) { } for this which uses a
closure!) after which the iPhone picks a set if the user does not pick one first. See who can get the most sets! Maybe represent the iPhone with an emoji somewhere on the screen (� while the timer is running, then maybe � a couple of seconds before the iPhone makes a turn and � if the iPhone wins or � if not)? As always, be sure to give careful thought to your MVC architecture if you tackle this one.
Give your game the concept of a “theme”. A theme determines the set of emoji from
which cards are chosen. All emoji in a given theme are related by that theme. See the
Hints for example themes. Your game should have at least 6 different themes and
should choose a random theme each time a new game starts.
You can find out what time it is using the Date struct. Read the documentation to
figure out how it works and then use it to adjust your scoring so that the more quickly
moves are made, the better the user’s score is. You can modify the scoring Required
Task in doing this, but the score must still somehow be dependent on matches being
rewarded and mismatches of previously-seen cards being penalized (in addition to
being time-based). It’s okay if a “good score” is a low number and a “bad score” is a
high number.
Allow the user to select cards to try to match as a Set by touching on the cards. It is
up to you how you want to show “selection” in your UI. See Hints below for some
ideas. Also support “deselection” (but when only 1 or 2 (not 3) cards are currently
selected).
Hints:-
You can show selection using the UIButton’s backgroundColor if you want, but UIKit
also knows how to put a border around any UIView (including a UIButton) with code
like this (which would draw a 3 points wide border in blue, for example):