Java Memory Game – Put Your Mind to the Test

In this project, we will create a Memory Game using Java Swing. The Memory Game is a popular game where players need to match pairs of identical cards by flipping them over. Our Memory Game will have a graphical user interface (GUI) implemented using Java Swing components. The game will consist of multiple levels and different difficulty modes.

About Java Memory Game App

The objective of this project is to guide learners in creating a Memory Game using Java’s Swing library. By following the project, learners will gain hands-on experience in setting up the game window, handling user interactions, implementing game logic for comparing and matching cards, and displaying the final score.

Prerequisites for Memory Game App using Java

To successfully follow along with this project, you should have a basic understanding of Java programming and object-oriented concepts. It is also important to have the Java Development Kit (JDK) installed on your machine for code compilation and execution.

Additionally, a working knowledge of Java Swing, a framework for creating GUIs, is required to comprehend and work with the graphical components used in this project. While any Integrated Development Environment (IDE) can be used, this tutorial utilizes Eclipse as the IDE of choice.

Download Java Memory game App Project

Please download the source code of Java Memory game App Project: Java Memory game App Project Code

Steps to Create Memory Game App Project using Java

Step 1:Setting up the Project in Eclipse:

Step 2: Implementing the code :

Step 3: Understanding the code we implemented:

Step 1:Setting up the Project in Eclipse:

>Create a new Java project in Eclipse.
>Right click on the project folder and create a new folder named images
>Paste the images you want to use in the game inside the folder, or you can use the images provided with the source code of this project
The project structure should look something like this:

project structure

The images with numbers as their name are different colors which we will use in the Hard difficulty mode, and the rest of the images will be used in the Easy difficulty mode.

Step 2: Implementing the code :

Here is the complete code for the MemoryGame.java:

package school.FirstCode;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;

@SuppressWarnings("serial")
public class MemoryGame extends JFrame implements ActionListener{

    private JPanel gamePanel;
    private JPanel winPanel;
    private String[] easyLvl = {"images/bear.png",
                                "images/cat.png",
                                "images/cow.png",
                                "images/dog.png",
                                "images/giraffe.png",
                                "images/hippo.png",
                                "images/horse.png",
                                "images/lion.png",
                                "images/monke.png",
                                "images/pig.png",
                                "images/bear.png",
                                "images/cat.png",
                                "images/cow.png",
                                "images/dog.png",
                                "images/giraffe.png",
                                "images/hippo.png",
                                "images/horse.png",
                                "images/lion.png",
                                "images/monke.png",
                                "images/pig.png"};
    
    private String[] hardLvl = {"images/1.png",
                                "images/10.png",
                                "images/2.png",
                                "images/3.png",
                                "images/4.png",
                                "images/5.png",
                                "images/6.png",
                                "images/7.png",
                                "images/8.png",
                                "images/9.png",
                                "images/1.png",
                                "images/10.png",
                                "images/2.png",
                                "images/3.png",
                                "images/4.png",
                                "images/5.png",
                                "images/6.png",
                                "images/7.png",
                                "images/8.png",
                                "images/9.png"};

    private List<String> currentList;
    private JButton[] cardButtons = new JButton[25];
    private boolean firstClick = true;
    private int cardOpenIdx;
    private boolean cardFlipped = false;
    private int score= 0;
    private JPanel startPanel;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MemoryGame window = new MemoryGame();
                    window.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MemoryGame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        setTitle("Memory Game by FirstCode");
        setBounds(100, 100, 450, 300);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
        
        gamePanel = new JPanel(new GridLayout(5,5,0,0));
        
        startPanel = new JPanel();
        getContentPane().add(startPanel);
        startPanel.setLayout(null);
        
        JLabel lblSelectDifficulty = new JLabel("Select Difficulty:");
        lblSelectDifficulty.setBounds(12, 225, 120, 15);
        startPanel.add(lblSelectDifficulty);
        
