// Purpose.  Convert keyboard application to mouse applet lab answer

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class PuzzleApplet extends Applet implements ActionListener {
   private int[]    slots = new int[16];
   private Button[] btns  = new Button[16];

   public void init() {
      setLayout( new GridLayout( 4, 4 ) );
      Font font = new Font( "Helvetica", Font.BOLD, 24 );
      for (int i=0; i < 16; i++) {
         btns[i] = new Button( Integer.toString( i+1 ) );
         btns[i].setFont( font );
         btns[i].addActionListener( this );
         add( btns[i] ); }
      btns[15].setLabel( "" );
      for (int i=1; i < 16;  i++) slots[i-1] = i;
   }
   public void start() {
      for (int i=0; i < 200; i++) move( (int)(Math.random()*1000) % 15 + 1 );
   }
   public void actionPerformed( ActionEvent e) {
      String str = ((Button)e.getSource()).getLabel();
      if (str.equals( "" )) return;
      move( Integer.parseInt( str ) );
   }
   private void move( int num ) {
      int i;    ////// find the slot this number is in //////
      for (i=0; i < 16; i++) if (slots[i] == num) break;
      if (tryAbove(i)) return;
      if (tryBelow(i)) return;
      if (tryLeft(i)) return;
      if (tryRight(i)) return; }
   private boolean tryAbove( int pos ) {
      if (pos < 4) return false;
      if (slots[pos-4] != 0  &&  ! tryAbove(pos-4)) return false;
      // the slot above is empty  OR  the move above succeeded
      swap( pos, pos-4 );
      return true; }
   private boolean tryBelow( int pos ) {
      if (pos > 11) return false;
      if (slots[pos+4] != 0  &&  ! tryBelow(pos+4)) return false;
      swap( pos, pos+4 );
      return true; }
   private boolean tryLeft( int pos ) {
      if (pos%4 == 0) return false;
      if (slots[pos-1] != 0  &&  ! tryLeft(pos-1)) return false;
      swap( pos, pos-1 );
      return true; }
   private boolean tryRight( int pos ) {
      if (pos%4 == 3) return false;
      if (slots[pos+1] != 0  &&  ! tryRight(pos+1)) return false;
      swap( pos, pos+1 );
      return true; }
   private void swap( int one, int two ) {
      int temp = slots[one];
      slots[one] = slots[two];
      slots[two] = temp;
      String str = btns[one].getLabel();
      btns[one].setLabel( btns[two].getLabel() );
      btns[two].setLabel( str );
}  }
