Robotic Pigeon v2.3
/*Robert Knepher
  *
 */
package robotrobot;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Enumeration;
import java.util.Random;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class RobotBoard extends JPanel
                       implements KeyListener
{
   private static final long serialVersionUID = 1L;
   public static final int NUMBER_OF_COLUMNS = 6;
   public static final int NUMBER_OF_ROWS    = 12;
   RobotFrame robotFrame;
   /**
    * Indicates whether we are displaying the active pair of descending
    * RobotIcons.
    */
   boolean displayingActivePair = false;
   public static final int UPDATES_BETWEEN_NEW_PAIR = 3;
   /**
    * Acts to create a pause between activePairs.
    */
   int updateCounter = 0;
   RobotPair activePair;
   RobotPair onDeckPair;
   RobotIcon[][] iconArray = new RobotIcon[NUMBER_OF_COLUMNS][NUMBER_OF_ROWS];
   /** Creates a new instance of RobotBoard */
   public RobotBoard( RobotFrame parentFrame )
   {
      robotFrame  = parentFrame;
      setSize(new Dimension(192, 384));
      setBackground(Color.white);
      for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
      {
         for(int y = 0; y < NUMBER_OF_ROWS; y++)
         {
            iconArray[x][y] = new RobotIcon(x, y, RobotIcon.TYPE_BLANK, this);
         }
      }
   }
   public Vector
   findHorizontalBasedMatch()
   {
      Vector vector = new Vector();
      int typeToMatch;
      int thisType;
      int matches = 0;
      int x;
      int y;
      int subX;
      for (y = NUMBER_OF_ROWS-1; y >= 0; y--)
      {
         // Reset at the beginning of each row
         typeToMatch = RobotIcon.TYPE_BLANK;
         for (x = 0; x < NUMBER_OF_COLUMNS; x++)
         {
            if (typeToMatch == RobotIcon.TYPE_BLANK)
            {
               // Traverse to the 1st non-blank icon.
                typeToMatch = iconArray[x][y].getType();
               if (typeToMatch != RobotIcon.TYPE_BLANK)
               {
                  matches = 1;
               }
               continue;
            }
            // typeToMatch != TYPE_BLANK, matches < 3
            thisType = iconArray[x][y].getType();
            if (thisType != typeToMatch)
            {
               typeToMatch = thisType;
               if (typeToMatch != RobotIcon.TYPE_BLANK)
               {
                  matches = 1;
               }
               continue;
            }
            else
            {
               matches++;
            }
            if (matches != 3)
            {
               continue;
            }
            // We have found 3 in a row horizontally. Try to find the additional
            // icon to have a "MATCH!"
            // Try 4 in a row
            if (x < NUMBER_OF_COLUMNS-1)
            {
               thisType = iconArray[x+1][y].getType();
               if (thisType == typeToMatch)
               {
                  // We've found 4 in a row.
                  vector.add( iconArray[x-2][y] );
                  vector.add( iconArray[x-1][y] );
                  vector.add( iconArray[x  ][y] );
                  vector.add( iconArray[x+1][y] );
                  return vector;
               }
            }
            // Try L upper left, T upper, and L upper right
            if (y > 0)
            {
               for (subX = x-2; subX <= x; subX++)
               {
                  thisType = iconArray[subX][y-1].getType();
                  if (thisType == typeToMatch)
                  {
                     // We've found a T or an L.
                     vector.add( iconArray[x-2][y] );
                     vector.add( iconArray[x-1][y] );
                     vector.add( iconArray[x  ][y] );
                     vector.add( iconArray[subX][y-1] );
                     return vector;
                  }
               }
            }
            // Try L lower left, T lower, and L lower right
            if (y < NUMBER_OF_ROWS-1)
            {
               for (subX = x-2; subX <= x; subX++)
               {
                  thisType = iconArray[subX][y+1].getType();
                  if (thisType == typeToMatch)
                  {
                     // We've found a T or an L.
                     vector.add( iconArray[x-2][y] );
                     vector.add( iconArray[x-1][y] );
                     vector.add( iconArray[x  ][y] );
                     vector.add( iconArray[subX][y+1] );
                     return vector;
                  }
               }
            }
            // 3 in a row, but no matches
            typeToMatch = RobotIcon.TYPE_BLANK;
         }  // for x... (end of row)
      }  // for y... (end of board
      return null;
   }
   public Vector
   findVerticalBasedMatch()
   {
      Vector vector = new Vector();
      int typeToMatch;
      int thisType;
      int matches = 0;
      int x;
      int y;
      int subY;
      for (x = NUMBER_OF_COLUMNS-1; x >= 0; x--)
      //for (x = 0; x <= NUMBER_OF_COLUMNS-1; x++)
      {
         // Reset at the beginning of each column
         typeToMatch = RobotIcon.TYPE_BLANK;
         for (y = 0; y < NUMBER_OF_ROWS; y++)
         {
            if (typeToMatch == RobotIcon.TYPE_BLANK)
            {
               // Traverse to the 1st non-blank icon.
              typeToMatch = iconArray[x][y].getType();
               if (typeToMatch != RobotIcon.TYPE_BLANK)
               {
                  matches = 1;
               }
               continue;
            }
            // typeToMatch != TYPE_BLANK, matches < 3
            thisType = iconArray[x][y].getType();
            if (thisType != typeToMatch)
            {
               typeToMatch = thisType;
               if (typeToMatch != RobotIcon.TYPE_BLANK)
               {
                  matches = 1;
               }
               continue;
            }
            else
            {
               matches++;
            }
            if (matches != 3)
            {
               continue;
            }
            // We have found 3 in a row VERTICALLY. Try to find the additional
            // icon to have a "MATCH!"
            // Try 4 in a row
            if (y < NUMBER_OF_ROWS-1)
            {
               thisType = iconArray[x][y+1].getType();
               if (thisType == typeToMatch)
               {
                  // We've found 4 in a row.
                  vector.add( iconArray[x][y-2] );
                  vector.add( iconArray[x][y-1] );
                  vector.add( iconArray[x  ][y] );
                  vector.add( iconArray[x][y+1] );
                  return vector;
               }
            }
            // Try L upper left, T left, and L lower left
            if (x > 0)     //y>0
            {
               for (subY = y-2; subY <= y; subY++)
               {
                  thisType = iconArray[x-1][subY].getType();
                  if (thisType == typeToMatch)
                  {
                     // We've found a T or an L.
                     vector.add( iconArray[x][y-2] );
                     vector.add( iconArray[x][y-1] );
                     vector.add( iconArray[x][y] );
                     vector.add( iconArray[x-1][subY] );
                     return vector;
                  }
               }
            }
            // Try L upper right, T right, and L lower right
            if (x < NUMBER_OF_COLUMNS-1)
            {
               for (subY = y-2; subY <= y; subY++)
               {
                  thisType = iconArray[x+1][subY].getType();
                  if (thisType == typeToMatch)
                  {
                     // We've found a T or an L.
                     vector.add( iconArray[x][y-2] );
                     vector.add( iconArray[x][y-1] );
                     vector.add( iconArray[x  ][y] );
                     vector.add( iconArray[x+1][subY] );
                     return vector;
                  }
               }
            }
            // 3 in a row, but no matches
            typeToMatch = RobotIcon.TYPE_BLANK;
         }  // for x... (end of row)
      }  // for y... (end of board
      return null;
   }
   public Vector
   findMatch()
   {
       Vector returnValue = findHorizontalBasedMatch();
       if (returnValue == null)
       {
           returnValue = findVerticalBasedMatch();
       }
       return returnValue;
   }
   /*
    * KeyListener Method
    */
   public void
   keyPressed(KeyEvent e)
   {
      int keyCode = e.getKeyCode();
      switch(keyCode)
      {
         case KeyEvent.VK_UP:
         case KeyEvent.VK_KP_UP:
            rotateCounterClockwise();
            break;
         case KeyEvent.VK_DOWN:
         case KeyEvent.VK_KP_DOWN:
            rotateClockwise();
            break;
         case KeyEvent.VK_LEFT:
         case KeyEvent.VK_KP_LEFT:
            moveLeft();
            break;
         case KeyEvent.VK_RIGHT:
         case KeyEvent.VK_KP_RIGHT:
            moveRight();
            break;
         default:
            break;
      }
   }
   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      RobotIcon icon;
      for(int x = 0; x < 6; x++)
      {
         for(int y = 0; y < 12; y++)
         {
            icon = iconArray[x][y];
            icon.paintBoard(g);
         }
      }
   }
   /**
    * This method creates a new random RobotPair.
    */
   RobotPair
   createNewRobotPair()
   {
      Random random = new Random();
      int    x1     = random.nextInt( NUMBER_OF_COLUMNS-1 );
      int    x2     = x1 + 1;
      int    type1  = random.nextInt( RobotIcon.TYPE_BLANK );
      int    type2  = random.nextInt( RobotIcon.TYPE_BLANK );
      RobotIcon firstIcon  = new RobotIcon( x1, 0, type1, this );
      RobotIcon secondIcon = new RobotIcon( x2, 0, type2, this );
      RobotPair returnValue = new RobotPair( firstIcon, secondIcon );
      return returnValue;
   }
   private void
   moveLeft()
   {
      if (!displayingActivePair)
      {
         // nothing to do
         return;
      }
      int minX = activePair.getMinX();
      if (minX == 0)
      {
         // Pair is as far to the left as it can go.
         return;
      }
      // if orientation is ORIENTATION_HORIZONTAL
      // minY and maxY should be the same.
      int minY = activePair.getMinY();
      int maxY = activePair.getMaxY();
      int typeMinY = iconArray[minX-1][minY].getType();
      int typeMaxY = iconArray[minX-1][maxY].getType();
      if ( (typeMinY != RobotIcon.TYPE_BLANK) ||
           (typeMaxY != RobotIcon.TYPE_BLANK) )
      {
         // There is a non-blank RobotIcon in the way. Can't move.
         return;
      }
      int type1 = activePair.getFirstType();
      int type2 = activePair.getSecondType();
      int orientation = activePair.getOrientation();
      switch (orientation)
      {
         case RobotPair.ORIENTATION_HORIZONTAL:
         {
            // minY should be equal to maxY
            // Before:
            //    |   | A | B |
            //
            // After:
            //    | A | B |   |
            //
            iconArray[minX-1][minY].setType(type1);
            iconArray[minX]  [minY].setType(type2);
            iconArray[minX+1][minY].setType(RobotIcon.TYPE_BLANK);
            activePair.setFirstIcon (iconArray[minX-1][minY]);
            activePair.setSecondIcon(iconArray[minX]  [minY]);
            activePair.update();
            repaint();
            break;
         }
         case RobotPair.ORIENTATION_VERTICAL:
         {
            // maxX (no variable) should be equal to minX
            // Before:
            //    |   | A |
            //    |   | B |
            //
            // After:
            //    | A |   |
            //    | B |   |
            //
            iconArray[minX-1][minY].setType(type1);
            iconArray[minX-1][maxY].setType(type2);
            iconArray[minX]  [minY].setType(RobotIcon.TYPE_BLANK);
            iconArray[minX]  [maxY].setType(RobotIcon.TYPE_BLANK);
            activePair.setFirstIcon (iconArray[minX-1][minY]);
            activePair.setSecondIcon(iconArray[minX-1][maxY]);
            activePair.update();
            repaint();
         }
         break;
      }
   }
   private void
   moveRight()
   {
      if (!displayingActivePair)
      {
         // nothing to do
         return;
      }
      int maxX = activePair.getMaxX();
      if (maxX == NUMBER_OF_COLUMNS-1)
      {
         // Pair is as far to the right as it can go.
         return;
      }
      // if orientation is ORIENTATION_HORIZONTAL
      // minY and maxY should be the same.
      int minY = activePair.getMinY();
      int maxY = activePair.getMaxY();
      int typeMinY = iconArray[maxX+1][minY].getType();
      int typeMaxY = iconArray[maxX+1][maxY].getType();
      if ( (typeMinY != RobotIcon.TYPE_BLANK) ||
           (typeMaxY != RobotIcon.TYPE_BLANK) )
      {
         // There is a non-blank RobotIcon in the way. Can't move.
         return;
      }
      int type1 = activePair.getFirstType();
      int type2 = activePair.getSecondType();
      int orientation = activePair.getOrientation();
      switch (orientation)
      {
         case RobotPair.ORIENTATION_HORIZONTAL:
         {
            // minY should be equal to maxY
            // Before:
            //    | A | B |   |
            //
            // After:
            //    |   | A | B |
            //
            iconArray[maxX+1][minY].setType(type2);
            iconArray[maxX]  [minY].setType(type1);
            iconArray[maxX-1][minY].setType(RobotIcon.TYPE_BLANK);
            activePair.setFirstIcon (iconArray[maxX][minY]);
            activePair.setSecondIcon(iconArray[maxX+1][minY]);
            activePair.update();
            repaint();
            break;
         }
         case RobotPair.ORIENTATION_VERTICAL:
         {
            // minX (no variable) should be equal to maxX
            // Before:
            //    | A |   |
            //    | B |   |
            //
            // After:
            //    |   | A |
            //    |   | B |
            //
            iconArray[maxX+1][minY].setType(type1);
            iconArray[maxX+1][maxY].setType(type2);
            iconArray[maxX]  [minY].setType(RobotIcon.TYPE_BLANK);
            iconArray[maxX]  [maxY].setType(RobotIcon.TYPE_BLANK);
            activePair.setFirstIcon (iconArray[maxX+1][minY]);
            activePair.setSecondIcon(iconArray[maxX+1][maxY]);
            activePair.update();
            repaint();
         }
         break;
      }
   }
   private void
   rotateCounterClockwise()
   {
      if (!displayingActivePair)
      {
         // nothing to do
         return;
      }
      int orientation = activePair.getOrientation();
      int minX        = activePair.getMinX();
      int maxX        = activePair.getMaxX();
      int minY        = activePair.getMinY();
      int maxY        = activePair.getMaxY();
      int type1       = activePair.getFirstType();
      int type2       = activePair.getSecondType();
      int type;
      // Assume orientation != ORIENTATION_ERROR
      if (orientation == RobotPair.ORIENTATION_HORIZONTAL)
      {
         // maxY should be equal to minY
         // Before:
         //    | A | B |
         //    |   |   |
         //
         // After:
         //    | B |   |
         //    | A |   |
         //
         if (maxY == (NUMBER_OF_ROWS-1))
         {
            // There's not room to rotate counter-clockwise.
            return;
         }
         type = iconArray[minX][maxY+1].getType();
         if (type != RobotIcon.TYPE_BLANK)
         {
            // There is a non-blank RobotIcon in the way. Can't move.
            return;
         }
         // Let's do it. activePair will become VERTICAL
         iconArray[minX][maxY+1].setType(type1);
         iconArray[minX][maxY]  .setType(type2);
         iconArray[maxX][maxY]  .setType(RobotIcon.TYPE_BLANK);
         activePair.setFirstIcon (iconArray[minX][maxY]);
         activePair.setSecondIcon(iconArray[minX][maxY+1]);
         activePair.update();
         repaint();
         return;
      }
      if (orientation == RobotPair.ORIENTATION_VERTICAL)
      {
         // maxX should be equal to minX
         // Before:
         //    | A |   |
         //    | B |   |
         //
         // After:
         //    | A | B |
         //    |   |   |
         //
         if (maxX == (NUMBER_OF_COLUMNS-1))
         {
            // There's not room to rotate counter-clockwise.
            return;
         }
         type = iconArray[maxX+1][minY].getType();
         if (type != RobotIcon.TYPE_BLANK)
         {
            // There is a non-blank RobotIcon in the way. Can't move.
            return;
         }
         // Let's do it. activePair will become HORIZONTAL
         // Note: firstIcon stays put.
         iconArray[maxX+1][minY].setType(type2);
         iconArray[maxX]  [maxY].setType(RobotIcon.TYPE_BLANK);
         activePair.setSecondIcon(iconArray[maxX+1][minY]);
         activePair.update();
         repaint();
         return;
      }
   }
   private void
   rotateClockwise()
   {
      if (!displayingActivePair)
      {
         // nothing to do
         return;
      }
      int orientation = activePair.getOrientation();
      int minX        = activePair.getMinX();
      int maxX        = activePair.getMaxX();
      int minY        = activePair.getMinY();
      int maxY        = activePair.getMaxY();
      int type1       = activePair.getFirstType();
      int type2       = activePair.getSecondType();
      int type;
      if (orientation == RobotPair.ORIENTATION_HORIZONTAL)
      {
         // maxY should be equal to minY
         // Before:
         //    | A | B |
         //    |   |   |
         //
         // After:
         //    | A |   |
         //    | B |   |
         //
         if (maxY == (NUMBER_OF_ROWS-1))
         {
            // There's not room to rotate counter-clockwise.
            return;
         }
         type = iconArray[minX][maxY+1].getType();
         if (type != RobotIcon.TYPE_BLANK)
         {
            // There is a non-blank RobotIcon in the way. Can't move.
            return;
         }
         // Let's do it. activePair will become VERTICAL
         // Note: firstIcon stays put.
         iconArray[minX][maxY+1].setType(type2);
         iconArray[maxX][maxY]  .setType(RobotIcon.TYPE_BLANK);
         activePair.setSecondIcon(iconArray[minX][maxY+1]);
         activePair.update();
         repaint();
         return;
      }
      if (orientation == RobotPair.ORIENTATION_VERTICAL)
      {
         // maxX should be equal to minX
         // Before:
         //    | A |   |
         //    | B |   |
         //
         // After:
         //    | B | A |
         //    |   |   |
         //
         if (maxX == (NUMBER_OF_COLUMNS-1))
         {
            // There's not room to rotate counter-clockwise.
            return;
         }
         type = iconArray[maxX+1][minY].getType();
         if (type != RobotIcon.TYPE_BLANK)
         {
            // There is a non-blank RobotIcon in the way. Can't move.
            return;
         }
         // Let's do it. activePair will become HORIZONTAL
         iconArray[minX]  [minY].setType(type2);
         iconArray[minX+1][minY].setType(type1);
         iconArray[minX]  [maxY].setType(RobotIcon.TYPE_BLANK);
         activePair.setFirstIcon (iconArray[minX]  [minY]);
         activePair.setSecondIcon(iconArray[minX+1][minY]);
         activePair.update();
         repaint();
         return;
      }
   }
   /*
    * This method is called periodically by RobotThread.run().
    *
    */
   public void
   update()
   {
      int minX;
      int maxX;
      int maxY;
      int orientation;
      int type1;
      int type2;
     
      // System.out.println("RobotBoard.update()");
     
      RobotPreview robotPreview = robotFrame.getRobotPreview();
      if (onDeckPair == null)
      {
         onDeckPair = createNewRobotPair();
         robotPreview.setRobotPair( onDeckPair );
      }
      if (!displayingActivePair)
      {
         updateCounter++;
         if (updateCounter < UPDATES_BETWEEN_NEW_PAIR)
         {
            // We're resting before the next pair.
            return;
         }
         // Rest is over - time to display activePair and update onDecPair.
         displayingActivePair = true;
         activePair = onDeckPair;
         onDeckPair = createNewRobotPair();
         robotPreview.setRobotPair( onDeckPair );
         minX = activePair.getMinX();
         type1 = iconArray[minX][0].getType();
         type2 = iconArray[minX+1][0].getType();
         if ( (type1 != RobotIcon.TYPE_BLANK) ||
              (type2 != RobotIcon.TYPE_BLANK) )
         {
            // No room for new pair. Game over.
            gameOver();
            return;
         }
         type1 = activePair.getFirstType();
         type2 = activePair.getSecondType();
         iconArray[minX]  [0].setType( type1 );
         iconArray[minX+1][0].setType( type2 );
         // Replacing RobotIcons in activePair with RobotIcons in iconArray.
         // Current pair in activePair will be garbage collected.
         activePair.setFirstIcon ( iconArray[minX]  [0] );
         activePair.setSecondIcon( iconArray[minX+1][0] );
         activePair.update();
         repaint();
         return;
      }
      // Lower activePair. If activePair can't be lowered, check for matches.
      maxY = activePair.getMaxY();
      if (maxY == NUMBER_OF_ROWS-1)
      {
         // Can't move, check for matches, finish processing.
         checkForMatches();
         return;
      }
      orientation = activePair.getOrientation();
      if (orientation == RobotPair.ORIENTATION_HORIZONTAL)
      {
         // Check icons below.
         minX = activePair.getMinX();
         type1 = iconArray[minX]  [maxY+1].getType();
         type2 = iconArray[minX+1][maxY+1].getType();
         if ( type1 == RobotIcon.TYPE_BLANK )
         {
            if ( type2 == RobotIcon.TYPE_BLANK )
            {
               // Both RobotIcons below are blank. OK to lower pair.
               // Before:
               //    | A | B |
               //    |   |   |
               //
               // After:
               //    |   |   |
               //    | A | B |
               //
               iconArray[minX]  [maxY+1].setType(activePair.getFirstType());
               iconArray[minX+1][maxY+1].setType(activePair.getSecondType());
               iconArray[minX]  [maxY  ].setType(RobotIcon.TYPE_BLANK);
               iconArray[minX+1][maxY  ].setType(RobotIcon.TYPE_BLANK);
               activePair.setFirstIcon ( iconArray[minX]  [maxY+1] );
               activePair.setSecondIcon( iconArray[minX+1][maxY+1] );
               activePair.update();
               repaint();
            }
            else
            {
               // Can move first RobotIcon, can't move second RobotIcon.
               // orientation will become ORIENTATION_BLOCKED.
               // Before:
               //    | A | B |
               //    |   |   |
               //
               // After:
               //    |   | B |
               //    | A |   |
               //
               iconArray[minX]  [maxY+1].setType(activePair.getFirstType());
               iconArray[minX]  [maxY  ].setType(RobotIcon.TYPE_BLANK);
               activePair.setFirstIcon ( iconArray[minX]  [maxY+1] );
               activePair.update();
               repaint();
            }
         }
         else
         {
            if ( type2 == RobotIcon.TYPE_BLANK )
            {
               // Can't move first RobotIcon, can move second RobotIcon.
               // orientation will become ORIENTATION_BLOCKED.
               // Before:
               //    | A | B |
               //    |   |   |
               //
               // After:
               //    | A |   |
               //    |   | B |
               //
               iconArray[minX+1][maxY+1].setType(activePair.getSecondType());
               iconArray[minX+1][maxY  ].setType(RobotIcon.TYPE_BLANK);
               activePair.setSecondIcon( iconArray[minX+1][maxY+1] );
               activePair.update();
               repaint();
            }
            else
            {
               // Can't move either RobotIcon. Check for matches, finish processing.
               checkForMatches();
            }
         }
      }  // if (orientation == RobotPair.ORIENTATION_HORIZONTAL)
      else
      if (orientation == RobotPair.ORIENTATION_VERTICAL)
      {
         // Check icon below.
         minX = activePair.getMinX();
         type2 = iconArray[minX][maxY+1].getType();
         if (type2 == RobotIcon.TYPE_BLANK)
         {
            // There's a blank icon below.
            // Before:
            //    | A |
            //    | B |
            //    |   |
            //
            // After:
            //    |   |
            //    | A |
            //    | B |
            //
            iconArray[minX][maxY+1].setType(activePair.getSecondType());
            iconArray[minX][maxY  ].setType(activePair.getFirstType());
            iconArray[minX][maxY-1].setType(RobotIcon.TYPE_BLANK);
            activePair.setFirstIcon ( iconArray[minX][maxY] );
            activePair.setSecondIcon( iconArray[minX][maxY+1] );
            activePair.update();
            repaint();
         }
         else
         {
            // Can't move. Check for matches, finish processing.
            checkForMatches();
         }
      }  // if (orientation == RobotPair.ORIENTATION_VERTICAL)
      else
      if (orientation == RobotPair.ORIENTATION_BLOCKED)
      {
         // orientation was ORIENTATION_HORIZONTAL, but now one of the
         // RobotIcons are blocked, so only one can descend.
         int blockStatus = activePair.getBlockStatus();
         if (blockStatus == RobotPair.FIRST_ICON_BLOCKED)
         {
            // Only the 2nd RobotIcon can be lowered.
            maxX = activePair.getMaxX();
            type2 = iconArray[maxX][maxY+1].getType();
            if (type2 == RobotIcon.TYPE_BLANK)
            {
               // There's a blank icon below.
               // Before:
               //    | A |   |
               //    | * | B |
               //    |   |   |
               //
               // After:
               //    | A |   |
               //    | * |   |
               //    |   | B |
               //
               iconArray[maxX][maxY+1].setType(activePair.getSecondType());
               iconArray[maxX][maxY  ].setType(RobotIcon.TYPE_BLANK);
               activePair.setSecondIcon( iconArray[maxX][maxY+1] );
               activePair.update();
               repaint();
            }
            else
            {
               // Can't move. Check for matches, finish processing.
               checkForMatches();
            }
         }  // if (blockStatus == RobotPair.FIRST_ICON_BLOCKED)
         else
         if (blockStatus == RobotPair.SECOND_ICON_BLOCKED)
         {
            // Only the 1st RobotIcon can be lowered.
            minX = activePair.getMinX();
            type1 = iconArray[minX][maxY+1].getType();
            if (type1 == RobotIcon.TYPE_BLANK)
            {
               // There's a blank icon below.
               // Before:
               //    |   | B |
               //    | A | * |
               //    |   |   |
               //
               // After:
               //    |   | B |
               //    |   | * |
               //    | A |   |
               //
               iconArray[minX][maxY+1].setType(activePair.getFirstType());
               iconArray[minX][maxY  ].setType(RobotIcon.TYPE_BLANK);
               activePair.setFirstIcon( iconArray[minX][maxY+1] );
               activePair.update();
               repaint();
            }
            else
            {
               // Can't move. Check for matches, finish processing.
               checkForMatches();
            }
         }  // if (blockStatus == RobotPair.SECOND_ICON_BLOCKED)
      }  // if (orientation == RobotPair.ORIENTATION_BLOCKED)
   }
   void
   gameOver()
   {
      int  playAgainOption = JOptionPane.NO_OPTION;
      // Reset variables.
      displayingActivePair = false;
      updateCounter = 0;
      System.out.println("Game Over");
      RobotThread robotThread = robotFrame.getRobotThread();
      robotThread.pauseThread();
      playAgainOption =
         JOptionPane.
            showConfirmDialog( this,
                               "Play again?",
                               "Game Over",
                               JOptionPane.YES_NO_OPTION );
      if (playAgainOption == JOptionPane.NO_OPTION)
      {
         System.exit(0);
      }
      for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
      {
         for(int y = 0; y < NUMBER_OF_ROWS; y++)
         {
            iconArray[x][y].setType( RobotIcon.TYPE_BLANK );
         }
      }
      repaint();
      robotThread.resumeThread();
   }
   /**
    * This method is called when the current active pair of RobotIcons can
    * descend no lower. It resets variables so that a new active pair will
    * appear. It also checks for matches. If so, it updates the board.
    */
   void
   checkForMatches()
   {
      RobotIcon tempIcon;
      Vector   matches;
      int      firstBlankIndex;
      int      totalBlanks;
      int      type;
      // Reset variables.
      displayingActivePair = false;
      updateCounter = 0;
      matches = findMatch();
      if (matches == null)
      {
         // Finished processing.
         return;
      }
      // Retrieve the RobotIcon elements, set their type to BLANK, then
      // update iconArray, moving elements down as need be.
      Enumeration enumeration = matches.elements();
      while (enumeration.hasMoreElements())
      {
         tempIcon = (RobotIcon) enumeration.nextElement();
         tempIcon.setType( RobotIcon.TYPE_BLANK );
      }
      // Update iconArray.
      for (int col = 0; col < NUMBER_OF_COLUMNS; col++)
      {
         // Reset the blank count for this row.
         firstBlankIndex = -1;
         totalBlanks     = 0;
         for (int row = NUMBER_OF_ROWS-1; row >= 0; row--)
         {
            // Travel up the column, looking for blanks below a non-blank.
            type = iconArray[col][row].getType();
            if (type == RobotIcon.TYPE_BLANK)
            {
               if (totalBlanks == 0)
               {
                  // This is the first blank we've come to.
                  firstBlankIndex = row;
               }
               totalBlanks++;
            }
            else
            {
               // This icon is a non-blank.
               if (totalBlanks == 0)
               {
                  // No problem. All icons below are non-blank
                  continue;
               }
               // We have found a non-blank icon, with blank icons below.
               // First lower the icons.
               for (int i = firstBlankIndex; i >= totalBlanks; i--)
               {
                  iconArray[col][i].setType( iconArray[col][i-totalBlanks].getType());
               }
               // Make the top icons of the column blank
               for (int i = 0; i < totalBlanks; i++)
               {
                  iconArray[col][i].setType( RobotIcon.TYPE_BLANK);
               }
               // We're done with this column.
               break;
            }
         }  // for (int row...)
      }  // for (int col...)
      repaint();
   }
   public void keyTyped(KeyEvent e)
   {
   }
   public void keyReleased(KeyEvent e)
   {
   }
}
package robotrobot;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
 * Robert Knepher
 *
 */
