The Fun with Random Series shuffles on with a card game!

Hi everybody!

Axure HQ here to share another “Fun With Random” project with you all.

Past Fun With Random games include Connor’s Spot the Difference, Chelsea’s Something Monsters game, Alyssa’s Rock, Paper, Scissors, Lizard, Spock, the infamous Monty Hall Problem created by Jonathan, and other classics such as Axure Quest VIII, Julie’s Game of Cards, and Deal or No Deal. In the newest installment of the Fun with Random game series, I introduce the age old parlour game of Pairs!

During this game you’ll put your memory to the test - trying to match face down pairs of cards by number value or type. The more pairs you find, the easier it will get! Essentially you can turn over any two cards at a time, the first of those cards will remain face up while the second will turn over for a short period before being turned back face down. You can turn the first of the two cards back over at any time to allow you to choose an alternative. Each time you match a pair of cards you score a point, get to 26 points within the allotted time and you win the game! You can select between three different levels of difficulty, each reducing the time you have to find all pairs. Hit the “Start” button to kick off the count down or “Reset” if you think you made a mistake and want to start again,

Play the game here!

Breakdown of the game:

The game is based around a repeater that contains all 52 card faces within its dataset. Each instance of an item, from within the dataset, has a dynamic panel placed on it that has a second state with the card back image. When the card back is clicked an event triggers and depending on the conditional met, will change the dynamic panels state to reveal the card face beneath it. So as to ensure there are only ever two, non matched, cards visible at any given time, we keep track via the “MarkedCount” variable. If a card is the first new card flipped, the user can then go on to flip a second card. If the second card is a match of the first, the score is increased by 1, “MarkedCount” is reduced to 0 and the user can go on the look for another pair. If there is no match, the second card turns back over, reducing the “MarkedCount” by 1 and the user can continue to look for matches. This process repeats until either the timer runs out or the user has flipped all 26 pairs.

Tricky logic

When creating this game there were a couple of hurdles to overcome within the confines of a prototype. Firstly, to verify a match between cards, we have to keep track of the value of the previous flipped card. This was achieved by categorising each card within the repeater dataset (simply numbered 1-13 to represent all cards in a suit) which then gets appended to the “CardValue” variable, when the card is clicked. When a second card is clicked, a comparison is done between the “CardValue” variable and the value of the clicked card in the repeaters dataset using [[item.Category]]. This produced the desired results when both cards are a pair but left us with the problem of what to do if the second card is not a match. We don’t want to hold the cards value as it is now flipped over to its back side and if we go on to click another card of the same value, we would get a false positive match. To solve this, I created a variable that keeps track of the previous cards value so that if there is not a match on the second card, the “CardValue” variable will be replaced that of the “LastCard” variable.

The second conundrum that came from using the “CardValue” variable as a comparison, was that of timing. If the “cardValue” variable is populated when a card is clicked, the proceeding comparison case, that checks if there is a match, would essentially find that the card is a match with itself. As Axure RP wasn’t particularly designed to have a lot of nested conditional statements (this is prototyping after all) I had to scratch my head for an alternative. In came the “Fire Event” action to the rescue. By placing all of my comparison logic in a different event ( I chose the “Get Focus” event but it doesn’t really matter, as long as the event won’t be triggered by other things happening in the viewport) I could then fire this event from within the first conditional which checks whether to flip a card. I now love the “Fire Event” action even more!

Randomised Cards

Now it wouldn’t be fun if all the cards were just placed in order! To ensure the game has some repeatable value, I wanted to have the cards placed in a random order each time a new game is started, this is “Fun With Random” after all. To implement this, I created a “Page Loaded” event on the canvas. It would be a tricky task to randomise the cards within a repeater, so I added a column named “Random ID” and then populated each row, using the “Update Rows” action, with a randomised number using the following expression:

[[Math.floor(Math.random() * 52) + 1]]

Following that, within the same “Page Loaded” event, I then sorted the cards by the “Random ID” column so that when the “Item Loaded” event is triggered, it places the items in that random order, onto the canvas.

Final Thoughts and The Next Iteration

Having done all of this, there are still a few bugs that could possibly be figured out for the next iteration. Currently, if a user was to click on a card that is face up and has already been identified as a match, it messes up the logic. I would like to be able to prevent the user from clicking any matched pairs visible but haven’t decided how best to keep track of those paris and their positions.

There can also be a problem if the user repeatedly clicks too fast on more than two cards in succession, sometimes causing the “MarkedCount” variable to become out of sync.

Have a go at trying to fix these bugs or improving the game, by downloading the .rp file below.

Breaker of Chains

Warning - Please don’t click the cards too fast in succession and don’t try to flip matched pairs back over. It will probably break!

Download the .rp file and happy prototyping :slight_smile: