Monday, June 9, 2014
Today in this article I will show you how to create or develop a Tower of Hanoi game in Java. The Tower of Hanoi is a famous problem that is solved by recursion. It has 3 towers and the first tower contains n number of disks. A person is said to have completed or solve the problem if he is able to move all the disks to the third tower with certain constraints.
    Similarly in the game that is developed here follows the rules - 1. Only one disk can be moved at a time. 2. Cannot place a larger disk on a smaller disk. The game her when starts will start with 4 initial disks. You will have to move all the disk to 3rd tower. You can use this game and ask people to complete and win the game of Tower of Hanoi. You also have a choice to select the number of disks you want to play with. So our main objective her is that we will actually not solve the Tower of Hanoi problem, rather use it as a game and ask players of the game to solve the problem.

    Here in our code we have two classes. The Run_Game class contains the main method and build the frame and menus of the game. The second class Tower is the important one and backbone of the game. Here first of all 2 arrays (size of 3) of stacks are created. One for holding disk values and other for color of disk. We need array of size 3 as there are three towers. So actually there are 3 stacks to contain disks. Now whenever a player clicks on a disk it is checked on which tower it is located. Now if it is on top of that tower then he can drag the disk. Now as soon as he releases his mouse again the tower where mouse is released is calculated and after that it is checked whether it is smaller than the top disk of that tower. If it is larger then an error message is generated and disk is placed at its previous position. But if it is a valid move then it is placed on that tower. In this way the game goes on until all the disks are moved.
Initial position

Game in transition