public class RobotFrame extends JFrame
{
   /**
     *
     */
   private static final long serialVersionUID = -7091286611323587347L;
   private JPanel contentPane;
   private JPanel jPanelMain = new JPanel();
   private BorderLayout borderLayoutContent = new BorderLayout();
   private JPanel jPanelInstructions = new JPanel();
   private JPanel jPanelPreview = new JPanel();
   private JPanel jPanelBoard = new JPanel();
   private JLabel jLabelInstructions = new JLabel();
   private BorderLayout borderLayoutBoard = new BorderLayout();
   private BorderLayout borderLayoutPreview = new BorderLayout();
   RobotBoard robotBoard;
   RobotPreview robotPreview;
   RobotThread robotThread;
   //Construct the frame
   public RobotFrame()
   {
      // System.out.println("RobotFrame.RobotFrame()");
     
      enableEvents(AWTEvent.WINDOW_EVENT_MASK);
      try
      {
         jbInit();
      }
      catch(Exception e)
      {
         e.printStackTrace();
      }
   }
   // Component initialization
   private void jbInit() throws Exception
   {
      robotBoard   = new RobotBoard( this );
      robotPreview = new RobotPreview( this );
  //  robotThread  = new RobotThread( RobotThread.DEFAULT_INTERVAL, robotBoard );
      robotThread  = new RobotThread( 500, robotBoard );
      robotThread.startThread();
      addKeyListener( robotBoard );
      //setIconImage(Toolkit.getDefaultToolkit().createImage(OverlayFrame.class.getResource("[Your Icon]")));
      contentPane = (JPanel) this.getContentPane();
      this.setSize(new Dimension(232, 442));  //226 416
      this.setTitle("The Game of RobotRobot");
      this.setResizable(false);
      contentPane.setLayout(borderLayoutContent);
      jPanelMain.setLayout(null);
      jPanelInstructions.setBounds(new Rectangle(0, 0, 226, 32));
      jPanelPreview.setBackground(Color.white);
      jPanelPreview.setBounds(new Rectangle(0, 32, 34, 410));
      jPanelPreview.setLayout(borderLayoutPreview);
      jPanelPreview.add(robotPreview,  BorderLayout.CENTER);
      jPanelBoard.setBackground(Color.white);
      jPanelBoard.setBounds(new Rectangle(34, 32, 198, 410));
      jPanelBoard.setLayout(borderLayoutBoard);
      jPanelBoard.add(robotBoard,  BorderLayout.CENTER);
      jLabelInstructions.setFont(new java.awt.Font("Dialog", 1, 14));
      jLabelInstructions.setText("Please use arrow keys");
      contentPane.add(jPanelMain,  BorderLayout.CENTER);
      jPanelMain.add(jPanelInstructions, null);
      jPanelInstructions.add(jLabelInstructions, null);
      jPanelMain.add(jPanelPreview, null);
      jPanelMain.add(jPanelBoard, null);
   }
   public RobotBoard
   getRobotBoard()
   {
      return robotBoard;
   }
   public RobotPreview
   getRobotPreview()
   {
      return robotPreview;
   }
   public RobotThread
   getRobotThread()
   {
      return robotThread;
   }
   //Overridden so we can exit when window is closed
   protected void processWindowEvent(WindowEvent e)
   {
      super.processWindowEvent(e);
      if (e.getID() == WindowEvent.WINDOW_CLOSING)
      {
         System.exit(0);
      }
   }
}
/*
 * RobotGuiApp.java
 *
 * Created on March 13, 2006, 10:52 PM
 *
 * Robert Knepher
 *
 */