        JTextArea txtrInstructions = new JTextArea();
        txtrInstructions.setEditable(false);
        txtrInstructions.setWrapStyleWord(true);
        txtrInstructions.setText("In this game you have to match the pair of cards with same images.\n For every correct match you get 1 Point and for every wrong match you get -1 point\n\nThere are two difficulty levels Easy and Hard.In easy mode you have to match animal images and in hard mode you have to match different color shades \n\nTo Start the game select a difficulty level form below:");
        txtrInstructions.setLineWrap(true);
        txtrInstructions.setBounds(20, 0, 400, 200);
        startPanel.add(txtrInstructions);
        
        JButton btnEasy = new JButton("Easy");
        btnEasy.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                remove(startPanel);
                setSize(new Dimension(750,800));
                getContentPane().add(gamePanel);
                setLevel(easyLvl);
                revalidate();
                repaint();
            }
        });
        btnEasy.setBounds(150, 220, 117, 25);
        startPanel.add(btnEasy);
        
        JButton btnHard = new JButton("Hard");
        btnHard.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                remove(startPanel);
                setSize(new Dimension(750,800));
                getContentPane().add(gamePanel);
                setLevel(hardLvl);
                revalidate();
                repaint();
            }
        });
        btnHard.setBounds(279, 220, 117, 25);
        startPanel.add(btnHard);

        
        
    }
    
//	Method to set the level and initialize the game variables
    private void setLevel(String[] icons) {
        score = 0;
        currentList = Arrays.asList(icons);
        Collections.shuffle(currentList);//shuffling the list to randomize the image positions
        for(int i = 0;i<20;i++){
            cardButtons[i] = new JButton();
            cardButtons[i].addActionListener(this);
            cardButtons[i].setIcon(new ImageIcon(currentList.get(i)));
            cardButtons[i].setBorder(new LineBorder(Color.black));
            cardButtons[i].setContentAreaFilled(false);;			
            gamePanel.add(cardButtons[i]);
        }
    }
    
//	method to hide all the cards from the user
    private void hideAll() {
        for(int i = 0;i<20;i++){
            cardButtons[i].setIcon(null);
        }
    }
    
//	Method to hide a card from the user 
    private void hideCard(int i) {
            cardButtons[i].setIcon(null);
    }
    
//	Method to check if all the elements in the list are matched
    private boolean checkWin() {
        String firstElement = currentList.iterator().next();  // Get the first element
        
        for (String element : currentList) {
            if (!element.equals(firstElement)) {
                return false;  // Element is different from the first element
            }
        }
        
        return true;  // All elements are the same

    }
    
//	Method to add the winnig screen and show the score and playAgain option
    private void winScreen() {
        remove(gamePanel);
        winPanel = new JPanel(new GridLayout(0,1));
        String winString = "You Lost!!Your score was "+score;
        if(score>0) {winString = "You Win!!Your score was "+score;}
        winPanel.add(new JLabel(winString));
        JButton playAgain = new JButton("Play Again");
        playAgain.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                remove(winPanel);
                getContentPane().add(startPanel);
                revalidate();
                repaint();
            }
        });
        winPanel.add(playAgain);
        setSize(new Dimension(450,300));
        getContentPane().add(winPanel);
        revalidate();
        repaint();
    }
    
//	Implementing the actionPerformed method to handle multiple button clicks
    @Override
    public void actionPerformed(ActionEvent e) {
        if (firstClick) {
            hideAll();
            firstClick = false;
            return;
        }

//Handling the clicks and checking if the cards match or not for every button
        for (int i = 0; i < cardButtons.length; i++) {
            if (e.getSource() == cardButtons[i] && currentList.get(i) != "matched") {
                cardButtons[i].setIcon(new ImageIcon(currentList.get(i)));

                if (cardFlipped) {
                    if (currentList.get(cardOpenIdx) == currentList.get(i) && i != cardOpenIdx) {
                        currentList.set(i, "matched");
                        currentList.set(cardOpenIdx, "matched");
                        cardFlipped = false;
                        score++;
                    } else {
                    	score--;
                        cardFlipped = false;

                        final int secondCardIndex = i; // Create a final copy of i

                        Timer timer = new Timer(150, new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                hideCard(cardOpenIdx);
                                hideCard(secondCardIndex); // Use the final copy of i
                            }
                        });
                        timer.setRepeats(false);
                        timer.start();
                    }
                } else {
                    cardOpenIdx = i;
                    cardFlipped = true;
                }
            }
            
           
        }
         if(checkWin()) {
            	winScreen();
            }
        
    }

}

