Saturday, September 25, 2010

A Free game in Java

I wanted to play this game so badly as I use to be very good at it. I was not knowing the proper keyword to find it online. So, what the heck, I went ahead and created one! The front end used was Swing.
The objective of this game is to arrange from numbers 1 through 24 (or depending on the size) in proper order and you have one square free. You can move to that empty sqaure by pressing either of the four arrow keys UP/DOWN/LEFT/RIGHT. All the puzzles formed will have a solution. You can use this code anywhere you want.

If you have Java installed in your browser, you should be able to see the Applet. Just click anywhere inside the applet and start playing using the arrow keys! Have fun!


Screenshot Applet



package boxgame;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class BoxPuzzle extends JFrame{
    private static final long serialVersionUID = 1L;
    
    private static final int SIZE = 5;
    JPanel[][] panelArray = new JPanel[SIZE][SIZE];
    private boolean dialogShown = false;
    
    public BoxPuzzle(){
        this.setTitle(SIZE*SIZE-1+" square puzzle");
        this.add(getGamePanel(SIZE));
        this.setSize(SIZE*75, SIZE*75);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        for(int i=0;i<SIZE*100;i++)//RANDOMIZE MOVES
            handleKeyPress((int)(Math.random()*4) + 37);
        processKeys();
        this.setVisible(true);
    }
    
    private void processKeys(){
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher( 
            new KeyEventDispatcher()  {  
                public boolean dispatchKeyEvent(KeyEvent e){
                    if(e.getID() == KeyEvent.KEY_PRESSED){
                        handleKeyPress(e.getKeyCode());
                        if(areThingsInPlace() && !dialogShown){
                            dialogShown = true;
                            JOptionPane.showMessageDialog(null,"Congratulations!!! YOU WIN!!");
                            System.exit(1);
                        }
                    }
                    return false;
                }  
        });
    }
    
    private void handleKeyPress(int keyCode) {
        int emptyIndex = findEmptyIndex();
        int x = emptyIndex/SIZE;
        int y = emptyIndex%SIZE;
        
        switch (keyCode) {
        case 37://LEFT KEY
            if(y==SIZE-1) return;
            doSwap(x,y,x,y+1);
            break;
        case 38://UP KEY
            if(x==SIZE-1) return;
            doSwap(x,y,x+1,y);
            break;
        case 39://RIGHT KEY
            if(y==0) return;
            doSwap(x,y,x,y-1);
            break;
        case 40://DOWN KEY
            if(x==0) return;
            doSwap(x,y,x-1,y);
            break;
        }
    }
    
    private void doSwap(int x,int y,int x1,int y1){
        Component temp1,temp2;
        temp1 = panelArray[x][y].getComponent(0);
        temp2 = panelArray[x1][y1].getComponent(0);
        panelArray[x][y].remove(0);
        panelArray[x1][y1].remove(0);
        panelArray[x1][y1].add(temp1);
        panelArray[x][y].add(temp2);
        temp2.requestFocus();
        this.repaint();
    }

    private int findEmptyIndex() {
        for(int i=0;i<SIZE;i++)
            for (int j=0;j<SIZE;j++)
                if(!(panelArray[i][j].getComponent(0) instanceof JButton))
                    return i*SIZE + j;
        return 0;
    }

    private boolean areThingsInPlace(){
        for(int i=0;i<SIZE*SIZE-1;i++){
            String name = (panelArray[i/SIZE][i%SIZE].getComponent(0)).getName();
            if(name!=null && !(name.equals(""+i)))
                return false;
        }
        return true;
    }
    
    public static void main(String args[]){
        new BoxPuzzle();
    }

    private JPanel getGamePanel(int difficulty) {
        JPanel pnlGame = new JPanel();
        GridLayout matrixLayout = new GridLayout(difficulty, difficulty);
        pnlGame.setLayout(matrixLayout);
        
        List<JComponent> componentsList = getRandomizedList(difficulty);
        int index = 0;
        for(int i=0;i<difficulty;i++){
            panelArray[i] = new JPanel[difficulty];
            for(int j=0;j<difficulty;j++){
                panelArray[i][j] = new JPanel();
                panelArray[i][j].setLayout(new GridLayout(1,1));
                panelArray[i][j].add(componentsList.get(index++));
                pnlGame.add(panelArray[i][j]);
            }
        }
        return pnlGame;
    }

    private List<JComponent> getRandomizedList(int difficulty) {
        List<JComponent> componentSet = new ArrayList<JComponent>();
        for(int i=0;i<difficulty*difficulty-1;i++){
            JButton button = new JButton(""+(i+1));
            button.setName(""+i);
            componentSet.add(button);
        }
        componentSet.add(new JPanel());
        return componentSet;
    }
}

Cheers,
Bragaadeesh.

5 comments:

Anil Samuel said...

Make an applet and publish it here !!

Bragaadeesh said...

@Anil: Running to office now.. Will do it tonight for sure!!

icewalker2g said...

Man that was a good game. Reminded me soo much of my junior high school days. And I finished the puzzle in under 15 mins (way too long btw).

As in every good piece of code though, there are always bugs. A few NullPointerExceptions in this one on line 93.

Nonetheless, great game. Time to pimp it up Java2D style (if I can make the time) :)

J. J. said...

Here's another free java game. This one uses Seam and Richfaces.

FloodIt

Enjoy

Bragaadeesh said...

@icewalker2g : nice to know it brought some of your green thoughts back!! Line 93 NPE is a stupid one :P. Will fix it!!

@J.J : The UI is lightweight, wants me to develop games in web! thanks for stopping by.