package robotrobot;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
/**
 *
  */
public class RobotGuiApp
{
   private boolean packFrame = false;
   private RobotFrame robotFrame;
   /** Creates a new instance of RobotGuiApp */
   public RobotGuiApp()
   {
      JFrame.setDefaultLookAndFeelDecorated(true);
      robotFrame = new RobotFrame();
      JFrame frame = robotFrame;
      //Validate frames that have preset sizes
      //Pack frames that have useful preferred size info, e.g. from their layout
      if (packFrame)
      {
         frame.pack();
      }
      else
      {
         frame.validate();
      }
      //Center the window
      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension frameSize = frame.getSize();
      if (frameSize.height > screenSize.height)
      {
         frameSize.height = screenSize.height;
      }
      if (frameSize.width > screenSize.width)
      {
         frameSize.width = screenSize.width;
      }
      frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
   }
   public RobotFrame
   getRobotFrame()
   {
      return robotFrame;
   }
   // Main method
   public static void main(String[] args)
   {
      try
      {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      }
      catch(Exception e)
      {
         e.printStackTrace();
      }
      RobotGuiApp robotGuiApp = new RobotGuiApp();
      // Give time to initialize.
      try
      {
         Thread.sleep(1000);
      }
      catch (InterruptedException ie)
      {
      }
      RobotFrame frame = robotGuiApp.getRobotFrame();
      RobotBoard robotBoard = frame.getRobotBoard();
      Vector vector = robotBoard.findMatch();
      if (vector != null)
      {
         System.out.println("Found a match!!");
         System.out.println("Coordinates are: ");
         Enumeration enumeration = vector.elements();
         while (enumeration.hasMoreElements())
         {
            RobotIcon icon = (RobotIcon) enumeration.nextElement();
            System.out.println( "x = " + icon.getXOffset() + ", " +
                                "y = " + icon.getYOffset() );
         }
      }
   }
}
/**
 * Robert Knepher
 *
 */