Step 3:Understanding the code we implemented:

The code implements a Memory Game using Java’s Swing library for creating a graphical user interface (GUI). The game consists of a grid of cards that the player needs to match.

When the program is executed, the main method is called, which creates an instance of the MemoryGame class and makes the game window visible.

The MemoryGame class extends JFrame and acts as the main window for the game. It contains methods for initializing the game, setting the difficulty level, handling card clicks, and displaying the win/lose screen.

The initialize method sets up the initial UI components, including a start panel with instructions and buttons for selecting the difficulty level. The setLevel method is called when the player selects a difficulty level. It shuffles the card icons, creates buttons for each card, assigns the shuffled icons to the buttons, and adds them to the game panel.

The actionPerformed method handles button clicks. It determines which card button was clicked and compares the icons on the cards. If the icons match, the cards remain face-up, and the score is incremented. If the icons do not match, the cards are briefly shown to the player before being hidden again, and the score is decremented.

The checkWin method is called after each move to check if all the cards have been matched. If all the cards are matched, the winScreen method is called, which removes the game panel and displays a win/lose screen with the final score and an option to play again.

Here’s an explanation of the functions in the code:

1. “MemoryGame()” – The constructor method for the “MemoryGame” class. It calls the “initialize()” method to set up the game.

2. “initialize()” – Initializes the JFrame window and sets up the initial UI components. It creates a start panel with instructions and buttons for selecting the difficulty level.

3. “setLevel(String[] icons)” – Sets the game level and initializes the game variables. It takes an array of icons representing the cards for the selected level. The method shuffles the icons, creates JButton instances for each card, assigns the icons to the buttons, and adds them to the game panel.

4. “hideAll()” – Hides all the cards by removing the icons from the buttons. It is called when the game starts or when the player makes an incorrect match.

5. “hideCard(int i)” – Hides a specific card identified by its index. It removes the icon from the button.

6. “checkWin()” – Checks if all the cards have been matched. It compares the first element in the “currentList” (shuffled list of icons) with every other element. If any element is different, the method returns false, indicating that not all cards are matched. If all elements are the same, it returns true, indicating that the player has won.

7. “winScreen()” – Adds a winning screen to the frame when the game is won or lost. It removes the game panel and creates a winning panel with a label showing the score and a “Play Again” button. Clicking the button returns the player to the start panel.

8. “actionPerformed(ActionEvent e)” – Handles the button clicks in the game. It is implemented from the “ActionListener” interface. This method is called when a button is clicked. It performs different actions based on the game’s logic. Initially, it hides all the cards when the first button is clicked. After that, it checks which button was clicked and compares the icons on the cards. If the icons match, the cards remain face-up, and the score is incremented. If the icons do not match, the cards are hidden after a brief delay, and the score is decremented. The method also checks if the game has been won after each move.

9. “main(String[] args)” – The entry point of the program. It creates an instance of “MemoryGame” and makes it visible.

Java Memory Game Output

java memory game output

memory game output

memory game project output

java memory game project output

Summary:

In this project, we learned how to create a Memory Game using Java’s Swing library. We started by setting up the game window and creating panels for the UI components. We then initialized the game with different difficulty levels, shuffling and assigning icons to the card buttons.

We learned how to handle user interactions by implementing logic for comparing clicked cards and updating the score accordingly. We also implemented functionality to flip the cards back if they don’t match. We explored how to check for a win condition by verifying if all the cards had been matched.

Leave a Reply

Your email address will not be published. Required fields are marked *