-------------------------------------------------------------------------------------------------------------------------
Java Source Code
-------------------------------------------------------------------------------------------------------------------------
Source Code for Tower.java
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class Tower extends JPanel implements MouseListener,MouseMotionListener{
    
    public static final long serialVersionUID=0xff;
    
    private Stack<Rectangle2D.Double> s[]=new Stack[3];
    private Stack<Color> disk_color[]=new Stack[3];
    private static Rectangle2D.Double top=null;
    private Color top_color=null;
    private double ax,ay,w,h;
    private boolean draggable=false,firstTime=false;
    
    public Tower() {
     firstTime=true;
     init(4);
     addMouseListener(this);
     addMouseMotionListener(this);
    }
    
    public void init(int val){
      Color c[]={Color.yellow,Color.red,Color.blue,Color.pink,Color.cyan,Color.magenta,Color.green,Color.orange,Color.lightGray};
                    
      s[0]=new Stack<Rectangle2D.Double>();
      s[1]=new Stack<Rectangle2D.Double>();
      s[2]=new Stack<Rectangle2D.Double>();
      
      disk_color[0]=new Stack<Color>();
      disk_color[1]=new Stack<Color>();
      disk_color[2]=new Stack<Color>();
            
      for (int i = 0; i<val; i++) {
      Rectangle2D.Double r=new Rectangle2D.Double();
   
     double x = getWidth()/6 ;
     x = (x == 0)?109 : x;
     double wr = val*25-20*i;
     r.setFrame(x-wr/2,190-i*20,wr,20);
        s[0].push(r);
        disk_color[0].push(c[i]);
      }
     
     top=null;
     top_color=null;
     ax=0.0; ay=0.0;  w=0.0;  h=0.0;
     draggable=false;
     repaint();
    }
    
    public void mouseClicked(MouseEvent ev){}
    
    public void mousePressed(MouseEvent ev){
     Point pos=ev.getPoint();
     int n=current_tower(pos);
     if(!s[n].empty()){
         top=s[n].peek();
         if(top.contains(pos)){
          top=s[n].pop();
          top_color=disk_color[n].pop();
          ax=top.getX();    ay=top.getY();
          w=pos.getX()-ax;   h=pos.getY()-ay;
          draggable=true;  //allowing dragging if current mouse position is in top disk
         }
         else{
          top=null;
          top_color=Color.black;
          draggable=false;
         }
     }
    }
    
    public void mouseReleased(MouseEvent ev){
     if(top!=null && draggable==true){
      int tower=current_tower(ev.getPoint());
      double x,y;
         if(!s[tower].empty()){
            if(s[tower].peek().getWidth()>top.getWidth())
                 y=s[tower].peek().getY()-20;  //calculating ay for dragged disk for placement
            else{
                JOptionPane.showMessageDialog(this,"Wrong Move","Tower Of Hanoi",JOptionPane.ERROR_MESSAGE);
                 tower=current_tower(new Point((int)ax,(int)ay));
                 if(!s[tower].empty())
                     y=s[tower].peek().getY()-20; 
                 else
                     y=getHeight()-40;
                   //return; //cannot put bigger disk on a smaller one
               }
         }
      else
          y=getHeight()-40;  //if no previous disk in tower
      
      x=(int)(getWidth()/6+(getWidth()/3)*tower-top.getWidth()/2);
      top.setFrame(x,y,top.getWidth(),top.getHeight());
         s[tower].push(top);
         disk_color[tower].push(top_color);
         
         top=null;
         top_color=Color.black;
         draggable=false;
         repaint();
     }
    }
    
    public void mouseEntered(MouseEvent ev){}
    
    public void mouseExited(MouseEvent ev){}
    
    public void mouseMoved(MouseEvent ev){}
    
    public void mouseDragged(MouseEvent ev){
     int cx=ev.getX();   //getting current mouse position
     int cy=ev.getY();
     if(top!=null && draggable==true){
        top.setFrame(cx-w,cy-h,top.getWidth(),top.getHeight());
        repaint();  //repainting if dragging a disk
     }
    }
    
   @Override
    public void paintComponent(Graphics g){
     Graphics2D g2d=(Graphics2D)g;
     g2d.setColor(Color.black);
     g2d.fillRect(0,0,getWidth(),getHeight());
     
     int holder_x=getWidth()/6;
     int holder_y1=getHeight()-10*20,holder_y2=getHeight()-20;
     
     g2d.setColor(Color.white);
     g2d.setStroke(new BasicStroke(5)); 
     g2d.drawLine(holder_x,holder_y1,holder_x,holder_y2);
     g2d.drawLine(3*holder_x,holder_y1,3*holder_x,holder_y2);
     g2d.drawLine(5*holder_x,holder_y1,5*holder_x,holder_y2);
     g2d.drawLine(0,holder_y2,getWidth(),holder_y2);
     
     g2d.setStroke(new BasicStroke(1));
     
       g2d.setColor(top_color);
     
       if(draggable==true && top!=null)
      g2d.fill(top);  //drawing dragged disk
     
     drawtower(g2d,0); //drawing disks of each tower
     drawtower(g2d,1);
     drawtower(g2d,2);
    }
    
    private void drawtower(Graphics2D g2d,int n){
     if(!s[n].empty()){
    for(int i = 0;i < s[n].size();i++){
          g2d.setColor(disk_color[n].get(i));
           g2d.fill(s[n].get(i));
       }
     }
    }
    
    private int current_tower(Point p){ //return current tower position with respect to Point p
     Rectangle2D.Double
      rA=new Rectangle2D.Double(),
      rB=new Rectangle2D.Double(),
      rC=new Rectangle2D.Double();
      
     rA.setFrame(0,0,getWidth()/3,getHeight());
     rB.setFrame(getWidth()/3,0,getWidth()/3,getHeight());
     rC.setFrame(2*getWidth()/3,0,getWidth()/3,getHeight());
     
     if(rA.contains(p))
      return 0;
     else if(rB.contains(p))
      return 1;
     else if(rC.contains(p))
      return 2;
     else
      return -1;
    }
}
Source Code for Run_Game.java
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class Run_Game implements ActionListener{
    
    private static JFrame f = new JFrame();
    private static Tower t;
    private static JMenuBar menu_bar=new JMenuBar();
    
    private JMenuItem
     new_game=new JMenuItem("New Game"),
     best_time=new JMenuItem("Best Time"),
     exit=new JMenuItem("Exit"),
     about=new JMenuItem("About.......");
     
    private JMenu
     help=new JMenu("Help"),
     game=new JMenu("Game");
     
    public Run_Game(String title) {
 f.setTitle(title);
     build();
    }
    
    public void actionPerformed(ActionEvent ev){
     if(ev.getSource()==new_game){
      Object values[]= { 3,4,5,6,7,8,9 };
      Object val=JOptionPane.showInputDialog(f,"No. Of Disks : ","Input",
                 JOptionPane.INFORMATION_MESSAGE,null,values,values[0]);
      if((int)val!=JOptionPane.CANCEL_OPTION)
       t.init((int)val);
     }
     else if(ev.getSource()==exit)
      System.exit(0);
    }
    
    private void build(){
     
     game.add(new_game);
     game.add(best_time);
     game.add(exit);
     help.add(about);
     
     menu_bar.add(game);
     menu_bar.add(help);
     
     new_game.addActionListener(this);
     exit.addActionListener(this);
  
 f.setJMenuBar(menu_bar);
        f.setSize(660, 280); 
        f.setResizable(false);
        f.setLocationRelativeTo(null); 
        f.setVisible(true);
 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    } 
    
    public static void main(String[] args) {
    SwingUtilities.invokeLater(
       () -> {
             Run_Game obj = new Run_Game("Tower Of Hanoi v1.0");
         t=new Tower();
                f.getContentPane().add(t);
  });
    }
}
-------------------------------------------------------------------------------------------------------------------------
Download Links
-------------------------------------------------------------------------------------------------------------------------
DOWNLOAD the project archive from Mediafire
DOWNLOAD the project archive from 4shared

1 comment:

Total Pageviews

Subscribe via Email

Followers


Popular Posts

About Me

My photo

I am a student of BTech Computer Science Engineering from RCCIIT,Kolkata. I am a crazy lover of Java and wants to settle as a Java developer. I have a seven years Java experience with an application developer experience for 2 years. Recently from March 2012 I am a registered S40 app developer for Nokia and has corrected an app of them. I am currently writing blogs to encourage and grow interest in all those who don't know or learning Java.