CS113 Lab 8: Memory Game

Credit: Jeff Knerr

Due Friday, April 23, before midnight

Goals

  • practice writing programs with classes and functions

As a kid I loved playing a memory game with cards: place as many pairs of cards as you want face down on a table, then take turns turning over two cards at a time. If the two cards match (both red twos, or black fives, etc), you get to keep the pair. If they don’t match, turn them back face down, and let the other player pick two cards.

For this lab we’re going to write a terminal-based memory card game, allowing a single user to select two cards at a time and see if they match.

Examples and Program Requirements

Here are a few examples of the running program, to help you see how things should work. Pay attention to how the game proceeds, and how input from the user is handled. As you can see from these examples, we have simplified the game a bit, since we’re using a terminal screen to display the game. For example, we don’t clear the screen between turns, making it easy to view past turns.

We are also using a deck of "bird" cards.

You have some freedom in how you want your game to look. Here are our requirements for the full program:

  • the program should print out adequate instructions throughout the game (see examples)

  • the program starts with 10 cards (5 pairs) face down

  • the user selects a card and is shown what that card is

  • the user selects a second card and is shown that card and if it’s a match or not

  • playing the game again should present the user with a different setup (i.e., the cards should be randomly shuffled each game)

  • the program should handle invalid user input properly by re-asking for a value (see Example 2)

  • the program should handle invalid selections (e.g., same card) by not doing them (and telling the user it was an invalid selection)

  • the game should end once all cards have been matched

  • when the game ends display a status message showing how many cards matched, how many turns it took, and a message based on those numbers (e.g., 10 cards in 5 turns: super!, 10 cards in 8 turns: not bad, 10 cards in 35 turns: better luck next time)

  • all output should be clean and easy to read

Card

Implement a class, Card, in the file Card.java. This class represents a card in our memory game.

Card should have the following data

  • mName (String): Stores the contents of the card, e.g. "chicken" or "egret"

  • mIsShowing (boolean): Stores whether the card is showing or not

Card should have the following methods

  • constructor Card(String name): Initializes the name of the card and set mIsShowing to false

  • public boolean matches(Card other): Returns true if the name of the other card matches this card

  • public boolean isShowing(): Accessor which returns mIsShowing

  • public String getName() `: Accessor which returns mName

  • void hide(): Sets mIsShowing to false

  • void show(): Sets mIsShowing to true

Test your Card class in a main function defined in Card.java. For example, the following main would produce the given output.

Card card = new Card("bluebell");
card.show();
System.out.println(card.getName() + " " + card.isShowing());

card.hide();
System.out.println(card.getName() + " " + card.isShowing());

Card test = new Card("tulip");
System.out.println("Matches?: "+test.matches(card));
bluebell true
bluebell false
Matches?: false

MemoryGame

In the file MemoryGame.java implement your memory game. Your main function in MemoryGame should implement the main game loop. Below is pseudocode.

print welcome message
create an array of cards
shuffle the cards

numMatched = 0;
numTurns = 0;
while not done
    increase number of turns by 1
    display the cards

    ask the user for a card
    show the card

    ask the user for an other card
    show the card

    if the two cards match
      increment the number of matches by 1
    else
      hide the cards

print game over messages

Tips

To initialize the cards, we suggest using an array of Strings, something like this:

String[] birds = {"finch","robin","crane","macaw","stork","egret","raven"};

You can make your cards something else if you want (countries, colors, movie characters, etc), but it is easier if all strings in the list have the same length.

For each bird, you need to create a pair of cards.

Card[] cards = new Card[birds.length * 2];
// create pairs of birds using a loop

To shuffle the cards, repeatedly swap cards using random numbers. Below is pseudocode.

for (i = 0; i < numshuffles; i++)
  idx1 = choose a random index
  idx2 = choose a random index
  swap the cards at idx1 and idx2

string formatting

Using the width specifier will probably help you line up all of your cards. In the following example, using %10s means strings with fewer than 10 characters are padded on the left with spaces:

String[] names = {"apple", "orange", "cupcake", "0123456789"};
for (int i = 0; i < names.length; i++) {
  System.out.printf("===%10s===" , names[i]);
}

Produces this output

===     apple===
===    orange===
===   cupcake===
===0123456789===

You have some flexibility in how you implement the functions in MemoryGame.java. However, we recommend your functions match the psuedocode given for main. For example,

  • public static void printWelcome(): Prints the welcome message at the start of the game

  • public static Card[] initCards(): Create the array of cards based on names of birds (or whatever you like)

  • public static void shuffle(Card[] cards): Shuffle the cards

  • public static void displayCards(Card[] cards): Displays the cards. Hidden cards should show a number. Showing cards should show the name

  • public static int askForCard(Card[] cards): Asks the user for a card and returns the index. This function should re-ask the user for input if their choice is invalid.

  • public static boolean isValid(Card[] cards, String userInput): Returns false if the input is not a valid number, is out of range, or corresponds to a card that is already showing.

  • public static void printGoodbye(int numMatched, int numTurns): Prints end of game messages

What to hand-in

  1. The program, MemoryGame.java, adding Card.java

  2. Make sure your programs have a header containing your name, date, and description.

  3. A brief write-up containing your name, assignment number, and a few sentences about how long you spent on the assignment and any interesting customizations you made.

How to hand-in

  1. Copy your files to your dropbox, into the folder called A07.