package robotrobot;
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.ImageIcon;
/**
 *
 *
 */
public class RobotIcon
{
    public static final int IMAGE_WIDTH = 32;
    public static final int IMAGE_HEIGHT = 32;
    boolean useBlankIcon = true;
    public static final int TYPE_RED    = 0;
    public static final int TYPE_GREEN  = 1;
        public static final int TYPE_BLUE   = 2;
    public static final int TYPE_YELLOW = 3;
    public static final int TYPE_BLANK  = 4;
    private static final ImageIcon robotRed    = new ImageIcon("images/robot_red.png");
    private static final ImageIcon robotGreen  = new ImageIcon("images/robot_green.png");
    private static final ImageIcon robotBlue   = new ImageIcon("images/robot_blue.png");
    private static final ImageIcon robotYellow = new ImageIcon("images/robot_yellow.png");
    private static final ImageIcon robotBlank  = new ImageIcon("images/robot_blank.png");
   /**
    * contains the X location of the icon ( 0 to 5 ) in the parent robotBoard
    */
   int xOffset = 0;
   /**
    * contains the Y location of the icon ( 0 to 11 ) in the parent robotBoard
    */
   int yOffset = 0;
   /**
    * contains the type of the icon ( TYPE_RED, TYPE_GREEN, etc. )
    */
   int type = 0;
   /**
    * contains the ImageIcon used by paint()
    */
   ImageIcon imageIcon = null;
   /**
    * contains the parent RobotBoard
    */
   RobotBoard robotBoard;
   /**
    * Creates a new instance of RobotIcon
    */
   public RobotIcon( int inputX,
                    int inputY,
                    int inputType,
                    RobotBoard inputBoard )
   {
      xOffset = inputX;
      yOffset = inputY;
      type = inputType;
      robotBoard = inputBoard;
      imageIcon = getImageIcon( type );
   }
   public int
   getXOffset()
   {
      return xOffset;
   }
   public int
   getYOffset()
   {
      return yOffset;
   }
   public int
   getType()
   {
      return type;
   }
   /**
    * Sets the X offset. Probably will never call.
    */
   public void
   setXOffset( int inputX )
   {
      xOffset = inputX;
   }
   /**
    * Sets the Y offset. Probably will never call.
    */
   public void
   setYOffset( int inputY )
   {
      yOffset = inputY;
   }
   public ImageIcon
   getImageIcon(int type)
   {
      switch(type){
         case TYPE_RED:
            return robotRed;
         case TYPE_GREEN:
            return robotGreen;
         case TYPE_BLUE:
            return robotBlue;
         case TYPE_YELLOW:
            return robotYellow;
         case TYPE_BLANK:
               return robotBlank;
         default:
            return null;
      }
   }
   public void
   setType(int inputType)
   {
       //update both RobotIcon.type and RobotIcon.imageIcon
       type = inputType;
       imageIcon = getImageIcon( type );
   }
   // Called by:
   //    RobotBoard.paintComponent()
   public void
   paintBoard( Graphics g )
   {
      // System.out.println("RobotIcon[" + xOffset + "," + yOffset + "].paint()");
      if ((type == TYPE_BLANK) && (!useBlankIcon))
      {
         g.clearRect( (xOffset * IMAGE_WIDTH),
                      (yOffset * IMAGE_HEIGHT),
                      IMAGE_WIDTH,
                      IMAGE_HEIGHT );
      }
      else
      {
         imageIcon.paintIcon( (Component) robotBoard,
                              g,
                              (xOffset * IMAGE_WIDTH),
                              (yOffset * IMAGE_HEIGHT) );
      }
   }
   // Called by:
   //    RobotPreview.paintComponent()
   public void
   paintPreview( Graphics g,
                   Component robotPreview,
                   int x,
                   int y )
   {
      // System.out.println("RobotIcon.paintPreview()");
      if ((type == TYPE_BLANK) && (!useBlankIcon))
      {
         g.clearRect( x,
                      y,
                      IMAGE_WIDTH,
                      IMAGE_HEIGHT );
      }
      else
      {
         imageIcon.paintIcon( robotPreview,
                              g,
                              x,
                              y );
      }
   }
}
/**
 * Robert Knepher
 *
 */
