Game Development 22 min read

Java Implementation of a Link‑Matching (连连看) Puzzle Game with Connection Algorithms and UI

This article explains how to build a classic link‑matching puzzle game in Java, covering the grid data model, random map generation, three connection algorithms (direct, one‑corner, two‑corner), mouse interaction, drawing routines, smart hint, shuffling, win detection and game restart, all illustrated with complete source code.

Java Captain
Java Captain
Java Captain
Java Implementation of a Link‑Matching (连连看) Puzzle Game with Connection Algorithms and UI

The tutorial introduces a "连连看" (link‑matching) desktop game, which challenges players to eliminate pairs of identical tiles within a limited time, allowing at most two bends in the connecting line.

Game data model : The board is an N×M grid stored in a two‑dimensional int array where each cell holds an image ID; -1 represents an empty cell (BLANK_STATE).

Map generation creates a 10×10 grid with ten different animal images, each appearing ten times. A temporary ArrayList list holds the IDs, which are then randomly placed into the map array:

public int[][] getMap(){
    ArrayList
list = new ArrayList
();
    for(int i=0;i
Connection algorithms
:
Direct connection (horizontal or vertical) – implemented in
horizontalLink
and
verticalLink
.
One‑corner connection – implemented in
oneCornerLink
by checking the two possible rectangle corners.
Two‑corner connection – implemented in
twoCornerLink
which searches outward from the first tile for a valid intermediate point and then uses the one‑corner logic.
Helper methods
throughHorizontalLink
and
throughVerticalLink
verify that a path to the board edge contains only empty cells.
private boolean throughHorizontalLink(int clickX,int clickY,boolean flag){
    if(flag){
        for(int i=clickY-1;i>=0;i--){
            if(map[clickX][i]!=BLANK_STATE) return false;
        }
    }else{
        for(int i=clickY+1;i
Mouse interaction
is handled in
mousePressed
. It translates pixel coordinates to grid indices, tracks the first and second clicks, checks whether the selected tiles can be linked using the algorithms above, draws selection boxes, draws the connecting line, updates the board and resets the click state.
@Override
public void mousePressed(MouseEvent e){
    Graphics g = this.getGraphics();
    int x = e.getX()-leftX;
    int y = e.getY()-leftY;
    int i = y/50;
    int j = x/50;
    if(x<0||y<0) return;
    if(isClick){
        if(map[i][j]!=BLANK_STATE){
            if(map[i][j]==clickId){
                if(i==clickX&&j==clickY) return;
                if(verticalLink(clickX,clickY,i,j)||horizontalLink(clickX,clickY,i,j)||oneCornerLink(clickX,clickY,i,j)||twoCornerLink(clickX,clickY,i,j)){
                    drawSelectedBlock(j*50+leftX,i*50+leftY,g);
                    drawLink(clickX,clickY,i,j);
                    isClick = false;
                }else{
                    clickId = map[i][j];
                    clearSelectBlock(clickX,clickY,g);
                    clickX = i; clickY = j;
                    drawSelectedBlock(j*50+leftX,i*50+leftY,g);
                }
            }else{
                clickId = map[i][j];
                clearSelectBlock(clickX,clickY,g);
                clickX = i; clickY = j;
                drawSelectedBlock(j*50+leftX,i*50+leftY,g);
            }
        }
    }else{
        if(map[i][j]!=BLANK_STATE){
            clickId = map[i][j];
            isClick = true;
            clickX = i; clickY = j;
            drawSelectedBlock(j*50+leftX,i*50+leftY,g);
        }
    }
}
Drawing utilities
:
drawSelectedBlock
draws a red 48×48 rectangle inside the 50×50 tile.
clearSelectBlock
erases the rectangle and redraws the underlying image.
drawLink
renders the connection line according to the link method (horizontal/vertical, one‑corner, two‑corner) and then pauses 500 ms before removing the tiles.
private void drawLink(int x1,int y1,int x2,int y2){
    Graphics g = this.getGraphics();
    Point p1 = new Point(y1*50+leftX+25, x1*50+leftY+25);
    Point p2 = new Point(y2*50+leftX+25, x2*50+leftY+25);
    if(linkMethod == LINKBYHORIZONTAL || linkMethod == LINKBYVERTICAL){
        g.drawLine(p1.x,p1.y,p2.x,p2.y);
    }else if(linkMethod == LINKBYONECORNER){
        Point z = new Point(z1.y*50+leftX+25, z1.x*50+leftY+25);
        g.drawLine(p1.x,p1.y,z.x,z.y);
        g.drawLine(p2.x,p2.y,z.x,z.y);
    }else{ // two corners
        Point zA = new Point(z1.y*50+leftX+25, z1.x*50+leftY+25);
        Point zB = new Point(z2.y*50+leftX+25, z2.x*50+leftY+25);
        if(p1.x!=zA.x || p1.y!=zA.y){
            Point tmp = zA; zA = zB; zB = tmp;
        }
        g.drawLine(p1.x,p1.y,zA.x,zA.y);
        g.drawLine(p2.x,p2.y,zB.x,zB.y);
        g.drawLine(zA.x,zA.y,zB.x,zB.y);
    }
    count+=2;
    GameClient.textField.setText(String.valueOf(count));
    try{ Thread.currentThread().sleep(500); }catch(InterruptedException e){}
    repaint();
    map[x1][y1]=BLANK_STATE; map[x2][y2]=BLANK_STATE;
    isWin();
}
Image handling and painting
are done with Swing:
getPics
loads ten PNG files into an
Image[] pics
array, and
paint
iterates over the board drawing each non‑blank tile.
private void getPics(){
    pics = new Image[10];
    for(int i=0;i<=9;i++){
        pics[i] = Toolkit.getDefaultToolkit().getImage("D:/Game/LinkGame/pic"+(i+1)+".png");
    }
}

public void paint(Graphics g){
    g.clearRect(0,0,800,30);
    for(int i=0;i
Smart hint
(
find2Block
) scans the board for any pair of matching tiles that can be linked; if found it highlights them and removes them automatically.
private boolean find2Block(){
    if(isClick){
        clearSelectBlock(clickX,clickY,this.getGraphics());
        isClick = false;
    }
    for(int i=0;i
Shuffling
(
getResetMap
) extracts all remaining IDs into a list, clears the board, then randomly places them back.
Game restart
(
startNewGame
) re‑initialises all state variables, creates a fresh map and repaints.
The article concludes with a download link for the full source code and encourages readers to discuss or suggest improvements.
JavaUIalgorithmGame developmentSwingpuzzle
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.