package robotrobot;
/**
 * A RobotPair holds a pair of RobotIcons. When the RobotPair is first created,
 * the RobotIcons that it holds are not elements of RobotBoard.iconArray. Once the RobotPair is displayed (and descending) on the screen,
 * 
 * it is updated via the set() methods, and its elements are elements of
 * RobotBoard.iconArray. There is minimal error checking on the
 * elements. If the RobotIcons are horizontally side-by-side, we count on the
 * programmer to always place the first RobotIcon on the left. If the RobotIcons
 * are vertically on top of one another, we count on the programmer to always
 * place the first RobotIcon above the second.
 */
public class RobotPair
{
   private RobotIcon firstIcon;
   private RobotIcon secondIcon;
   /**
    * Indicates whether one of the RobotIcons is "blocked". This can only occur
    * if the icons were previously oriented horizontally. The blocked RobotIcon
    * is directly above a non-blank RobotIcon (not a member of this pair),
    * and therefore cannot descend any further.
    */
   private int blockStatus = NO_ICONS_BLOCKED;
   // Values of blockStatus
   /**
    * Indicates the first RobotIcon is "blocked" (cannot descend further).
    */
   public static final int FIRST_ICON_BLOCKED = 1;
   /**
    * Indicates the second RobotIcon is "blocked" (cannot descend further).
    */
   public static final int SECOND_ICON_BLOCKED = 2;
   /**
    * Indicates neither RobotIcon is "blocked" (both can descend further).
    */
   public static final int NO_ICONS_BLOCKED = 3;
   private int orientation;
   // Values of orientation
   /**
    * Indicates the first icon is left of the second.
    */
   public static final int ORIENTATION_HORIZONTAL = 1;
   /**
    * Indicates the first icon is above the the second.
    */
   public static final int ORIENTATION_VERTICAL = 2;
   /**
    * Indicates the first icon is left of the second, and one of the icons
    * is blocked (cannot descend further).
    */
   public static final int ORIENTATION_BLOCKED = 3;
   /**
    * Indicates there is an error in the orientation of the RobotIcons.
    * (They are not in the same column or adjacent columns).
    */
   public static final int ORIENTATION_ERROR = 4;
   private int minX;
   private int maxX;
   private int minY;
   private int maxY;
   // Values of orientation
   public RobotPair( RobotIcon icon1, RobotIcon icon2 )
   {
      firstIcon  = icon1;
      secondIcon = icon2;
      update();
   }
   public void
   setFirstIcon( RobotIcon inputIcon )
   {
      if (inputIcon == null)
      {
         return;
      }
      firstIcon = inputIcon;
   }
    public RobotIcon
    getFirstIcon()
    {
      return firstIcon;
    }
   public int
   getFirstType()
   {
      return firstIcon.getType();
   }
   public int
   getFirstX()
   {
      return firstIcon.getXOffset();
   }
   public int
   getFirstY()
   {
      return firstIcon.getYOffset();
   }
   public void
   setSecondIcon( RobotIcon inputIcon )
   {
      if (inputIcon == null)
      {
         return;
      }
      secondIcon = inputIcon;
   }
   public RobotIcon
   getSecondIcon()
   {
      return secondIcon;
   }
   public int
   getSecondType()
   {
      return secondIcon.getType();
   }
   public int
   getSecondX()
   {
      return secondIcon.getXOffset();
   }
   public int
   getSecondY()
   {
      return secondIcon.getYOffset();
   }
   public int
   getMinX()
   {
      return minX;
   }
   public int
   getMaxX()
   {
      return maxX;
   }
   public int
   getMinY()
   {
      return minY;
   }
   public int
   getMaxY()
   {
      return maxY;
   }
   public int
   getBlockStatus()
   {
      return blockStatus;
   }
   public int
   getOrientation()
   {
      return orientation;
   }
   public void
   update()
   {
      boolean switchIcons = false;
      int x1 = getFirstX();
      int y1 = getFirstY();
      int x2 = getSecondX();
      int y2 = getSecondY();
      if (x1 < x2)
      {
         minX = x1;
         maxX = x2;
         orientation = ORIENTATION_HORIZONTAL;
      }
      else if (x1 > x2 )
      {
         minX = x2;
         maxX = x1;
         orientation = ORIENTATION_HORIZONTAL;
         switchIcons = true;
      }
      else if (y1 < y2)
      {
         // x1 == x2
         minY = y1;
         maxY = y2;
         orientation = ORIENTATION_VERTICAL;
      }
      else if (y1 > y2)
      {
         // x1 == x2
         minY = y2;
         maxY = y1;
         orientation = ORIENTATION_VERTICAL;
         switchIcons = true;
      }
      else
      {
         // x1 == x2
         // y1 == y2
         minX = maxX = x1;
         minY = maxY = y1;
         orientation = ORIENTATION_ERROR;
      }
      switch (orientation)
      {
         case ORIENTATION_HORIZONTAL:
         {
            // minX, maxX set, set minY, maxY
            if (y1 < y2)
            {
               // x1 != x2: must be blocked.
               minY = y1;
               maxY = y2;
               orientation = ORIENTATION_BLOCKED;
            }
            else if (y1 > y2)
            {
               // x1 != x2: must be blocked.
               minY = y2;
               maxY = y1;
               orientation = ORIENTATION_BLOCKED;
            }
            else
            {
               // x1 != x2: still horizontal.
               minY = maxY = y1;
            }
            if ((maxX-minX) > 1)
            {
               // Can't have RobotIcons apart by more than one column.
               orientation = ORIENTATION_ERROR;
            }
            break;
         }
         case ORIENTATION_VERTICAL:
         {
            // minY, maxY set, set minX, maxX
            minX = maxX = x1;
            if ( (maxY - minY) > 1 )
            {
               // Can't have vertical RobotIcons that are not adjacent.
               orientation = ORIENTATION_ERROR;
            }
            break;
         }
      }  // switch
      if (switchIcons)
      {
         // Switch icons to either keep 1st left of 2nd or 1st above 2nd.
         RobotIcon tempIcon;
         tempIcon   = firstIcon;
         firstIcon  = secondIcon;
         secondIcon = tempIcon;
      }
      if (orientation == ORIENTATION_BLOCKED)
      {
         // RobotIcons could have been switched. Reset y1, y2.
         y1 = getFirstY();
         y2 = getSecondY();
         if (y1 < y2)
         {
            // secondIcon kept descending, firstIcon is blocked.
            blockStatus = FIRST_ICON_BLOCKED;
         }
         else
         {
            // firstIcon kept descending, secondIcon is blocked.
            blockStatus = SECOND_ICON_BLOCKED;
         }
      }
      if (orientation == ORIENTATION_ERROR)
      {
         printError( x1, y1, x2, y2 );
      }
   }
   void
   printError( int x1,
               int y1,
               int x2,
               int y2 )
   {
      System.err.println( "RobotPair: (" + x1 + ", " + y1 + "), (" +
                                          x2 + ", " + y2 + ")" );
   }
}
/**
 * Robert Knepher
 *
 */
package robotrobot;
import java.awt.*;
import javax.swing.JPanel;
public class RobotPreview extends JPanel
{
   RobotFrame robotFrame;
   RobotPair robotPair;
   /** Creates a new instance of RobotPreview */
   public RobotPreview( RobotFrame parentFrame )
   {
      robotFrame = parentFrame;
      setSize(new Dimension(34, 384));
      setBackground(Color.white);
   }
   public void
   setRobotPair( RobotPair inputPair )
   {
      // System.out.println("RobotPreview.setRobotPair()");
     
      robotPair = inputPair;
     
      repaint();
   }
   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      g.setColor(Color.black);
      g.drawLine(33, 0, 33, 383);
      if (robotPair != null )
      {
        
          RobotIcon icon = robotPair.getFirstIcon();
         
          // System.out.println("first icon type = " + icon.getType());
          icon.paintPreview( g, this, 0, 0 );
          icon = robotPair.getSecondIcon();
          // System.out.println("second icon type = " + icon.getType());
          icon.paintPreview( g, this, 0, RobotIcon.IMAGE_HEIGHT );
      }
   }
}
/**
 * Robert Knepher
 *
 */
package robotrobot;
public class RobotThread
       extends Thread
{
   /**
    * b_keepRunning
    *    boolean variable. Set this to false to safely stop the Thread.
    * Set by:
    *    stopThread()
    * Set and Used by:
    *    run()
    */
   private boolean b_keepRunning = true;
   public static final long DEFAULT_INTERVAL = 1000;
   long sleepInterval;
   RobotBoard robotBoard;
   /*
    * The following constants are possible values of threadState
    */
   public static final int STATE_NOT_STARTED = 0;
   public static final int STATE_RUNNING = 1;
   public static final int STATE_PAUSED = 2;
   public static final int STATE_STOPPED = 3;
   /**
    * Indicates the state of the Thread.
    */
   private int threadState = STATE_NOT_STARTED;
   public RobotThread( long      interval,
                      RobotBoard inputBoard )
   {
      sleepInterval = interval;
      robotBoard     = inputBoard;
   }
   public void
   setInterval( long interval )
   {
      sleepInterval = interval;
   }
   public void run()
   {
      while (b_keepRunning)
      {
         // System.out.println("RobotThread.run()");
        
         try
         {
            if (threadState == STATE_PAUSED)
            {
               // pauseThread() has been called.
               synchronized (this)
               {
                  while (threadState == STATE_PAUSED)
                  {
                     wait();
                  }
                  // resumeThread() has been called.
               }
            }
            if (!b_keepRunning)
            {
               // stopThread() has been called
               break;
            }
            robotBoard.update();
            sleep(sleepInterval);
         }
         catch (InterruptedException e)
         {
         }
      }
      threadState = STATE_STOPPED;
   }
   /**
    * Starts the Thread
    */
   public synchronized void
   startThread()
   {
      if (threadState == STATE_NOT_STARTED)
      {
         threadState = STATE_RUNNING;
         start();
      }
   }
   /**
    * Stops the Thread. The specific Thread cannot be restarted.
    */
   public synchronized void
   stopThread()
   {
      b_keepRunning = false;
      if (threadState == STATE_PAUSED)
      {
         resumeThread();
      }
   }
   /**
    * Pauses the Thread
    */
   public synchronized void
   pauseThread()
   {
      if (threadState == STATE_RUNNING) {
         threadState = STATE_PAUSED;
      }
   }
   /**
    * Resumes the Thread after a pause.
    */
   public synchronized void
   resumeThread()
   {
      if (threadState == STATE_PAUSED) {
         threadState = STATE_RUNNING;
         notify();
     }
  }
}
 


0 Comments:
Post a Comment
<< Home